11cb0ef41Sopenharmony_ci// Copyright (c) 1994-2006 Sun Microsystems Inc.
21cb0ef41Sopenharmony_ci// All Rights Reserved.
31cb0ef41Sopenharmony_ci//
41cb0ef41Sopenharmony_ci// Redistribution and use in source and binary forms, with or without
51cb0ef41Sopenharmony_ci// modification, are permitted provided that the following conditions are
61cb0ef41Sopenharmony_ci// met:
71cb0ef41Sopenharmony_ci//
81cb0ef41Sopenharmony_ci// - Redistributions of source code must retain the above copyright notice,
91cb0ef41Sopenharmony_ci// this list of conditions and the following disclaimer.
101cb0ef41Sopenharmony_ci//
111cb0ef41Sopenharmony_ci// - Redistribution in binary form must reproduce the above copyright
121cb0ef41Sopenharmony_ci// notice, this list of conditions and the following disclaimer in the
131cb0ef41Sopenharmony_ci// documentation and/or other materials provided with the distribution.
141cb0ef41Sopenharmony_ci//
151cb0ef41Sopenharmony_ci// - Neither the name of Sun Microsystems or the names of contributors may
161cb0ef41Sopenharmony_ci// be used to endorse or promote products derived from this software without
171cb0ef41Sopenharmony_ci// specific prior written permission.
181cb0ef41Sopenharmony_ci//
191cb0ef41Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
201cb0ef41Sopenharmony_ci// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
211cb0ef41Sopenharmony_ci// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
221cb0ef41Sopenharmony_ci// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
231cb0ef41Sopenharmony_ci// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
241cb0ef41Sopenharmony_ci// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
251cb0ef41Sopenharmony_ci// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
261cb0ef41Sopenharmony_ci// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
271cb0ef41Sopenharmony_ci// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
281cb0ef41Sopenharmony_ci// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
291cb0ef41Sopenharmony_ci// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci// The original source code covered by the above license above has been
321cb0ef41Sopenharmony_ci// modified significantly by Google Inc.
331cb0ef41Sopenharmony_ci// Copyright 2011 the V8 project authors. All rights reserved.
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci// A light-weight IA32 Assembler.
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci#ifndef V8_CODEGEN_IA32_ASSEMBLER_IA32_H_
381cb0ef41Sopenharmony_ci#define V8_CODEGEN_IA32_ASSEMBLER_IA32_H_
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci#include <deque>
411cb0ef41Sopenharmony_ci#include <memory>
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci#include "src/codegen/assembler.h"
441cb0ef41Sopenharmony_ci#include "src/codegen/ia32/constants-ia32.h"
451cb0ef41Sopenharmony_ci#include "src/codegen/ia32/fma-instr.h"
461cb0ef41Sopenharmony_ci#include "src/codegen/ia32/register-ia32.h"
471cb0ef41Sopenharmony_ci#include "src/codegen/ia32/sse-instr.h"
481cb0ef41Sopenharmony_ci#include "src/codegen/label.h"
491cb0ef41Sopenharmony_ci#include "src/execution/isolate.h"
501cb0ef41Sopenharmony_ci#include "src/objects/smi.h"
511cb0ef41Sopenharmony_ci#include "src/utils/utils.h"
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_cinamespace v8 {
541cb0ef41Sopenharmony_cinamespace internal {
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ciclass SafepointTableBuilder;
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_cienum Condition {
591cb0ef41Sopenharmony_ci  // any value < 0 is considered no_condition
601cb0ef41Sopenharmony_ci  no_condition = -1,
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  overflow = 0,
631cb0ef41Sopenharmony_ci  no_overflow = 1,
641cb0ef41Sopenharmony_ci  below = 2,
651cb0ef41Sopenharmony_ci  above_equal = 3,
661cb0ef41Sopenharmony_ci  equal = 4,
671cb0ef41Sopenharmony_ci  not_equal = 5,
681cb0ef41Sopenharmony_ci  below_equal = 6,
691cb0ef41Sopenharmony_ci  above = 7,
701cb0ef41Sopenharmony_ci  negative = 8,
711cb0ef41Sopenharmony_ci  positive = 9,
721cb0ef41Sopenharmony_ci  parity_even = 10,
731cb0ef41Sopenharmony_ci  parity_odd = 11,
741cb0ef41Sopenharmony_ci  less = 12,
751cb0ef41Sopenharmony_ci  greater_equal = 13,
761cb0ef41Sopenharmony_ci  less_equal = 14,
771cb0ef41Sopenharmony_ci  greater = 15,
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci  // aliases
801cb0ef41Sopenharmony_ci  carry = below,
811cb0ef41Sopenharmony_ci  not_carry = above_equal,
821cb0ef41Sopenharmony_ci  zero = equal,
831cb0ef41Sopenharmony_ci  not_zero = not_equal,
841cb0ef41Sopenharmony_ci  sign = negative,
851cb0ef41Sopenharmony_ci  not_sign = positive
861cb0ef41Sopenharmony_ci};
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci// Returns the equivalent of !cc.
891cb0ef41Sopenharmony_ci// Negation of the default no_condition (-1) results in a non-default
901cb0ef41Sopenharmony_ci// no_condition value (-2). As long as tests for no_condition check
911cb0ef41Sopenharmony_ci// for condition < 0, this will work as expected.
921cb0ef41Sopenharmony_ciinline Condition NegateCondition(Condition cc) {
931cb0ef41Sopenharmony_ci  return static_cast<Condition>(cc ^ 1);
941cb0ef41Sopenharmony_ci}
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_cienum RoundingMode {
971cb0ef41Sopenharmony_ci  kRoundToNearest = 0x0,
981cb0ef41Sopenharmony_ci  kRoundDown = 0x1,
991cb0ef41Sopenharmony_ci  kRoundUp = 0x2,
1001cb0ef41Sopenharmony_ci  kRoundToZero = 0x3
1011cb0ef41Sopenharmony_ci};
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci// -----------------------------------------------------------------------------
1041cb0ef41Sopenharmony_ci// Machine instruction Immediates
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ciclass Immediate {
1071cb0ef41Sopenharmony_ci public:
1081cb0ef41Sopenharmony_ci  // Calls where x is an Address (uintptr_t) resolve to this overload.
1091cb0ef41Sopenharmony_ci  inline explicit Immediate(int x, RelocInfo::Mode rmode = RelocInfo::NO_INFO) {
1101cb0ef41Sopenharmony_ci    value_.immediate = x;
1111cb0ef41Sopenharmony_ci    rmode_ = rmode;
1121cb0ef41Sopenharmony_ci  }
1131cb0ef41Sopenharmony_ci  inline explicit Immediate(const ExternalReference& ext)
1141cb0ef41Sopenharmony_ci      : Immediate(ext.address(), RelocInfo::EXTERNAL_REFERENCE) {}
1151cb0ef41Sopenharmony_ci  inline explicit Immediate(Handle<HeapObject> handle)
1161cb0ef41Sopenharmony_ci      : Immediate(handle.address(), RelocInfo::FULL_EMBEDDED_OBJECT) {}
1171cb0ef41Sopenharmony_ci  inline explicit Immediate(Smi value)
1181cb0ef41Sopenharmony_ci      : Immediate(static_cast<intptr_t>(value.ptr())) {}
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci  static Immediate EmbeddedNumber(double number);  // Smi or HeapNumber.
1211cb0ef41Sopenharmony_ci  static Immediate EmbeddedStringConstant(const StringConstantBase* str);
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci  static Immediate CodeRelativeOffset(Label* label) { return Immediate(label); }
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci  bool is_heap_object_request() const {
1261cb0ef41Sopenharmony_ci    DCHECK_IMPLIES(is_heap_object_request_,
1271cb0ef41Sopenharmony_ci                   rmode_ == RelocInfo::FULL_EMBEDDED_OBJECT ||
1281cb0ef41Sopenharmony_ci                       rmode_ == RelocInfo::CODE_TARGET);
1291cb0ef41Sopenharmony_ci    return is_heap_object_request_;
1301cb0ef41Sopenharmony_ci  }
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  HeapObjectRequest heap_object_request() const {
1331cb0ef41Sopenharmony_ci    DCHECK(is_heap_object_request());
1341cb0ef41Sopenharmony_ci    return value_.heap_object_request;
1351cb0ef41Sopenharmony_ci  }
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  int immediate() const {
1381cb0ef41Sopenharmony_ci    DCHECK(!is_heap_object_request());
1391cb0ef41Sopenharmony_ci    return value_.immediate;
1401cb0ef41Sopenharmony_ci  }
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci  bool is_embedded_object() const {
1431cb0ef41Sopenharmony_ci    return !is_heap_object_request() &&
1441cb0ef41Sopenharmony_ci           rmode() == RelocInfo::FULL_EMBEDDED_OBJECT;
1451cb0ef41Sopenharmony_ci  }
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci  Handle<HeapObject> embedded_object() const {
1481cb0ef41Sopenharmony_ci    return Handle<HeapObject>(reinterpret_cast<Address*>(immediate()));
1491cb0ef41Sopenharmony_ci  }
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci  bool is_external_reference() const {
1521cb0ef41Sopenharmony_ci    return rmode() == RelocInfo::EXTERNAL_REFERENCE;
1531cb0ef41Sopenharmony_ci  }
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ci  ExternalReference external_reference() const {
1561cb0ef41Sopenharmony_ci    DCHECK(is_external_reference());
1571cb0ef41Sopenharmony_ci    return bit_cast<ExternalReference>(immediate());
1581cb0ef41Sopenharmony_ci  }
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ci  bool is_zero() const {
1611cb0ef41Sopenharmony_ci    return RelocInfo::IsNoInfo(rmode_) && immediate() == 0;
1621cb0ef41Sopenharmony_ci  }
1631cb0ef41Sopenharmony_ci  bool is_int8() const {
1641cb0ef41Sopenharmony_ci    return RelocInfo::IsNoInfo(rmode_) && i::is_int8(immediate());
1651cb0ef41Sopenharmony_ci  }
1661cb0ef41Sopenharmony_ci  bool is_uint8() const {
1671cb0ef41Sopenharmony_ci    return RelocInfo::IsNoInfo(rmode_) && i::is_uint8(immediate());
1681cb0ef41Sopenharmony_ci  }
1691cb0ef41Sopenharmony_ci  bool is_int16() const {
1701cb0ef41Sopenharmony_ci    return RelocInfo::IsNoInfo(rmode_) && i::is_int16(immediate());
1711cb0ef41Sopenharmony_ci  }
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ci  bool is_uint16() const {
1741cb0ef41Sopenharmony_ci    return RelocInfo::IsNoInfo(rmode_) && i::is_uint16(immediate());
1751cb0ef41Sopenharmony_ci  }
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_ci  RelocInfo::Mode rmode() const { return rmode_; }
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci private:
1801cb0ef41Sopenharmony_ci  inline explicit Immediate(Label* value) {
1811cb0ef41Sopenharmony_ci    value_.immediate = reinterpret_cast<int32_t>(value);
1821cb0ef41Sopenharmony_ci    rmode_ = RelocInfo::INTERNAL_REFERENCE;
1831cb0ef41Sopenharmony_ci  }
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci  union Value {
1861cb0ef41Sopenharmony_ci    Value() {}
1871cb0ef41Sopenharmony_ci    HeapObjectRequest heap_object_request;
1881cb0ef41Sopenharmony_ci    int immediate;
1891cb0ef41Sopenharmony_ci  } value_;
1901cb0ef41Sopenharmony_ci  bool is_heap_object_request_ = false;
1911cb0ef41Sopenharmony_ci  RelocInfo::Mode rmode_;
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ci  friend class Operand;
1941cb0ef41Sopenharmony_ci  friend class Assembler;
1951cb0ef41Sopenharmony_ci  friend class MacroAssembler;
1961cb0ef41Sopenharmony_ci};
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_ci// -----------------------------------------------------------------------------
1991cb0ef41Sopenharmony_ci// Machine instruction Operands
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_cienum ScaleFactor {
2021cb0ef41Sopenharmony_ci  times_1 = 0,
2031cb0ef41Sopenharmony_ci  times_2 = 1,
2041cb0ef41Sopenharmony_ci  times_4 = 2,
2051cb0ef41Sopenharmony_ci  times_8 = 3,
2061cb0ef41Sopenharmony_ci  times_int_size = times_4,
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci  times_half_system_pointer_size = times_2,
2091cb0ef41Sopenharmony_ci  times_system_pointer_size = times_4,
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_ci  times_tagged_size = times_4,
2121cb0ef41Sopenharmony_ci};
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE Operand {
2151cb0ef41Sopenharmony_ci public:
2161cb0ef41Sopenharmony_ci  // reg
2171cb0ef41Sopenharmony_ci  V8_INLINE explicit Operand(Register reg) { set_modrm(3, reg); }
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_ci  // XMM reg
2201cb0ef41Sopenharmony_ci  V8_INLINE explicit Operand(XMMRegister xmm_reg) {
2211cb0ef41Sopenharmony_ci    Register reg = Register::from_code(xmm_reg.code());
2221cb0ef41Sopenharmony_ci    set_modrm(3, reg);
2231cb0ef41Sopenharmony_ci  }
2241cb0ef41Sopenharmony_ci
2251cb0ef41Sopenharmony_ci  // [disp/r]
2261cb0ef41Sopenharmony_ci  V8_INLINE explicit Operand(int32_t disp, RelocInfo::Mode rmode) {
2271cb0ef41Sopenharmony_ci    set_modrm(0, ebp);
2281cb0ef41Sopenharmony_ci    set_dispr(disp, rmode);
2291cb0ef41Sopenharmony_ci  }
2301cb0ef41Sopenharmony_ci
2311cb0ef41Sopenharmony_ci  // [disp/r]
2321cb0ef41Sopenharmony_ci  V8_INLINE explicit Operand(Immediate imm) {
2331cb0ef41Sopenharmony_ci    set_modrm(0, ebp);
2341cb0ef41Sopenharmony_ci    set_dispr(imm.immediate(), imm.rmode_);
2351cb0ef41Sopenharmony_ci  }
2361cb0ef41Sopenharmony_ci
2371cb0ef41Sopenharmony_ci  // [base + disp/r]
2381cb0ef41Sopenharmony_ci  explicit Operand(Register base, int32_t disp,
2391cb0ef41Sopenharmony_ci                   RelocInfo::Mode rmode = RelocInfo::NO_INFO);
2401cb0ef41Sopenharmony_ci
2411cb0ef41Sopenharmony_ci  // [rip + disp/r]
2421cb0ef41Sopenharmony_ci  explicit Operand(Label* label) {
2431cb0ef41Sopenharmony_ci    set_modrm(0, ebp);
2441cb0ef41Sopenharmony_ci    set_dispr(reinterpret_cast<intptr_t>(label), RelocInfo::INTERNAL_REFERENCE);
2451cb0ef41Sopenharmony_ci  }
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ci  // [base + index*scale + disp/r]
2481cb0ef41Sopenharmony_ci  explicit Operand(Register base, Register index, ScaleFactor scale,
2491cb0ef41Sopenharmony_ci                   int32_t disp, RelocInfo::Mode rmode = RelocInfo::NO_INFO);
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_ci  // [index*scale + disp/r]
2521cb0ef41Sopenharmony_ci  explicit Operand(Register index, ScaleFactor scale, int32_t disp,
2531cb0ef41Sopenharmony_ci                   RelocInfo::Mode rmode = RelocInfo::NO_INFO);
2541cb0ef41Sopenharmony_ci
2551cb0ef41Sopenharmony_ci  static Operand JumpTable(Register index, ScaleFactor scale, Label* table) {
2561cb0ef41Sopenharmony_ci    return Operand(index, scale, reinterpret_cast<int32_t>(table),
2571cb0ef41Sopenharmony_ci                   RelocInfo::INTERNAL_REFERENCE);
2581cb0ef41Sopenharmony_ci  }
2591cb0ef41Sopenharmony_ci
2601cb0ef41Sopenharmony_ci  static Operand ForRegisterPlusImmediate(Register base, Immediate imm) {
2611cb0ef41Sopenharmony_ci    return Operand(base, imm.value_.immediate, imm.rmode_);
2621cb0ef41Sopenharmony_ci  }
2631cb0ef41Sopenharmony_ci
2641cb0ef41Sopenharmony_ci  // Returns true if this Operand is a wrapper for the specified register.
2651cb0ef41Sopenharmony_ci  bool is_reg(Register reg) const { return is_reg(reg.code()); }
2661cb0ef41Sopenharmony_ci  bool is_reg(XMMRegister reg) const { return is_reg(reg.code()); }
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci  // Returns true if this Operand is a wrapper for one register.
2691cb0ef41Sopenharmony_ci  bool is_reg_only() const;
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_ci  // Asserts that this Operand is a wrapper for one register and returns the
2721cb0ef41Sopenharmony_ci  // register.
2731cb0ef41Sopenharmony_ci  Register reg() const;
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ci  base::Vector<const byte> encoded_bytes() const { return {buf_, len_}; }
2761cb0ef41Sopenharmony_ci  RelocInfo::Mode rmode() { return rmode_; }
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_ci private:
2791cb0ef41Sopenharmony_ci  // Set the ModRM byte without an encoded 'reg' register. The
2801cb0ef41Sopenharmony_ci  // register is encoded later as part of the emit_operand operation.
2811cb0ef41Sopenharmony_ci  inline void set_modrm(int mod, Register rm) {
2821cb0ef41Sopenharmony_ci    DCHECK_EQ(mod & -4, 0);
2831cb0ef41Sopenharmony_ci    buf_[0] = mod << 6 | rm.code();
2841cb0ef41Sopenharmony_ci    len_ = 1;
2851cb0ef41Sopenharmony_ci  }
2861cb0ef41Sopenharmony_ci
2871cb0ef41Sopenharmony_ci  inline void set_sib(ScaleFactor scale, Register index, Register base);
2881cb0ef41Sopenharmony_ci  inline void set_disp8(int8_t disp);
2891cb0ef41Sopenharmony_ci  inline void set_dispr(int32_t disp, RelocInfo::Mode rmode) {
2901cb0ef41Sopenharmony_ci    DCHECK(len_ == 1 || len_ == 2);
2911cb0ef41Sopenharmony_ci    Address p = reinterpret_cast<Address>(&buf_[len_]);
2921cb0ef41Sopenharmony_ci    WriteUnalignedValue(p, disp);
2931cb0ef41Sopenharmony_ci    len_ += sizeof(int32_t);
2941cb0ef41Sopenharmony_ci    rmode_ = rmode;
2951cb0ef41Sopenharmony_ci  }
2961cb0ef41Sopenharmony_ci
2971cb0ef41Sopenharmony_ci  inline bool is_reg(int reg_code) const {
2981cb0ef41Sopenharmony_ci    return ((buf_[0] & 0xF8) == 0xC0)  // addressing mode is register only.
2991cb0ef41Sopenharmony_ci           && ((buf_[0] & 0x07) == reg_code);  // register codes match.
3001cb0ef41Sopenharmony_ci  }
3011cb0ef41Sopenharmony_ci
3021cb0ef41Sopenharmony_ci  byte buf_[6];
3031cb0ef41Sopenharmony_ci  // The number of bytes in buf_.
3041cb0ef41Sopenharmony_ci  uint8_t len_ = 0;
3051cb0ef41Sopenharmony_ci  // Only valid if len_ > 4.
3061cb0ef41Sopenharmony_ci  RelocInfo::Mode rmode_ = RelocInfo::NO_INFO;
3071cb0ef41Sopenharmony_ci};
3081cb0ef41Sopenharmony_ciASSERT_TRIVIALLY_COPYABLE(Operand);
3091cb0ef41Sopenharmony_cistatic_assert(sizeof(Operand) <= 2 * kSystemPointerSize,
3101cb0ef41Sopenharmony_ci              "Operand must be small enough to pass it by value");
3111cb0ef41Sopenharmony_ci
3121cb0ef41Sopenharmony_cibool operator!=(Operand op, XMMRegister r);
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ci// -----------------------------------------------------------------------------
3151cb0ef41Sopenharmony_ci// A Displacement describes the 32bit immediate field of an instruction which
3161cb0ef41Sopenharmony_ci// may be used together with a Label in order to refer to a yet unknown code
3171cb0ef41Sopenharmony_ci// position. Displacements stored in the instruction stream are used to describe
3181cb0ef41Sopenharmony_ci// the instruction and to chain a list of instructions using the same Label.
3191cb0ef41Sopenharmony_ci// A Displacement contains 2 different fields:
3201cb0ef41Sopenharmony_ci//
3211cb0ef41Sopenharmony_ci// next field: position of next displacement in the chain (0 = end of list)
3221cb0ef41Sopenharmony_ci// type field: instruction type
3231cb0ef41Sopenharmony_ci//
3241cb0ef41Sopenharmony_ci// A next value of null (0) indicates the end of a chain (note that there can
3251cb0ef41Sopenharmony_ci// be no displacement at position zero, because there is always at least one
3261cb0ef41Sopenharmony_ci// instruction byte before the displacement).
3271cb0ef41Sopenharmony_ci//
3281cb0ef41Sopenharmony_ci// Displacement _data field layout
3291cb0ef41Sopenharmony_ci//
3301cb0ef41Sopenharmony_ci// |31.....2|1......0|
3311cb0ef41Sopenharmony_ci// [  next  |  type  |
3321cb0ef41Sopenharmony_ci
3331cb0ef41Sopenharmony_ciclass Displacement {
3341cb0ef41Sopenharmony_ci public:
3351cb0ef41Sopenharmony_ci  enum Type { UNCONDITIONAL_JUMP, CODE_RELATIVE, OTHER, CODE_ABSOLUTE };
3361cb0ef41Sopenharmony_ci
3371cb0ef41Sopenharmony_ci  int data() const { return data_; }
3381cb0ef41Sopenharmony_ci  Type type() const { return TypeField::decode(data_); }
3391cb0ef41Sopenharmony_ci  void next(Label* L) const {
3401cb0ef41Sopenharmony_ci    int n = NextField::decode(data_);
3411cb0ef41Sopenharmony_ci    n > 0 ? L->link_to(n) : L->Unuse();
3421cb0ef41Sopenharmony_ci  }
3431cb0ef41Sopenharmony_ci  void link_to(Label* L) { init(L, type()); }
3441cb0ef41Sopenharmony_ci
3451cb0ef41Sopenharmony_ci  explicit Displacement(int data) { data_ = data; }
3461cb0ef41Sopenharmony_ci
3471cb0ef41Sopenharmony_ci  Displacement(Label* L, Type type) { init(L, type); }
3481cb0ef41Sopenharmony_ci
3491cb0ef41Sopenharmony_ci  void print() {
3501cb0ef41Sopenharmony_ci    PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"),
3511cb0ef41Sopenharmony_ci           NextField::decode(data_));
3521cb0ef41Sopenharmony_ci  }
3531cb0ef41Sopenharmony_ci
3541cb0ef41Sopenharmony_ci private:
3551cb0ef41Sopenharmony_ci  int data_;
3561cb0ef41Sopenharmony_ci
3571cb0ef41Sopenharmony_ci  using TypeField = base::BitField<Type, 0, 2>;
3581cb0ef41Sopenharmony_ci  using NextField = base::BitField<int, 2, 32 - 2>;
3591cb0ef41Sopenharmony_ci
3601cb0ef41Sopenharmony_ci  void init(Label* L, Type type);
3611cb0ef41Sopenharmony_ci};
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
3641cb0ef41Sopenharmony_ci private:
3651cb0ef41Sopenharmony_ci  // We check before assembling an instruction that there is sufficient
3661cb0ef41Sopenharmony_ci  // space to write an instruction and its relocation information.
3671cb0ef41Sopenharmony_ci  // The relocation writer's position must be kGap bytes above the end of
3681cb0ef41Sopenharmony_ci  // the generated instructions. This leaves enough space for the
3691cb0ef41Sopenharmony_ci  // longest possible ia32 instruction, 15 bytes, and the longest possible
3701cb0ef41Sopenharmony_ci  // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
3711cb0ef41Sopenharmony_ci  // (There is a 15 byte limit on ia32 instruction length that rules out some
3721cb0ef41Sopenharmony_ci  // otherwise valid instructions.)
3731cb0ef41Sopenharmony_ci  // This allows for a single, fast space check per instruction.
3741cb0ef41Sopenharmony_ci  static constexpr int kGap = 32;
3751cb0ef41Sopenharmony_ci  STATIC_ASSERT(AssemblerBase::kMinimalBufferSize >= 2 * kGap);
3761cb0ef41Sopenharmony_ci
3771cb0ef41Sopenharmony_ci public:
3781cb0ef41Sopenharmony_ci  // Create an assembler. Instructions and relocation information are emitted
3791cb0ef41Sopenharmony_ci  // into a buffer, with the instructions starting from the beginning and the
3801cb0ef41Sopenharmony_ci  // relocation information starting from the end of the buffer. See CodeDesc
3811cb0ef41Sopenharmony_ci  // for a detailed comment on the layout (globals.h).
3821cb0ef41Sopenharmony_ci  //
3831cb0ef41Sopenharmony_ci  // If the provided buffer is nullptr, the assembler allocates and grows its
3841cb0ef41Sopenharmony_ci  // own buffer. Otherwise it takes ownership of the provided buffer.
3851cb0ef41Sopenharmony_ci  explicit Assembler(const AssemblerOptions&,
3861cb0ef41Sopenharmony_ci                     std::unique_ptr<AssemblerBuffer> = {});
3871cb0ef41Sopenharmony_ci
3881cb0ef41Sopenharmony_ci  // GetCode emits any pending (non-emitted) code and fills the descriptor desc.
3891cb0ef41Sopenharmony_ci  static constexpr int kNoHandlerTable = 0;
3901cb0ef41Sopenharmony_ci  static constexpr SafepointTableBuilder* kNoSafepointTable = nullptr;
3911cb0ef41Sopenharmony_ci  void GetCode(Isolate* isolate, CodeDesc* desc,
3921cb0ef41Sopenharmony_ci               SafepointTableBuilder* safepoint_table_builder,
3931cb0ef41Sopenharmony_ci               int handler_table_offset);
3941cb0ef41Sopenharmony_ci
3951cb0ef41Sopenharmony_ci  // Convenience wrapper for code without safepoint or handler tables.
3961cb0ef41Sopenharmony_ci  void GetCode(Isolate* isolate, CodeDesc* desc) {
3971cb0ef41Sopenharmony_ci    GetCode(isolate, desc, kNoSafepointTable, kNoHandlerTable);
3981cb0ef41Sopenharmony_ci  }
3991cb0ef41Sopenharmony_ci
4001cb0ef41Sopenharmony_ci  void FinalizeJumpOptimizationInfo();
4011cb0ef41Sopenharmony_ci
4021cb0ef41Sopenharmony_ci  // Unused on this architecture.
4031cb0ef41Sopenharmony_ci  void MaybeEmitOutOfLineConstantPool() {}
4041cb0ef41Sopenharmony_ci
4051cb0ef41Sopenharmony_ci  // Read/Modify the code target in the branch/call instruction at pc.
4061cb0ef41Sopenharmony_ci  // The isolate argument is unused (and may be nullptr) when skipping flushing.
4071cb0ef41Sopenharmony_ci  inline static Address target_address_at(Address pc, Address constant_pool);
4081cb0ef41Sopenharmony_ci  inline static void set_target_address_at(
4091cb0ef41Sopenharmony_ci      Address pc, Address constant_pool, Address target,
4101cb0ef41Sopenharmony_ci      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
4111cb0ef41Sopenharmony_ci
4121cb0ef41Sopenharmony_ci  // This sets the branch destination (which is in the instruction on x86).
4131cb0ef41Sopenharmony_ci  // This is for calls and branches within generated code.
4141cb0ef41Sopenharmony_ci  inline static void deserialization_set_special_target_at(
4151cb0ef41Sopenharmony_ci      Address instruction_payload, Code code, Address target);
4161cb0ef41Sopenharmony_ci
4171cb0ef41Sopenharmony_ci  // Get the size of the special target encoded at 'instruction_payload'.
4181cb0ef41Sopenharmony_ci  inline static int deserialization_special_target_size(
4191cb0ef41Sopenharmony_ci      Address instruction_payload);
4201cb0ef41Sopenharmony_ci
4211cb0ef41Sopenharmony_ci  // This sets the internal reference at the pc.
4221cb0ef41Sopenharmony_ci  inline static void deserialization_set_target_internal_reference_at(
4231cb0ef41Sopenharmony_ci      Address pc, Address target,
4241cb0ef41Sopenharmony_ci      RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
4251cb0ef41Sopenharmony_ci
4261cb0ef41Sopenharmony_ci  static constexpr int kSpecialTargetSize = kSystemPointerSize;
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ci  // One byte opcode for test al, 0xXX.
4291cb0ef41Sopenharmony_ci  static constexpr byte kTestAlByte = 0xA8;
4301cb0ef41Sopenharmony_ci  // One byte opcode for nop.
4311cb0ef41Sopenharmony_ci  static constexpr byte kNopByte = 0x90;
4321cb0ef41Sopenharmony_ci
4331cb0ef41Sopenharmony_ci  // One byte opcode for a short unconditional jump.
4341cb0ef41Sopenharmony_ci  static constexpr byte kJmpShortOpcode = 0xEB;
4351cb0ef41Sopenharmony_ci  // One byte prefix for a short conditional jump.
4361cb0ef41Sopenharmony_ci  static constexpr byte kJccShortPrefix = 0x70;
4371cb0ef41Sopenharmony_ci  static constexpr byte kJncShortOpcode = kJccShortPrefix | not_carry;
4381cb0ef41Sopenharmony_ci  static constexpr byte kJcShortOpcode = kJccShortPrefix | carry;
4391cb0ef41Sopenharmony_ci  static constexpr byte kJnzShortOpcode = kJccShortPrefix | not_zero;
4401cb0ef41Sopenharmony_ci  static constexpr byte kJzShortOpcode = kJccShortPrefix | zero;
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_ci  // ---------------------------------------------------------------------------
4431cb0ef41Sopenharmony_ci  // Code generation
4441cb0ef41Sopenharmony_ci  //
4451cb0ef41Sopenharmony_ci  // - function names correspond one-to-one to ia32 instruction mnemonics
4461cb0ef41Sopenharmony_ci  // - unless specified otherwise, instructions operate on 32bit operands
4471cb0ef41Sopenharmony_ci  // - instructions on 8bit (byte) operands/registers have a trailing '_b'
4481cb0ef41Sopenharmony_ci  // - instructions on 16bit (word) operands/registers have a trailing '_w'
4491cb0ef41Sopenharmony_ci  // - naming conflicts with C++ keywords are resolved via a trailing '_'
4501cb0ef41Sopenharmony_ci
4511cb0ef41Sopenharmony_ci  // NOTE ON INTERFACE: Currently, the interface is not very consistent
4521cb0ef41Sopenharmony_ci  // in the sense that some operations (e.g. mov()) can be called in more
4531cb0ef41Sopenharmony_ci  // the one way to generate the same instruction: The Register argument
4541cb0ef41Sopenharmony_ci  // can in some cases be replaced with an Operand(Register) argument.
4551cb0ef41Sopenharmony_ci  // This should be cleaned up and made more orthogonal. The questions
4561cb0ef41Sopenharmony_ci  // is: should we always use Operands instead of Registers where an
4571cb0ef41Sopenharmony_ci  // Operand is possible, or should we have a Register (overloaded) form
4581cb0ef41Sopenharmony_ci  // instead? We must be careful to make sure that the selected instruction
4591cb0ef41Sopenharmony_ci  // is obvious from the parameters to avoid hard-to-find code generation
4601cb0ef41Sopenharmony_ci  // bugs.
4611cb0ef41Sopenharmony_ci
4621cb0ef41Sopenharmony_ci  // Insert the smallest number of nop instructions
4631cb0ef41Sopenharmony_ci  // possible to align the pc offset to a multiple
4641cb0ef41Sopenharmony_ci  // of m. m must be a power of 2.
4651cb0ef41Sopenharmony_ci  void Align(int m);
4661cb0ef41Sopenharmony_ci  // Insert the smallest number of zero bytes possible to align the pc offset
4671cb0ef41Sopenharmony_ci  // to a mulitple of m. m must be a power of 2 (>= 2).
4681cb0ef41Sopenharmony_ci  void DataAlign(int m);
4691cb0ef41Sopenharmony_ci  void Nop(int bytes = 1);
4701cb0ef41Sopenharmony_ci  // Aligns code to something that's optimal for a jump target for the platform.
4711cb0ef41Sopenharmony_ci  void CodeTargetAlign();
4721cb0ef41Sopenharmony_ci  void LoopHeaderAlign() { CodeTargetAlign(); }
4731cb0ef41Sopenharmony_ci
4741cb0ef41Sopenharmony_ci  // Stack
4751cb0ef41Sopenharmony_ci  void pushad();
4761cb0ef41Sopenharmony_ci  void popad();
4771cb0ef41Sopenharmony_ci
4781cb0ef41Sopenharmony_ci  void pushfd();
4791cb0ef41Sopenharmony_ci  void popfd();
4801cb0ef41Sopenharmony_ci
4811cb0ef41Sopenharmony_ci  void push(const Immediate& x);
4821cb0ef41Sopenharmony_ci  void push_imm32(int32_t imm32);
4831cb0ef41Sopenharmony_ci  void push(Register src);
4841cb0ef41Sopenharmony_ci  void push(Operand src);
4851cb0ef41Sopenharmony_ci
4861cb0ef41Sopenharmony_ci  void pop(Register dst);
4871cb0ef41Sopenharmony_ci  void pop(Operand dst);
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ci  void leave();
4901cb0ef41Sopenharmony_ci
4911cb0ef41Sopenharmony_ci  // Moves
4921cb0ef41Sopenharmony_ci  void mov_b(Register dst, Register src) { mov_b(dst, Operand(src)); }
4931cb0ef41Sopenharmony_ci  void mov_b(Register dst, Operand src);
4941cb0ef41Sopenharmony_ci  void mov_b(Register dst, int8_t imm8) { mov_b(Operand(dst), imm8); }
4951cb0ef41Sopenharmony_ci  void mov_b(Operand dst, int8_t src) { mov_b(dst, Immediate(src)); }
4961cb0ef41Sopenharmony_ci  void mov_b(Operand dst, const Immediate& src);
4971cb0ef41Sopenharmony_ci  void mov_b(Operand dst, Register src);
4981cb0ef41Sopenharmony_ci
4991cb0ef41Sopenharmony_ci  void mov_w(Register dst, Operand src);
5001cb0ef41Sopenharmony_ci  void mov_w(Operand dst, int16_t src) { mov_w(dst, Immediate(src)); }
5011cb0ef41Sopenharmony_ci  void mov_w(Operand dst, const Immediate& src);
5021cb0ef41Sopenharmony_ci  void mov_w(Operand dst, Register src);
5031cb0ef41Sopenharmony_ci
5041cb0ef41Sopenharmony_ci  void mov(Register dst, int32_t imm32);
5051cb0ef41Sopenharmony_ci  void mov(Register dst, const Immediate& x);
5061cb0ef41Sopenharmony_ci  void mov(Register dst, Handle<HeapObject> handle);
5071cb0ef41Sopenharmony_ci  void mov(Register dst, Operand src);
5081cb0ef41Sopenharmony_ci  void mov(Register dst, Register src);
5091cb0ef41Sopenharmony_ci  void mov(Operand dst, const Immediate& x);
5101cb0ef41Sopenharmony_ci  void mov(Operand dst, Handle<HeapObject> handle);
5111cb0ef41Sopenharmony_ci  void mov(Operand dst, Register src);
5121cb0ef41Sopenharmony_ci  void mov(Operand dst, Address src, RelocInfo::Mode);
5131cb0ef41Sopenharmony_ci
5141cb0ef41Sopenharmony_ci  void movsx_b(Register dst, Register src) { movsx_b(dst, Operand(src)); }
5151cb0ef41Sopenharmony_ci  void movsx_b(Register dst, Operand src);
5161cb0ef41Sopenharmony_ci
5171cb0ef41Sopenharmony_ci  void movsx_w(Register dst, Register src) { movsx_w(dst, Operand(src)); }
5181cb0ef41Sopenharmony_ci  void movsx_w(Register dst, Operand src);
5191cb0ef41Sopenharmony_ci
5201cb0ef41Sopenharmony_ci  void movzx_b(Register dst, Register src) { movzx_b(dst, Operand(src)); }
5211cb0ef41Sopenharmony_ci  void movzx_b(Register dst, Operand src);
5221cb0ef41Sopenharmony_ci
5231cb0ef41Sopenharmony_ci  void movzx_w(Register dst, Register src) { movzx_w(dst, Operand(src)); }
5241cb0ef41Sopenharmony_ci  void movzx_w(Register dst, Operand src);
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_ci  void movq(XMMRegister dst, Operand src);
5271cb0ef41Sopenharmony_ci  void movq(Operand dst, XMMRegister src);
5281cb0ef41Sopenharmony_ci
5291cb0ef41Sopenharmony_ci  // Conditional moves
5301cb0ef41Sopenharmony_ci  void cmov(Condition cc, Register dst, Register src) {
5311cb0ef41Sopenharmony_ci    cmov(cc, dst, Operand(src));
5321cb0ef41Sopenharmony_ci  }
5331cb0ef41Sopenharmony_ci  void cmov(Condition cc, Register dst, Operand src);
5341cb0ef41Sopenharmony_ci
5351cb0ef41Sopenharmony_ci  // Flag management.
5361cb0ef41Sopenharmony_ci  void cld();
5371cb0ef41Sopenharmony_ci
5381cb0ef41Sopenharmony_ci  // Repetitive string instructions.
5391cb0ef41Sopenharmony_ci  void rep_movs();
5401cb0ef41Sopenharmony_ci  void rep_stos();
5411cb0ef41Sopenharmony_ci  void stos();
5421cb0ef41Sopenharmony_ci
5431cb0ef41Sopenharmony_ci  void xadd(Operand dst, Register src);
5441cb0ef41Sopenharmony_ci  void xadd_b(Operand dst, Register src);
5451cb0ef41Sopenharmony_ci  void xadd_w(Operand dst, Register src);
5461cb0ef41Sopenharmony_ci
5471cb0ef41Sopenharmony_ci  // Exchange
5481cb0ef41Sopenharmony_ci  void xchg(Register dst, Register src);
5491cb0ef41Sopenharmony_ci  void xchg(Register dst, Operand src);
5501cb0ef41Sopenharmony_ci  void xchg_b(Register reg, Operand op);
5511cb0ef41Sopenharmony_ci  void xchg_w(Register reg, Operand op);
5521cb0ef41Sopenharmony_ci
5531cb0ef41Sopenharmony_ci  // Lock prefix
5541cb0ef41Sopenharmony_ci  void lock();
5551cb0ef41Sopenharmony_ci
5561cb0ef41Sopenharmony_ci  // CompareExchange
5571cb0ef41Sopenharmony_ci  void cmpxchg(Operand dst, Register src);
5581cb0ef41Sopenharmony_ci  void cmpxchg_b(Operand dst, Register src);
5591cb0ef41Sopenharmony_ci  void cmpxchg_w(Operand dst, Register src);
5601cb0ef41Sopenharmony_ci  void cmpxchg8b(Operand dst);
5611cb0ef41Sopenharmony_ci
5621cb0ef41Sopenharmony_ci  // Memory Fence
5631cb0ef41Sopenharmony_ci  void mfence();
5641cb0ef41Sopenharmony_ci  void lfence();
5651cb0ef41Sopenharmony_ci
5661cb0ef41Sopenharmony_ci  void pause();
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci  // Arithmetics
5691cb0ef41Sopenharmony_ci  void adc(Register dst, int32_t imm32);
5701cb0ef41Sopenharmony_ci  void adc(Register dst, Register src) { adc(dst, Operand(src)); }
5711cb0ef41Sopenharmony_ci  void adc(Register dst, Operand src);
5721cb0ef41Sopenharmony_ci
5731cb0ef41Sopenharmony_ci  void add(Register dst, Register src) { add(dst, Operand(src)); }
5741cb0ef41Sopenharmony_ci  void add(Register dst, Operand src);
5751cb0ef41Sopenharmony_ci  void add(Operand dst, Register src);
5761cb0ef41Sopenharmony_ci  void add(Register dst, const Immediate& imm) { add(Operand(dst), imm); }
5771cb0ef41Sopenharmony_ci  void add(Operand dst, const Immediate& x);
5781cb0ef41Sopenharmony_ci
5791cb0ef41Sopenharmony_ci  void and_(Register dst, int32_t imm32);
5801cb0ef41Sopenharmony_ci  void and_(Register dst, const Immediate& x);
5811cb0ef41Sopenharmony_ci  void and_(Register dst, Register src) { and_(dst, Operand(src)); }
5821cb0ef41Sopenharmony_ci  void and_(Register dst, Operand src);
5831cb0ef41Sopenharmony_ci  void and_(Operand dst, Register src);
5841cb0ef41Sopenharmony_ci  void and_(Operand dst, const Immediate& x);
5851cb0ef41Sopenharmony_ci
5861cb0ef41Sopenharmony_ci  void cmpb(Register reg, Immediate imm8) {
5871cb0ef41Sopenharmony_ci    DCHECK(reg.is_byte_register());
5881cb0ef41Sopenharmony_ci    cmpb(Operand(reg), imm8);
5891cb0ef41Sopenharmony_ci  }
5901cb0ef41Sopenharmony_ci  void cmpb(Operand op, Immediate imm8);
5911cb0ef41Sopenharmony_ci  void cmpb(Register reg, Operand op);
5921cb0ef41Sopenharmony_ci  void cmpb(Operand op, Register reg);
5931cb0ef41Sopenharmony_ci  void cmpb(Register dst, Register src) { cmpb(Operand(dst), src); }
5941cb0ef41Sopenharmony_ci  void cmpb_al(Operand op);
5951cb0ef41Sopenharmony_ci  void cmpw_ax(Operand op);
5961cb0ef41Sopenharmony_ci  void cmpw(Operand dst, Immediate src);
5971cb0ef41Sopenharmony_ci  void cmpw(Register dst, Immediate src) { cmpw(Operand(dst), src); }
5981cb0ef41Sopenharmony_ci  void cmpw(Register dst, Operand src);
5991cb0ef41Sopenharmony_ci  void cmpw(Register dst, Register src) { cmpw(Operand(dst), src); }
6001cb0ef41Sopenharmony_ci  void cmpw(Operand dst, Register src);
6011cb0ef41Sopenharmony_ci  void cmp(Register reg, int32_t imm32);
6021cb0ef41Sopenharmony_ci  void cmp(Register reg, Handle<HeapObject> handle);
6031cb0ef41Sopenharmony_ci  void cmp(Register reg0, Register reg1) { cmp(reg0, Operand(reg1)); }
6041cb0ef41Sopenharmony_ci  void cmp(Register reg, Operand op);
6051cb0ef41Sopenharmony_ci  void cmp(Register reg, const Immediate& imm) { cmp(Operand(reg), imm); }
6061cb0ef41Sopenharmony_ci  void cmp(Operand op, Register reg);
6071cb0ef41Sopenharmony_ci  void cmp(Operand op, const Immediate& imm);
6081cb0ef41Sopenharmony_ci  void cmp(Operand op, Handle<HeapObject> handle);
6091cb0ef41Sopenharmony_ci
6101cb0ef41Sopenharmony_ci  void dec_b(Register dst);
6111cb0ef41Sopenharmony_ci  void dec_b(Operand dst);
6121cb0ef41Sopenharmony_ci
6131cb0ef41Sopenharmony_ci  void dec(Register dst);
6141cb0ef41Sopenharmony_ci  void dec(Operand dst);
6151cb0ef41Sopenharmony_ci
6161cb0ef41Sopenharmony_ci  void cdq();
6171cb0ef41Sopenharmony_ci
6181cb0ef41Sopenharmony_ci  void idiv(Register src) { idiv(Operand(src)); }
6191cb0ef41Sopenharmony_ci  void idiv(Operand src);
6201cb0ef41Sopenharmony_ci  void div(Register src) { div(Operand(src)); }
6211cb0ef41Sopenharmony_ci  void div(Operand src);
6221cb0ef41Sopenharmony_ci
6231cb0ef41Sopenharmony_ci  // Signed multiply instructions.
6241cb0ef41Sopenharmony_ci  void imul(Register src);  // edx:eax = eax * src.
6251cb0ef41Sopenharmony_ci  void imul(Register dst, Register src) { imul(dst, Operand(src)); }
6261cb0ef41Sopenharmony_ci  void imul(Register dst, Operand src);                  // dst = dst * src.
6271cb0ef41Sopenharmony_ci  void imul(Register dst, Register src, int32_t imm32);  // dst = src * imm32.
6281cb0ef41Sopenharmony_ci  void imul(Register dst, Operand src, int32_t imm32);
6291cb0ef41Sopenharmony_ci
6301cb0ef41Sopenharmony_ci  void inc(Register dst);
6311cb0ef41Sopenharmony_ci  void inc(Operand dst);
6321cb0ef41Sopenharmony_ci
6331cb0ef41Sopenharmony_ci  void lea(Register dst, Operand src);
6341cb0ef41Sopenharmony_ci
6351cb0ef41Sopenharmony_ci  // Unsigned multiply instruction.
6361cb0ef41Sopenharmony_ci  void mul(Register src);  // edx:eax = eax * reg.
6371cb0ef41Sopenharmony_ci
6381cb0ef41Sopenharmony_ci  void neg(Register dst);
6391cb0ef41Sopenharmony_ci  void neg(Operand dst);
6401cb0ef41Sopenharmony_ci
6411cb0ef41Sopenharmony_ci  void not_(Register dst);
6421cb0ef41Sopenharmony_ci  void not_(Operand dst);
6431cb0ef41Sopenharmony_ci
6441cb0ef41Sopenharmony_ci  void or_(Register dst, int32_t imm32);
6451cb0ef41Sopenharmony_ci  void or_(Register dst, Register src) { or_(dst, Operand(src)); }
6461cb0ef41Sopenharmony_ci  void or_(Register dst, Operand src);
6471cb0ef41Sopenharmony_ci  void or_(Operand dst, Register src);
6481cb0ef41Sopenharmony_ci  void or_(Register dst, const Immediate& imm) { or_(Operand(dst), imm); }
6491cb0ef41Sopenharmony_ci  void or_(Operand dst, const Immediate& x);
6501cb0ef41Sopenharmony_ci
6511cb0ef41Sopenharmony_ci  void rcl(Register dst, uint8_t imm8);
6521cb0ef41Sopenharmony_ci  void rcr(Register dst, uint8_t imm8);
6531cb0ef41Sopenharmony_ci
6541cb0ef41Sopenharmony_ci  void rol(Register dst, uint8_t imm8) { rol(Operand(dst), imm8); }
6551cb0ef41Sopenharmony_ci  void rol(Operand dst, uint8_t imm8);
6561cb0ef41Sopenharmony_ci  void rol_cl(Register dst) { rol_cl(Operand(dst)); }
6571cb0ef41Sopenharmony_ci  void rol_cl(Operand dst);
6581cb0ef41Sopenharmony_ci
6591cb0ef41Sopenharmony_ci  void ror(Register dst, uint8_t imm8) { ror(Operand(dst), imm8); }
6601cb0ef41Sopenharmony_ci  void ror(Operand dst, uint8_t imm8);
6611cb0ef41Sopenharmony_ci  void ror_cl(Register dst) { ror_cl(Operand(dst)); }
6621cb0ef41Sopenharmony_ci  void ror_cl(Operand dst);
6631cb0ef41Sopenharmony_ci
6641cb0ef41Sopenharmony_ci  void sar(Register dst, uint8_t imm8) { sar(Operand(dst), imm8); }
6651cb0ef41Sopenharmony_ci  void sar(Operand dst, uint8_t imm8);
6661cb0ef41Sopenharmony_ci  void sar_cl(Register dst) { sar_cl(Operand(dst)); }
6671cb0ef41Sopenharmony_ci  void sar_cl(Operand dst);
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_ci  void sbb(Register dst, Register src) { sbb(dst, Operand(src)); }
6701cb0ef41Sopenharmony_ci  void sbb(Register dst, Operand src);
6711cb0ef41Sopenharmony_ci
6721cb0ef41Sopenharmony_ci  void shl(Register dst, uint8_t imm8) { shl(Operand(dst), imm8); }
6731cb0ef41Sopenharmony_ci  void shl(Operand dst, uint8_t imm8);
6741cb0ef41Sopenharmony_ci  void shl_cl(Register dst) { shl_cl(Operand(dst)); }
6751cb0ef41Sopenharmony_ci  void shl_cl(Operand dst);
6761cb0ef41Sopenharmony_ci  void shld(Register dst, Register src, uint8_t shift);
6771cb0ef41Sopenharmony_ci  void shld_cl(Register dst, Register src);
6781cb0ef41Sopenharmony_ci
6791cb0ef41Sopenharmony_ci  void shr(Register dst, uint8_t imm8) { shr(Operand(dst), imm8); }
6801cb0ef41Sopenharmony_ci  void shr(Operand dst, uint8_t imm8);
6811cb0ef41Sopenharmony_ci  void shr_cl(Register dst) { shr_cl(Operand(dst)); }
6821cb0ef41Sopenharmony_ci  void shr_cl(Operand dst);
6831cb0ef41Sopenharmony_ci  void shrd(Register dst, Register src, uint8_t shift);
6841cb0ef41Sopenharmony_ci  void shrd_cl(Register dst, Register src) { shrd_cl(Operand(dst), src); }
6851cb0ef41Sopenharmony_ci  void shrd_cl(Operand dst, Register src);
6861cb0ef41Sopenharmony_ci
6871cb0ef41Sopenharmony_ci  void sub(Register dst, const Immediate& imm) { sub(Operand(dst), imm); }
6881cb0ef41Sopenharmony_ci  void sub(Operand dst, const Immediate& x);
6891cb0ef41Sopenharmony_ci  void sub(Register dst, Register src) { sub(dst, Operand(src)); }
6901cb0ef41Sopenharmony_ci  void sub(Register dst, Operand src);
6911cb0ef41Sopenharmony_ci  void sub(Operand dst, Register src);
6921cb0ef41Sopenharmony_ci  void sub_sp_32(uint32_t imm);
6931cb0ef41Sopenharmony_ci
6941cb0ef41Sopenharmony_ci  void test(Register reg, const Immediate& imm);
6951cb0ef41Sopenharmony_ci  void test(Register reg0, Register reg1) { test(reg0, Operand(reg1)); }
6961cb0ef41Sopenharmony_ci  void test(Register reg, Operand op);
6971cb0ef41Sopenharmony_ci  void test(Operand op, const Immediate& imm);
6981cb0ef41Sopenharmony_ci  void test(Operand op, Register reg) { test(reg, op); }
6991cb0ef41Sopenharmony_ci  void test_b(Register reg, Operand op);
7001cb0ef41Sopenharmony_ci  void test_b(Register reg, Immediate imm8);
7011cb0ef41Sopenharmony_ci  void test_b(Operand op, Immediate imm8);
7021cb0ef41Sopenharmony_ci  void test_b(Operand op, Register reg) { test_b(reg, op); }
7031cb0ef41Sopenharmony_ci  void test_b(Register dst, Register src) { test_b(dst, Operand(src)); }
7041cb0ef41Sopenharmony_ci  void test_w(Register reg, Operand op);
7051cb0ef41Sopenharmony_ci  void test_w(Register reg, Immediate imm16);
7061cb0ef41Sopenharmony_ci  void test_w(Operand op, Immediate imm16);
7071cb0ef41Sopenharmony_ci  void test_w(Operand op, Register reg) { test_w(reg, op); }
7081cb0ef41Sopenharmony_ci  void test_w(Register dst, Register src) { test_w(dst, Operand(src)); }
7091cb0ef41Sopenharmony_ci
7101cb0ef41Sopenharmony_ci  void xor_(Register dst, int32_t imm32);
7111cb0ef41Sopenharmony_ci  void xor_(Register dst, Register src) { xor_(dst, Operand(src)); }
7121cb0ef41Sopenharmony_ci  void xor_(Register dst, Operand src);
7131cb0ef41Sopenharmony_ci  void xor_(Operand dst, Register src);
7141cb0ef41Sopenharmony_ci  void xor_(Register dst, const Immediate& imm) { xor_(Operand(dst), imm); }
7151cb0ef41Sopenharmony_ci  void xor_(Operand dst, const Immediate& x);
7161cb0ef41Sopenharmony_ci
7171cb0ef41Sopenharmony_ci  // Bit operations.
7181cb0ef41Sopenharmony_ci  void bswap(Register dst);
7191cb0ef41Sopenharmony_ci  void bt(Operand dst, Register src);
7201cb0ef41Sopenharmony_ci  void bts(Register dst, Register src) { bts(Operand(dst), src); }
7211cb0ef41Sopenharmony_ci  void bts(Operand dst, Register src);
7221cb0ef41Sopenharmony_ci  void bsr(Register dst, Register src) { bsr(dst, Operand(src)); }
7231cb0ef41Sopenharmony_ci  void bsr(Register dst, Operand src);
7241cb0ef41Sopenharmony_ci  void bsf(Register dst, Register src) { bsf(dst, Operand(src)); }
7251cb0ef41Sopenharmony_ci  void bsf(Register dst, Operand src);
7261cb0ef41Sopenharmony_ci
7271cb0ef41Sopenharmony_ci  // Miscellaneous
7281cb0ef41Sopenharmony_ci  void hlt();
7291cb0ef41Sopenharmony_ci  void int3();
7301cb0ef41Sopenharmony_ci  void nop();
7311cb0ef41Sopenharmony_ci  void ret(int imm16);
7321cb0ef41Sopenharmony_ci  void ud2();
7331cb0ef41Sopenharmony_ci
7341cb0ef41Sopenharmony_ci  // Label operations & relative jumps (PPUM Appendix D)
7351cb0ef41Sopenharmony_ci  //
7361cb0ef41Sopenharmony_ci  // Takes a branch opcode (cc) and a label (L) and generates
7371cb0ef41Sopenharmony_ci  // either a backward branch or a forward branch and links it
7381cb0ef41Sopenharmony_ci  // to the label fixup chain. Usage:
7391cb0ef41Sopenharmony_ci  //
7401cb0ef41Sopenharmony_ci  // Label L;    // unbound label
7411cb0ef41Sopenharmony_ci  // j(cc, &L);  // forward branch to unbound label
7421cb0ef41Sopenharmony_ci  // bind(&L);   // bind label to the current pc
7431cb0ef41Sopenharmony_ci  // j(cc, &L);  // backward branch to bound label
7441cb0ef41Sopenharmony_ci  // bind(&L);   // illegal: a label may be bound only once
7451cb0ef41Sopenharmony_ci  //
7461cb0ef41Sopenharmony_ci  // Note: The same Label can be used for forward and backward branches
7471cb0ef41Sopenharmony_ci  // but it may be bound only once.
7481cb0ef41Sopenharmony_ci
7491cb0ef41Sopenharmony_ci  void bind(Label* L);  // binds an unbound label L to the current code position
7501cb0ef41Sopenharmony_ci
7511cb0ef41Sopenharmony_ci  // Calls
7521cb0ef41Sopenharmony_ci  void call(Label* L);
7531cb0ef41Sopenharmony_ci  void call(Address entry, RelocInfo::Mode rmode);
7541cb0ef41Sopenharmony_ci  void call(Register reg) { call(Operand(reg)); }
7551cb0ef41Sopenharmony_ci  void call(Operand adr);
7561cb0ef41Sopenharmony_ci  void call(Handle<Code> code, RelocInfo::Mode rmode);
7571cb0ef41Sopenharmony_ci  void wasm_call(Address address, RelocInfo::Mode rmode);
7581cb0ef41Sopenharmony_ci
7591cb0ef41Sopenharmony_ci  // Jumps
7601cb0ef41Sopenharmony_ci  // unconditional jump to L
7611cb0ef41Sopenharmony_ci  void jmp(Label* L, Label::Distance distance = Label::kFar);
7621cb0ef41Sopenharmony_ci  void jmp(Address entry, RelocInfo::Mode rmode);
7631cb0ef41Sopenharmony_ci  void jmp(Register reg) { jmp(Operand(reg)); }
7641cb0ef41Sopenharmony_ci  void jmp(Operand adr);
7651cb0ef41Sopenharmony_ci  void jmp(Handle<Code> code, RelocInfo::Mode rmode);
7661cb0ef41Sopenharmony_ci  // Unconditional jump relative to the current address. Low-level routine,
7671cb0ef41Sopenharmony_ci  // use with caution!
7681cb0ef41Sopenharmony_ci  void jmp_rel(int offset);
7691cb0ef41Sopenharmony_ci
7701cb0ef41Sopenharmony_ci  // Conditional jumps
7711cb0ef41Sopenharmony_ci  void j(Condition cc, Label* L, Label::Distance distance = Label::kFar);
7721cb0ef41Sopenharmony_ci  void j(Condition cc, byte* entry, RelocInfo::Mode rmode);
7731cb0ef41Sopenharmony_ci  void j(Condition cc, Handle<Code> code,
7741cb0ef41Sopenharmony_ci         RelocInfo::Mode rmode = RelocInfo::CODE_TARGET);
7751cb0ef41Sopenharmony_ci
7761cb0ef41Sopenharmony_ci  // Floating-point operations
7771cb0ef41Sopenharmony_ci  void fld(int i);
7781cb0ef41Sopenharmony_ci  void fstp(int i);
7791cb0ef41Sopenharmony_ci
7801cb0ef41Sopenharmony_ci  void fld1();
7811cb0ef41Sopenharmony_ci  void fldz();
7821cb0ef41Sopenharmony_ci  void fldpi();
7831cb0ef41Sopenharmony_ci  void fldln2();
7841cb0ef41Sopenharmony_ci
7851cb0ef41Sopenharmony_ci  void fld_s(Operand adr);
7861cb0ef41Sopenharmony_ci  void fld_d(Operand adr);
7871cb0ef41Sopenharmony_ci
7881cb0ef41Sopenharmony_ci  void fstp_s(Operand adr);
7891cb0ef41Sopenharmony_ci  void fst_s(Operand adr);
7901cb0ef41Sopenharmony_ci  void fstp_d(Operand adr);
7911cb0ef41Sopenharmony_ci  void fst_d(Operand adr);
7921cb0ef41Sopenharmony_ci
7931cb0ef41Sopenharmony_ci  void fild_s(Operand adr);
7941cb0ef41Sopenharmony_ci  void fild_d(Operand adr);
7951cb0ef41Sopenharmony_ci
7961cb0ef41Sopenharmony_ci  void fist_s(Operand adr);
7971cb0ef41Sopenharmony_ci
7981cb0ef41Sopenharmony_ci  void fistp_s(Operand adr);
7991cb0ef41Sopenharmony_ci  void fistp_d(Operand adr);
8001cb0ef41Sopenharmony_ci
8011cb0ef41Sopenharmony_ci  // The fisttp instructions require SSE3.
8021cb0ef41Sopenharmony_ci  void fisttp_s(Operand adr);
8031cb0ef41Sopenharmony_ci  void fisttp_d(Operand adr);
8041cb0ef41Sopenharmony_ci
8051cb0ef41Sopenharmony_ci  void fabs();
8061cb0ef41Sopenharmony_ci  void fchs();
8071cb0ef41Sopenharmony_ci  void fcos();
8081cb0ef41Sopenharmony_ci  void fsin();
8091cb0ef41Sopenharmony_ci  void fptan();
8101cb0ef41Sopenharmony_ci  void fyl2x();
8111cb0ef41Sopenharmony_ci  void f2xm1();
8121cb0ef41Sopenharmony_ci  void fscale();
8131cb0ef41Sopenharmony_ci  void fninit();
8141cb0ef41Sopenharmony_ci
8151cb0ef41Sopenharmony_ci  void fadd(int i);
8161cb0ef41Sopenharmony_ci  void fadd_i(int i);
8171cb0ef41Sopenharmony_ci  void fsub(int i);
8181cb0ef41Sopenharmony_ci  void fsub_i(int i);
8191cb0ef41Sopenharmony_ci  void fmul(int i);
8201cb0ef41Sopenharmony_ci  void fmul_i(int i);
8211cb0ef41Sopenharmony_ci  void fdiv(int i);
8221cb0ef41Sopenharmony_ci  void fdiv_i(int i);
8231cb0ef41Sopenharmony_ci
8241cb0ef41Sopenharmony_ci  void fisub_s(Operand adr);
8251cb0ef41Sopenharmony_ci
8261cb0ef41Sopenharmony_ci  void faddp(int i = 1);
8271cb0ef41Sopenharmony_ci  void fsubp(int i = 1);
8281cb0ef41Sopenharmony_ci  void fsubrp(int i = 1);
8291cb0ef41Sopenharmony_ci  void fmulp(int i = 1);
8301cb0ef41Sopenharmony_ci  void fdivp(int i = 1);
8311cb0ef41Sopenharmony_ci  void fprem();
8321cb0ef41Sopenharmony_ci  void fprem1();
8331cb0ef41Sopenharmony_ci
8341cb0ef41Sopenharmony_ci  void fxch(int i = 1);
8351cb0ef41Sopenharmony_ci  void fincstp();
8361cb0ef41Sopenharmony_ci  void ffree(int i = 0);
8371cb0ef41Sopenharmony_ci
8381cb0ef41Sopenharmony_ci  void ftst();
8391cb0ef41Sopenharmony_ci  void fucomp(int i);
8401cb0ef41Sopenharmony_ci  void fucompp();
8411cb0ef41Sopenharmony_ci  void fucomi(int i);
8421cb0ef41Sopenharmony_ci  void fucomip();
8431cb0ef41Sopenharmony_ci  void fcompp();
8441cb0ef41Sopenharmony_ci  void fnstsw_ax();
8451cb0ef41Sopenharmony_ci  void fwait();
8461cb0ef41Sopenharmony_ci  void fnclex();
8471cb0ef41Sopenharmony_ci
8481cb0ef41Sopenharmony_ci  void frndint();
8491cb0ef41Sopenharmony_ci
8501cb0ef41Sopenharmony_ci  void sahf();
8511cb0ef41Sopenharmony_ci  void setcc(Condition cc, Register reg);
8521cb0ef41Sopenharmony_ci
8531cb0ef41Sopenharmony_ci  void cpuid();
8541cb0ef41Sopenharmony_ci
8551cb0ef41Sopenharmony_ci  // SSE instructions
8561cb0ef41Sopenharmony_ci  void addss(XMMRegister dst, XMMRegister src) { addss(dst, Operand(src)); }
8571cb0ef41Sopenharmony_ci  void addss(XMMRegister dst, Operand src);
8581cb0ef41Sopenharmony_ci  void subss(XMMRegister dst, XMMRegister src) { subss(dst, Operand(src)); }
8591cb0ef41Sopenharmony_ci  void subss(XMMRegister dst, Operand src);
8601cb0ef41Sopenharmony_ci  void mulss(XMMRegister dst, XMMRegister src) { mulss(dst, Operand(src)); }
8611cb0ef41Sopenharmony_ci  void mulss(XMMRegister dst, Operand src);
8621cb0ef41Sopenharmony_ci  void divss(XMMRegister dst, XMMRegister src) { divss(dst, Operand(src)); }
8631cb0ef41Sopenharmony_ci  void divss(XMMRegister dst, Operand src);
8641cb0ef41Sopenharmony_ci  void sqrtss(XMMRegister dst, XMMRegister src) { sqrtss(dst, Operand(src)); }
8651cb0ef41Sopenharmony_ci  void sqrtss(XMMRegister dst, Operand src);
8661cb0ef41Sopenharmony_ci
8671cb0ef41Sopenharmony_ci  void ucomiss(XMMRegister dst, XMMRegister src) { ucomiss(dst, Operand(src)); }
8681cb0ef41Sopenharmony_ci  void ucomiss(XMMRegister dst, Operand src);
8691cb0ef41Sopenharmony_ci  void movaps(XMMRegister dst, XMMRegister src) { movaps(dst, Operand(src)); }
8701cb0ef41Sopenharmony_ci  void movaps(XMMRegister dst, Operand src);
8711cb0ef41Sopenharmony_ci  void movups(XMMRegister dst, XMMRegister src) { movups(dst, Operand(src)); }
8721cb0ef41Sopenharmony_ci  void movups(XMMRegister dst, Operand src);
8731cb0ef41Sopenharmony_ci  void movups(Operand dst, XMMRegister src);
8741cb0ef41Sopenharmony_ci  void shufps(XMMRegister dst, XMMRegister src, byte imm8);
8751cb0ef41Sopenharmony_ci  void shufpd(XMMRegister dst, XMMRegister src, byte imm8);
8761cb0ef41Sopenharmony_ci
8771cb0ef41Sopenharmony_ci  void movhlps(XMMRegister dst, XMMRegister src);
8781cb0ef41Sopenharmony_ci  void movlhps(XMMRegister dst, XMMRegister src);
8791cb0ef41Sopenharmony_ci  void movlps(XMMRegister dst, Operand src);
8801cb0ef41Sopenharmony_ci  void movlps(Operand dst, XMMRegister src);
8811cb0ef41Sopenharmony_ci  void movhps(XMMRegister dst, Operand src);
8821cb0ef41Sopenharmony_ci  void movhps(Operand dst, XMMRegister src);
8831cb0ef41Sopenharmony_ci
8841cb0ef41Sopenharmony_ci  void maxss(XMMRegister dst, XMMRegister src) { maxss(dst, Operand(src)); }
8851cb0ef41Sopenharmony_ci  void maxss(XMMRegister dst, Operand src);
8861cb0ef41Sopenharmony_ci  void minss(XMMRegister dst, XMMRegister src) { minss(dst, Operand(src)); }
8871cb0ef41Sopenharmony_ci  void minss(XMMRegister dst, Operand src);
8881cb0ef41Sopenharmony_ci
8891cb0ef41Sopenharmony_ci  void haddps(XMMRegister dst, Operand src);
8901cb0ef41Sopenharmony_ci  void haddps(XMMRegister dst, XMMRegister src) { haddps(dst, Operand(src)); }
8911cb0ef41Sopenharmony_ci  void sqrtpd(XMMRegister dst, Operand src) {
8921cb0ef41Sopenharmony_ci    sse2_instr(dst, src, 0x66, 0x0F, 0x51);
8931cb0ef41Sopenharmony_ci  }
8941cb0ef41Sopenharmony_ci  void sqrtpd(XMMRegister dst, XMMRegister src) { sqrtpd(dst, Operand(src)); }
8951cb0ef41Sopenharmony_ci
8961cb0ef41Sopenharmony_ci  void cmpps(XMMRegister dst, Operand src, uint8_t cmp);
8971cb0ef41Sopenharmony_ci  void cmpps(XMMRegister dst, XMMRegister src, uint8_t cmp) {
8981cb0ef41Sopenharmony_ci    cmpps(dst, Operand(src), cmp);
8991cb0ef41Sopenharmony_ci  }
9001cb0ef41Sopenharmony_ci  void cmppd(XMMRegister dst, Operand src, uint8_t cmp);
9011cb0ef41Sopenharmony_ci  void cmppd(XMMRegister dst, XMMRegister src, uint8_t cmp) {
9021cb0ef41Sopenharmony_ci    cmppd(dst, Operand(src), cmp);
9031cb0ef41Sopenharmony_ci  }
9041cb0ef41Sopenharmony_ci
9051cb0ef41Sopenharmony_ci// Packed floating-point comparison operations.
9061cb0ef41Sopenharmony_ci#define PACKED_CMP_LIST(V) \
9071cb0ef41Sopenharmony_ci  V(cmpeq, 0x0)            \
9081cb0ef41Sopenharmony_ci  V(cmplt, 0x1)            \
9091cb0ef41Sopenharmony_ci  V(cmple, 0x2)            \
9101cb0ef41Sopenharmony_ci  V(cmpunord, 0x3)         \
9111cb0ef41Sopenharmony_ci  V(cmpneq, 0x4)
9121cb0ef41Sopenharmony_ci
9131cb0ef41Sopenharmony_ci#define SSE_CMP_P(instr, imm8)                                            \
9141cb0ef41Sopenharmony_ci  void instr##ps(XMMRegister dst, XMMRegister src) {                      \
9151cb0ef41Sopenharmony_ci    cmpps(dst, Operand(src), imm8);                                       \
9161cb0ef41Sopenharmony_ci  }                                                                       \
9171cb0ef41Sopenharmony_ci  void instr##ps(XMMRegister dst, Operand src) { cmpps(dst, src, imm8); } \
9181cb0ef41Sopenharmony_ci  void instr##pd(XMMRegister dst, XMMRegister src) {                      \
9191cb0ef41Sopenharmony_ci    cmppd(dst, Operand(src), imm8);                                       \
9201cb0ef41Sopenharmony_ci  }                                                                       \
9211cb0ef41Sopenharmony_ci  void instr##pd(XMMRegister dst, Operand src) { cmppd(dst, src, imm8); }
9221cb0ef41Sopenharmony_ci
9231cb0ef41Sopenharmony_ci  PACKED_CMP_LIST(SSE_CMP_P)
9241cb0ef41Sopenharmony_ci#undef SSE_CMP_P
9251cb0ef41Sopenharmony_ci
9261cb0ef41Sopenharmony_ci  // SSE2 instructions
9271cb0ef41Sopenharmony_ci  void cvttss2si(Register dst, Operand src);
9281cb0ef41Sopenharmony_ci  void cvttss2si(Register dst, XMMRegister src) {
9291cb0ef41Sopenharmony_ci    cvttss2si(dst, Operand(src));
9301cb0ef41Sopenharmony_ci  }
9311cb0ef41Sopenharmony_ci  void cvttsd2si(Register dst, Operand src);
9321cb0ef41Sopenharmony_ci  void cvttsd2si(Register dst, XMMRegister src) {
9331cb0ef41Sopenharmony_ci    cvttsd2si(dst, Operand(src));
9341cb0ef41Sopenharmony_ci  }
9351cb0ef41Sopenharmony_ci  void cvtsd2si(Register dst, XMMRegister src);
9361cb0ef41Sopenharmony_ci
9371cb0ef41Sopenharmony_ci  void cvtsi2ss(XMMRegister dst, Register src) { cvtsi2ss(dst, Operand(src)); }
9381cb0ef41Sopenharmony_ci  void cvtsi2ss(XMMRegister dst, Operand src);
9391cb0ef41Sopenharmony_ci  void cvtsi2sd(XMMRegister dst, Register src) { cvtsi2sd(dst, Operand(src)); }
9401cb0ef41Sopenharmony_ci  void cvtsi2sd(XMMRegister dst, Operand src);
9411cb0ef41Sopenharmony_ci  void cvtss2sd(XMMRegister dst, Operand src);
9421cb0ef41Sopenharmony_ci  void cvtss2sd(XMMRegister dst, XMMRegister src) {
9431cb0ef41Sopenharmony_ci    cvtss2sd(dst, Operand(src));
9441cb0ef41Sopenharmony_ci  }
9451cb0ef41Sopenharmony_ci  void cvtdq2pd(XMMRegister dst, XMMRegister src);
9461cb0ef41Sopenharmony_ci  void cvtpd2ps(XMMRegister dst, XMMRegister src);
9471cb0ef41Sopenharmony_ci  void cvttps2dq(XMMRegister dst, XMMRegister src) {
9481cb0ef41Sopenharmony_ci    cvttps2dq(dst, Operand(src));
9491cb0ef41Sopenharmony_ci  }
9501cb0ef41Sopenharmony_ci  void cvttps2dq(XMMRegister dst, Operand src);
9511cb0ef41Sopenharmony_ci  void cvttpd2dq(XMMRegister dst, XMMRegister src);
9521cb0ef41Sopenharmony_ci
9531cb0ef41Sopenharmony_ci  void ucomisd(XMMRegister dst, XMMRegister src) { ucomisd(dst, Operand(src)); }
9541cb0ef41Sopenharmony_ci  void ucomisd(XMMRegister dst, Operand src);
9551cb0ef41Sopenharmony_ci
9561cb0ef41Sopenharmony_ci  void roundss(XMMRegister dst, XMMRegister src, RoundingMode mode);
9571cb0ef41Sopenharmony_ci  void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode);
9581cb0ef41Sopenharmony_ci
9591cb0ef41Sopenharmony_ci  void movapd(XMMRegister dst, XMMRegister src) { movapd(dst, Operand(src)); }
9601cb0ef41Sopenharmony_ci  void movapd(XMMRegister dst, Operand src) {
9611cb0ef41Sopenharmony_ci    sse2_instr(dst, src, 0x66, 0x0F, 0x28);
9621cb0ef41Sopenharmony_ci  }
9631cb0ef41Sopenharmony_ci  void movupd(XMMRegister dst, Operand src) {
9641cb0ef41Sopenharmony_ci    sse2_instr(dst, src, 0x66, 0x0F, 0x10);
9651cb0ef41Sopenharmony_ci  }
9661cb0ef41Sopenharmony_ci
9671cb0ef41Sopenharmony_ci  void movmskpd(Register dst, XMMRegister src);
9681cb0ef41Sopenharmony_ci  void movmskps(Register dst, XMMRegister src);
9691cb0ef41Sopenharmony_ci
9701cb0ef41Sopenharmony_ci  void pmovmskb(Register dst, XMMRegister src);
9711cb0ef41Sopenharmony_ci
9721cb0ef41Sopenharmony_ci  void cmpltsd(XMMRegister dst, XMMRegister src);
9731cb0ef41Sopenharmony_ci
9741cb0ef41Sopenharmony_ci  void movdqa(XMMRegister dst, Operand src);
9751cb0ef41Sopenharmony_ci  void movdqa(Operand dst, XMMRegister src);
9761cb0ef41Sopenharmony_ci  void movdqa(XMMRegister dst, XMMRegister src);
9771cb0ef41Sopenharmony_ci  void movdqu(XMMRegister dst, Operand src);
9781cb0ef41Sopenharmony_ci  void movdqu(Operand dst, XMMRegister src);
9791cb0ef41Sopenharmony_ci  void movdqu(XMMRegister dst, XMMRegister src);
9801cb0ef41Sopenharmony_ci  void movdq(bool aligned, XMMRegister dst, Operand src) {
9811cb0ef41Sopenharmony_ci    if (aligned) {
9821cb0ef41Sopenharmony_ci      movdqa(dst, src);
9831cb0ef41Sopenharmony_ci    } else {
9841cb0ef41Sopenharmony_ci      movdqu(dst, src);
9851cb0ef41Sopenharmony_ci    }
9861cb0ef41Sopenharmony_ci  }
9871cb0ef41Sopenharmony_ci
9881cb0ef41Sopenharmony_ci  void movd(XMMRegister dst, Register src) { movd(dst, Operand(src)); }
9891cb0ef41Sopenharmony_ci  void movd(XMMRegister dst, Operand src);
9901cb0ef41Sopenharmony_ci  void movd(Register dst, XMMRegister src) { movd(Operand(dst), src); }
9911cb0ef41Sopenharmony_ci  void movd(Operand dst, XMMRegister src);
9921cb0ef41Sopenharmony_ci  void movsd(XMMRegister dst, XMMRegister src) { movsd(dst, Operand(src)); }
9931cb0ef41Sopenharmony_ci  void movsd(XMMRegister dst, Operand src);
9941cb0ef41Sopenharmony_ci  void movsd(Operand dst, XMMRegister src);
9951cb0ef41Sopenharmony_ci
9961cb0ef41Sopenharmony_ci  void movss(XMMRegister dst, Operand src);
9971cb0ef41Sopenharmony_ci  void movss(Operand dst, XMMRegister src);
9981cb0ef41Sopenharmony_ci  void movss(XMMRegister dst, XMMRegister src) { movss(dst, Operand(src)); }
9991cb0ef41Sopenharmony_ci
10001cb0ef41Sopenharmony_ci  void extractps(Operand dst, XMMRegister src, byte imm8);
10011cb0ef41Sopenharmony_ci  void extractps(Register dst, XMMRegister src, byte imm8);
10021cb0ef41Sopenharmony_ci
10031cb0ef41Sopenharmony_ci  void pcmpgtq(XMMRegister dst, XMMRegister src);
10041cb0ef41Sopenharmony_ci
10051cb0ef41Sopenharmony_ci  void psllw(XMMRegister reg, uint8_t shift);
10061cb0ef41Sopenharmony_ci  void pslld(XMMRegister reg, uint8_t shift);
10071cb0ef41Sopenharmony_ci  void psrlw(XMMRegister reg, uint8_t shift);
10081cb0ef41Sopenharmony_ci  void psrld(XMMRegister reg, uint8_t shift);
10091cb0ef41Sopenharmony_ci  void psraw(XMMRegister reg, uint8_t shift);
10101cb0ef41Sopenharmony_ci  void psrad(XMMRegister reg, uint8_t shift);
10111cb0ef41Sopenharmony_ci  void psllq(XMMRegister reg, uint8_t shift);
10121cb0ef41Sopenharmony_ci  void psrlq(XMMRegister reg, uint8_t shift);
10131cb0ef41Sopenharmony_ci
10141cb0ef41Sopenharmony_ci  void pshufhw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
10151cb0ef41Sopenharmony_ci    pshufhw(dst, Operand(src), shuffle);
10161cb0ef41Sopenharmony_ci  }
10171cb0ef41Sopenharmony_ci  void pshufhw(XMMRegister dst, Operand src, uint8_t shuffle);
10181cb0ef41Sopenharmony_ci  void pshuflw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
10191cb0ef41Sopenharmony_ci    pshuflw(dst, Operand(src), shuffle);
10201cb0ef41Sopenharmony_ci  }
10211cb0ef41Sopenharmony_ci  void pshuflw(XMMRegister dst, Operand src, uint8_t shuffle);
10221cb0ef41Sopenharmony_ci  void pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
10231cb0ef41Sopenharmony_ci    pshufd(dst, Operand(src), shuffle);
10241cb0ef41Sopenharmony_ci  }
10251cb0ef41Sopenharmony_ci  void pshufd(XMMRegister dst, Operand src, uint8_t shuffle);
10261cb0ef41Sopenharmony_ci
10271cb0ef41Sopenharmony_ci  void pblendw(XMMRegister dst, XMMRegister src, uint8_t mask) {
10281cb0ef41Sopenharmony_ci    pblendw(dst, Operand(src), mask);
10291cb0ef41Sopenharmony_ci  }
10301cb0ef41Sopenharmony_ci  void pblendw(XMMRegister dst, Operand src, uint8_t mask);
10311cb0ef41Sopenharmony_ci
10321cb0ef41Sopenharmony_ci  void palignr(XMMRegister dst, XMMRegister src, uint8_t mask) {
10331cb0ef41Sopenharmony_ci    palignr(dst, Operand(src), mask);
10341cb0ef41Sopenharmony_ci  }
10351cb0ef41Sopenharmony_ci  void palignr(XMMRegister dst, Operand src, uint8_t mask);
10361cb0ef41Sopenharmony_ci
10371cb0ef41Sopenharmony_ci  void pextrb(Register dst, XMMRegister src, uint8_t offset) {
10381cb0ef41Sopenharmony_ci    pextrb(Operand(dst), src, offset);
10391cb0ef41Sopenharmony_ci  }
10401cb0ef41Sopenharmony_ci  void pextrb(Operand dst, XMMRegister src, uint8_t offset);
10411cb0ef41Sopenharmony_ci  // SSE3 instructions
10421cb0ef41Sopenharmony_ci  void movddup(XMMRegister dst, Operand src);
10431cb0ef41Sopenharmony_ci  void movddup(XMMRegister dst, XMMRegister src) { movddup(dst, Operand(src)); }
10441cb0ef41Sopenharmony_ci  void movshdup(XMMRegister dst, XMMRegister src);
10451cb0ef41Sopenharmony_ci
10461cb0ef41Sopenharmony_ci  // Use SSE4_1 encoding for pextrw reg, xmm, imm8 for consistency
10471cb0ef41Sopenharmony_ci  void pextrw(Register dst, XMMRegister src, uint8_t offset) {
10481cb0ef41Sopenharmony_ci    pextrw(Operand(dst), src, offset);
10491cb0ef41Sopenharmony_ci  }
10501cb0ef41Sopenharmony_ci  void pextrw(Operand dst, XMMRegister src, uint8_t offset);
10511cb0ef41Sopenharmony_ci  void pextrd(Register dst, XMMRegister src, uint8_t offset) {
10521cb0ef41Sopenharmony_ci    pextrd(Operand(dst), src, offset);
10531cb0ef41Sopenharmony_ci  }
10541cb0ef41Sopenharmony_ci  void pextrd(Operand dst, XMMRegister src, uint8_t offset);
10551cb0ef41Sopenharmony_ci
10561cb0ef41Sopenharmony_ci  void insertps(XMMRegister dst, XMMRegister src, uint8_t offset) {
10571cb0ef41Sopenharmony_ci    insertps(dst, Operand(src), offset);
10581cb0ef41Sopenharmony_ci  }
10591cb0ef41Sopenharmony_ci  void insertps(XMMRegister dst, Operand src, uint8_t offset);
10601cb0ef41Sopenharmony_ci  void pinsrb(XMMRegister dst, Register src, uint8_t offset) {
10611cb0ef41Sopenharmony_ci    pinsrb(dst, Operand(src), offset);
10621cb0ef41Sopenharmony_ci  }
10631cb0ef41Sopenharmony_ci  void pinsrb(XMMRegister dst, Operand src, uint8_t offset);
10641cb0ef41Sopenharmony_ci  void pinsrw(XMMRegister dst, Register src, uint8_t offset) {
10651cb0ef41Sopenharmony_ci    pinsrw(dst, Operand(src), offset);
10661cb0ef41Sopenharmony_ci  }
10671cb0ef41Sopenharmony_ci  void pinsrw(XMMRegister dst, Operand src, uint8_t offset);
10681cb0ef41Sopenharmony_ci  void pinsrd(XMMRegister dst, Register src, uint8_t offset) {
10691cb0ef41Sopenharmony_ci    pinsrd(dst, Operand(src), offset);
10701cb0ef41Sopenharmony_ci  }
10711cb0ef41Sopenharmony_ci  void pinsrd(XMMRegister dst, Operand src, uint8_t offset);
10721cb0ef41Sopenharmony_ci
10731cb0ef41Sopenharmony_ci  void roundps(XMMRegister dst, XMMRegister src, RoundingMode mode);
10741cb0ef41Sopenharmony_ci  void roundpd(XMMRegister dst, XMMRegister src, RoundingMode mode);
10751cb0ef41Sopenharmony_ci
10761cb0ef41Sopenharmony_ci  // AVX instructions
10771cb0ef41Sopenharmony_ci  void vaddss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
10781cb0ef41Sopenharmony_ci    vaddss(dst, src1, Operand(src2));
10791cb0ef41Sopenharmony_ci  }
10801cb0ef41Sopenharmony_ci  void vaddss(XMMRegister dst, XMMRegister src1, Operand src2) {
10811cb0ef41Sopenharmony_ci    vss(0x58, dst, src1, src2);
10821cb0ef41Sopenharmony_ci  }
10831cb0ef41Sopenharmony_ci  void vsubss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
10841cb0ef41Sopenharmony_ci    vsubss(dst, src1, Operand(src2));
10851cb0ef41Sopenharmony_ci  }
10861cb0ef41Sopenharmony_ci  void vsubss(XMMRegister dst, XMMRegister src1, Operand src2) {
10871cb0ef41Sopenharmony_ci    vss(0x5c, dst, src1, src2);
10881cb0ef41Sopenharmony_ci  }
10891cb0ef41Sopenharmony_ci  void vmulss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
10901cb0ef41Sopenharmony_ci    vmulss(dst, src1, Operand(src2));
10911cb0ef41Sopenharmony_ci  }
10921cb0ef41Sopenharmony_ci  void vmulss(XMMRegister dst, XMMRegister src1, Operand src2) {
10931cb0ef41Sopenharmony_ci    vss(0x59, dst, src1, src2);
10941cb0ef41Sopenharmony_ci  }
10951cb0ef41Sopenharmony_ci  void vdivss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
10961cb0ef41Sopenharmony_ci    vdivss(dst, src1, Operand(src2));
10971cb0ef41Sopenharmony_ci  }
10981cb0ef41Sopenharmony_ci  void vdivss(XMMRegister dst, XMMRegister src1, Operand src2) {
10991cb0ef41Sopenharmony_ci    vss(0x5e, dst, src1, src2);
11001cb0ef41Sopenharmony_ci  }
11011cb0ef41Sopenharmony_ci  void vmaxss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
11021cb0ef41Sopenharmony_ci    vmaxss(dst, src1, Operand(src2));
11031cb0ef41Sopenharmony_ci  }
11041cb0ef41Sopenharmony_ci  void vmaxss(XMMRegister dst, XMMRegister src1, Operand src2) {
11051cb0ef41Sopenharmony_ci    vss(0x5f, dst, src1, src2);
11061cb0ef41Sopenharmony_ci  }
11071cb0ef41Sopenharmony_ci  void vminss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
11081cb0ef41Sopenharmony_ci    vminss(dst, src1, Operand(src2));
11091cb0ef41Sopenharmony_ci  }
11101cb0ef41Sopenharmony_ci  void vminss(XMMRegister dst, XMMRegister src1, Operand src2) {
11111cb0ef41Sopenharmony_ci    vss(0x5d, dst, src1, src2);
11121cb0ef41Sopenharmony_ci  }
11131cb0ef41Sopenharmony_ci  void vsqrtss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
11141cb0ef41Sopenharmony_ci    vsqrtss(dst, src1, Operand(src2));
11151cb0ef41Sopenharmony_ci  }
11161cb0ef41Sopenharmony_ci  void vsqrtss(XMMRegister dst, XMMRegister src1, Operand src2) {
11171cb0ef41Sopenharmony_ci    vss(0x51, dst, src1, src2);
11181cb0ef41Sopenharmony_ci  }
11191cb0ef41Sopenharmony_ci  void vss(byte op, XMMRegister dst, XMMRegister src1, Operand src2);
11201cb0ef41Sopenharmony_ci
11211cb0ef41Sopenharmony_ci  void vhaddps(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
11221cb0ef41Sopenharmony_ci    vhaddps(dst, src1, Operand(src2));
11231cb0ef41Sopenharmony_ci  }
11241cb0ef41Sopenharmony_ci  void vhaddps(XMMRegister dst, XMMRegister src1, Operand src2) {
11251cb0ef41Sopenharmony_ci    vinstr(0x7C, dst, src1, src2, kF2, k0F, kWIG);
11261cb0ef41Sopenharmony_ci  }
11271cb0ef41Sopenharmony_ci  void vsqrtpd(XMMRegister dst, XMMRegister src) { vsqrtpd(dst, Operand(src)); }
11281cb0ef41Sopenharmony_ci  void vsqrtpd(XMMRegister dst, Operand src) {
11291cb0ef41Sopenharmony_ci    vinstr(0x51, dst, xmm0, src, k66, k0F, kWIG);
11301cb0ef41Sopenharmony_ci  }
11311cb0ef41Sopenharmony_ci  void vmovss(Operand dst, XMMRegister src) {
11321cb0ef41Sopenharmony_ci    vinstr(0x11, src, xmm0, dst, kF3, k0F, kWIG);
11331cb0ef41Sopenharmony_ci  }
11341cb0ef41Sopenharmony_ci  void vmovss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
11351cb0ef41Sopenharmony_ci    vinstr(0x10, dst, src1, src2, kF3, k0F, kWIG);
11361cb0ef41Sopenharmony_ci  }
11371cb0ef41Sopenharmony_ci  void vmovss(XMMRegister dst, Operand src) {
11381cb0ef41Sopenharmony_ci    vinstr(0x10, dst, xmm0, src, kF3, k0F, kWIG);
11391cb0ef41Sopenharmony_ci  }
11401cb0ef41Sopenharmony_ci  void vmovsd(Operand dst, XMMRegister src) {
11411cb0ef41Sopenharmony_ci    vinstr(0x11, src, xmm0, dst, kF2, k0F, kWIG);
11421cb0ef41Sopenharmony_ci  }
11431cb0ef41Sopenharmony_ci  void vmovsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
11441cb0ef41Sopenharmony_ci    vinstr(0x10, dst, src1, src2, kF2, k0F, kWIG);
11451cb0ef41Sopenharmony_ci  }
11461cb0ef41Sopenharmony_ci  void vmovsd(XMMRegister dst, Operand src) {
11471cb0ef41Sopenharmony_ci    vinstr(0x10, dst, xmm0, src, kF2, k0F, kWIG);
11481cb0ef41Sopenharmony_ci  }
11491cb0ef41Sopenharmony_ci
11501cb0ef41Sopenharmony_ci  void vextractps(Operand dst, XMMRegister src, byte imm8);
11511cb0ef41Sopenharmony_ci
11521cb0ef41Sopenharmony_ci  void vpcmpgtq(XMMRegister dst, XMMRegister src1, XMMRegister src2);
11531cb0ef41Sopenharmony_ci
11541cb0ef41Sopenharmony_ci  void vmovaps(XMMRegister dst, XMMRegister src) { vmovaps(dst, Operand(src)); }
11551cb0ef41Sopenharmony_ci  void vmovaps(XMMRegister dst, Operand src) { vps(0x28, dst, xmm0, src); }
11561cb0ef41Sopenharmony_ci  void vmovapd(XMMRegister dst, XMMRegister src) { vmovapd(dst, Operand(src)); }
11571cb0ef41Sopenharmony_ci  void vmovapd(XMMRegister dst, Operand src) { vpd(0x28, dst, xmm0, src); }
11581cb0ef41Sopenharmony_ci  void vmovups(Operand dst, XMMRegister src) { vps(0x11, src, xmm0, dst); }
11591cb0ef41Sopenharmony_ci  void vmovups(XMMRegister dst, XMMRegister src) { vmovups(dst, Operand(src)); }
11601cb0ef41Sopenharmony_ci  void vmovups(XMMRegister dst, Operand src) { vps(0x10, dst, xmm0, src); }
11611cb0ef41Sopenharmony_ci  void vmovupd(XMMRegister dst, Operand src) { vpd(0x10, dst, xmm0, src); }
11621cb0ef41Sopenharmony_ci  void vshufps(XMMRegister dst, XMMRegister src1, XMMRegister src2, byte imm8) {
11631cb0ef41Sopenharmony_ci    vshufps(dst, src1, Operand(src2), imm8);
11641cb0ef41Sopenharmony_ci  }
11651cb0ef41Sopenharmony_ci  void vshufps(XMMRegister dst, XMMRegister src1, Operand src2, byte imm8);
11661cb0ef41Sopenharmony_ci  void vshufpd(XMMRegister dst, XMMRegister src1, XMMRegister src2, byte imm8) {
11671cb0ef41Sopenharmony_ci    vshufpd(dst, src1, Operand(src2), imm8);
11681cb0ef41Sopenharmony_ci  }
11691cb0ef41Sopenharmony_ci  void vshufpd(XMMRegister dst, XMMRegister src1, Operand src2, byte imm8);
11701cb0ef41Sopenharmony_ci
11711cb0ef41Sopenharmony_ci  void vmovhlps(XMMRegister dst, XMMRegister src1, XMMRegister src2);
11721cb0ef41Sopenharmony_ci  void vmovlhps(XMMRegister dst, XMMRegister src1, XMMRegister src2);
11731cb0ef41Sopenharmony_ci  void vmovlps(XMMRegister dst, XMMRegister src1, Operand src2);
11741cb0ef41Sopenharmony_ci  void vmovlps(Operand dst, XMMRegister src);
11751cb0ef41Sopenharmony_ci  void vmovhps(XMMRegister dst, XMMRegister src1, Operand src2);
11761cb0ef41Sopenharmony_ci  void vmovhps(Operand dst, XMMRegister src);
11771cb0ef41Sopenharmony_ci
11781cb0ef41Sopenharmony_ci  void vpsllw(XMMRegister dst, XMMRegister src, uint8_t imm8);
11791cb0ef41Sopenharmony_ci  void vpslld(XMMRegister dst, XMMRegister src, uint8_t imm8);
11801cb0ef41Sopenharmony_ci  void vpsllq(XMMRegister dst, XMMRegister src, uint8_t imm8);
11811cb0ef41Sopenharmony_ci  void vpsrlw(XMMRegister dst, XMMRegister src, uint8_t imm8);
11821cb0ef41Sopenharmony_ci  void vpsrld(XMMRegister dst, XMMRegister src, uint8_t imm8);
11831cb0ef41Sopenharmony_ci  void vpsraw(XMMRegister dst, XMMRegister src, uint8_t imm8);
11841cb0ef41Sopenharmony_ci  void vpsrad(XMMRegister dst, XMMRegister src, uint8_t imm8);
11851cb0ef41Sopenharmony_ci  void vpsrlq(XMMRegister dst, XMMRegister src, uint8_t imm8);
11861cb0ef41Sopenharmony_ci
11871cb0ef41Sopenharmony_ci  void vpshufhw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
11881cb0ef41Sopenharmony_ci    vpshufhw(dst, Operand(src), shuffle);
11891cb0ef41Sopenharmony_ci  }
11901cb0ef41Sopenharmony_ci  void vpshufhw(XMMRegister dst, Operand src, uint8_t shuffle);
11911cb0ef41Sopenharmony_ci  void vpshuflw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
11921cb0ef41Sopenharmony_ci    vpshuflw(dst, Operand(src), shuffle);
11931cb0ef41Sopenharmony_ci  }
11941cb0ef41Sopenharmony_ci  void vpshuflw(XMMRegister dst, Operand src, uint8_t shuffle);
11951cb0ef41Sopenharmony_ci  void vpshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
11961cb0ef41Sopenharmony_ci    vpshufd(dst, Operand(src), shuffle);
11971cb0ef41Sopenharmony_ci  }
11981cb0ef41Sopenharmony_ci  void vpshufd(XMMRegister dst, Operand src, uint8_t shuffle);
11991cb0ef41Sopenharmony_ci
12001cb0ef41Sopenharmony_ci  void vblendvps(XMMRegister dst, XMMRegister src1, XMMRegister src2,
12011cb0ef41Sopenharmony_ci                 XMMRegister mask);
12021cb0ef41Sopenharmony_ci  void vblendvpd(XMMRegister dst, XMMRegister src1, XMMRegister src2,
12031cb0ef41Sopenharmony_ci                 XMMRegister mask);
12041cb0ef41Sopenharmony_ci  void vpblendvb(XMMRegister dst, XMMRegister src1, XMMRegister src2,
12051cb0ef41Sopenharmony_ci                 XMMRegister mask);
12061cb0ef41Sopenharmony_ci
12071cb0ef41Sopenharmony_ci  void vpblendw(XMMRegister dst, XMMRegister src1, XMMRegister src2,
12081cb0ef41Sopenharmony_ci                uint8_t mask) {
12091cb0ef41Sopenharmony_ci    vpblendw(dst, src1, Operand(src2), mask);
12101cb0ef41Sopenharmony_ci  }
12111cb0ef41Sopenharmony_ci  void vpblendw(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t mask);
12121cb0ef41Sopenharmony_ci
12131cb0ef41Sopenharmony_ci  void vpalignr(XMMRegister dst, XMMRegister src1, XMMRegister src2,
12141cb0ef41Sopenharmony_ci                uint8_t mask) {
12151cb0ef41Sopenharmony_ci    vpalignr(dst, src1, Operand(src2), mask);
12161cb0ef41Sopenharmony_ci  }
12171cb0ef41Sopenharmony_ci  void vpalignr(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t mask);
12181cb0ef41Sopenharmony_ci
12191cb0ef41Sopenharmony_ci  void vpextrb(Register dst, XMMRegister src, uint8_t offset) {
12201cb0ef41Sopenharmony_ci    vpextrb(Operand(dst), src, offset);
12211cb0ef41Sopenharmony_ci  }
12221cb0ef41Sopenharmony_ci  void vpextrb(Operand dst, XMMRegister src, uint8_t offset);
12231cb0ef41Sopenharmony_ci  void vpextrw(Register dst, XMMRegister src, uint8_t offset) {
12241cb0ef41Sopenharmony_ci    vpextrw(Operand(dst), src, offset);
12251cb0ef41Sopenharmony_ci  }
12261cb0ef41Sopenharmony_ci  void vpextrw(Operand dst, XMMRegister src, uint8_t offset);
12271cb0ef41Sopenharmony_ci  void vpextrd(Register dst, XMMRegister src, uint8_t offset) {
12281cb0ef41Sopenharmony_ci    vpextrd(Operand(dst), src, offset);
12291cb0ef41Sopenharmony_ci  }
12301cb0ef41Sopenharmony_ci  void vpextrd(Operand dst, XMMRegister src, uint8_t offset);
12311cb0ef41Sopenharmony_ci
12321cb0ef41Sopenharmony_ci  void vinsertps(XMMRegister dst, XMMRegister src1, XMMRegister src2,
12331cb0ef41Sopenharmony_ci                 uint8_t offset) {
12341cb0ef41Sopenharmony_ci    vinsertps(dst, src1, Operand(src2), offset);
12351cb0ef41Sopenharmony_ci  }
12361cb0ef41Sopenharmony_ci  void vinsertps(XMMRegister dst, XMMRegister src1, Operand src2,
12371cb0ef41Sopenharmony_ci                 uint8_t offset);
12381cb0ef41Sopenharmony_ci  void vpinsrb(XMMRegister dst, XMMRegister src1, Register src2,
12391cb0ef41Sopenharmony_ci               uint8_t offset) {
12401cb0ef41Sopenharmony_ci    vpinsrb(dst, src1, Operand(src2), offset);
12411cb0ef41Sopenharmony_ci  }
12421cb0ef41Sopenharmony_ci  void vpinsrb(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t offset);
12431cb0ef41Sopenharmony_ci  void vpinsrw(XMMRegister dst, XMMRegister src1, Register src2,
12441cb0ef41Sopenharmony_ci               uint8_t offset) {
12451cb0ef41Sopenharmony_ci    vpinsrw(dst, src1, Operand(src2), offset);
12461cb0ef41Sopenharmony_ci  }
12471cb0ef41Sopenharmony_ci  void vpinsrw(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t offset);
12481cb0ef41Sopenharmony_ci  void vpinsrd(XMMRegister dst, XMMRegister src1, Register src2,
12491cb0ef41Sopenharmony_ci               uint8_t offset) {
12501cb0ef41Sopenharmony_ci    vpinsrd(dst, src1, Operand(src2), offset);
12511cb0ef41Sopenharmony_ci  }
12521cb0ef41Sopenharmony_ci  void vpinsrd(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t offset);
12531cb0ef41Sopenharmony_ci
12541cb0ef41Sopenharmony_ci  void vroundsd(XMMRegister dst, XMMRegister src1, XMMRegister src2,
12551cb0ef41Sopenharmony_ci                RoundingMode mode);
12561cb0ef41Sopenharmony_ci  void vroundss(XMMRegister dst, XMMRegister src1, XMMRegister src2,
12571cb0ef41Sopenharmony_ci                RoundingMode mode);
12581cb0ef41Sopenharmony_ci  void vroundps(XMMRegister dst, XMMRegister src, RoundingMode mode);
12591cb0ef41Sopenharmony_ci  void vroundpd(XMMRegister dst, XMMRegister src, RoundingMode mode);
12601cb0ef41Sopenharmony_ci
12611cb0ef41Sopenharmony_ci  void vcvtdq2pd(XMMRegister dst, XMMRegister src) {
12621cb0ef41Sopenharmony_ci    vinstr(0xE6, dst, xmm0, src, kF3, k0F, kWIG);
12631cb0ef41Sopenharmony_ci  }
12641cb0ef41Sopenharmony_ci  void vcvtpd2ps(XMMRegister dst, XMMRegister src) {
12651cb0ef41Sopenharmony_ci    vinstr(0x5A, dst, xmm0, src, k66, k0F, kWIG);
12661cb0ef41Sopenharmony_ci  }
12671cb0ef41Sopenharmony_ci  void vcvttps2dq(XMMRegister dst, XMMRegister src) {
12681cb0ef41Sopenharmony_ci    vcvttps2dq(dst, Operand(src));
12691cb0ef41Sopenharmony_ci  }
12701cb0ef41Sopenharmony_ci  void vcvttps2dq(XMMRegister dst, Operand src) {
12711cb0ef41Sopenharmony_ci    vinstr(0x5B, dst, xmm0, src, kF3, k0F, kWIG);
12721cb0ef41Sopenharmony_ci  }
12731cb0ef41Sopenharmony_ci  void vcvttpd2dq(XMMRegister dst, XMMRegister src) {
12741cb0ef41Sopenharmony_ci    vinstr(0xE6, dst, xmm0, src, k66, k0F, kWIG);
12751cb0ef41Sopenharmony_ci  }
12761cb0ef41Sopenharmony_ci  void vcvttsd2si(Register dst, XMMRegister src) {
12771cb0ef41Sopenharmony_ci    XMMRegister idst = XMMRegister::from_code(dst.code());
12781cb0ef41Sopenharmony_ci    vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW0);
12791cb0ef41Sopenharmony_ci  }
12801cb0ef41Sopenharmony_ci  void vcvttsd2si(Register dst, Operand src) {
12811cb0ef41Sopenharmony_ci    XMMRegister idst = XMMRegister::from_code(dst.code());
12821cb0ef41Sopenharmony_ci    vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW0);
12831cb0ef41Sopenharmony_ci  }
12841cb0ef41Sopenharmony_ci  void vcvtss2sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
12851cb0ef41Sopenharmony_ci    vinstr(0x5a, dst, src1, src2, kF3, k0F, kWIG);
12861cb0ef41Sopenharmony_ci  }
12871cb0ef41Sopenharmony_ci  void vcvtss2sd(XMMRegister dst, XMMRegister src1, Operand src2) {
12881cb0ef41Sopenharmony_ci    vinstr(0x5a, dst, src1, src2, kF3, k0F, kWIG);
12891cb0ef41Sopenharmony_ci  }
12901cb0ef41Sopenharmony_ci  void vcvttss2si(Register dst, XMMRegister src) {
12911cb0ef41Sopenharmony_ci    XMMRegister idst = XMMRegister::from_code(dst.code());
12921cb0ef41Sopenharmony_ci    vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW0);
12931cb0ef41Sopenharmony_ci  }
12941cb0ef41Sopenharmony_ci  void vcvttss2si(Register dst, Operand src) {
12951cb0ef41Sopenharmony_ci    XMMRegister idst = XMMRegister::from_code(dst.code());
12961cb0ef41Sopenharmony_ci    vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW0);
12971cb0ef41Sopenharmony_ci  }
12981cb0ef41Sopenharmony_ci
12991cb0ef41Sopenharmony_ci  void vmovddup(XMMRegister dst, Operand src) {
13001cb0ef41Sopenharmony_ci    vinstr(0x12, dst, xmm0, src, kF2, k0F, kWIG);
13011cb0ef41Sopenharmony_ci  }
13021cb0ef41Sopenharmony_ci  void vmovddup(XMMRegister dst, XMMRegister src) {
13031cb0ef41Sopenharmony_ci    vmovddup(dst, Operand(src));
13041cb0ef41Sopenharmony_ci  }
13051cb0ef41Sopenharmony_ci  void vmovshdup(XMMRegister dst, XMMRegister src) {
13061cb0ef41Sopenharmony_ci    vinstr(0x16, dst, xmm0, src, kF3, k0F, kWIG);
13071cb0ef41Sopenharmony_ci  }
13081cb0ef41Sopenharmony_ci  void vbroadcastss(XMMRegister dst, XMMRegister src) {
13091cb0ef41Sopenharmony_ci    vinstr(0x18, dst, xmm0, src, k66, k0F38, kW0, AVX2);
13101cb0ef41Sopenharmony_ci  }
13111cb0ef41Sopenharmony_ci  void vbroadcastss(XMMRegister dst, Operand src) {
13121cb0ef41Sopenharmony_ci    vinstr(0x18, dst, xmm0, src, k66, k0F38, kW0);
13131cb0ef41Sopenharmony_ci  }
13141cb0ef41Sopenharmony_ci  void vmovdqa(XMMRegister dst, Operand src) {
13151cb0ef41Sopenharmony_ci    vinstr(0x6F, dst, xmm0, src, k66, k0F, kWIG);
13161cb0ef41Sopenharmony_ci  }
13171cb0ef41Sopenharmony_ci  void vmovdqa(XMMRegister dst, XMMRegister src) {
13181cb0ef41Sopenharmony_ci    vinstr(0x6F, dst, xmm0, src, k66, k0F, kWIG);
13191cb0ef41Sopenharmony_ci  }
13201cb0ef41Sopenharmony_ci  void vmovdqu(XMMRegister dst, Operand src) {
13211cb0ef41Sopenharmony_ci    vinstr(0x6F, dst, xmm0, src, kF3, k0F, kWIG);
13221cb0ef41Sopenharmony_ci  }
13231cb0ef41Sopenharmony_ci  void vmovdqu(Operand dst, XMMRegister src) {
13241cb0ef41Sopenharmony_ci    vinstr(0x7F, src, xmm0, dst, kF3, k0F, kWIG);
13251cb0ef41Sopenharmony_ci  }
13261cb0ef41Sopenharmony_ci  void vmovd(XMMRegister dst, Register src) { vmovd(dst, Operand(src)); }
13271cb0ef41Sopenharmony_ci  void vmovd(XMMRegister dst, Operand src) {
13281cb0ef41Sopenharmony_ci    vinstr(0x6E, dst, xmm0, src, k66, k0F, kWIG);
13291cb0ef41Sopenharmony_ci  }
13301cb0ef41Sopenharmony_ci  void vmovd(Register dst, XMMRegister src) { movd(Operand(dst), src); }
13311cb0ef41Sopenharmony_ci  void vmovd(Operand dst, XMMRegister src) {
13321cb0ef41Sopenharmony_ci    vinstr(0x7E, src, xmm0, dst, k66, k0F, kWIG);
13331cb0ef41Sopenharmony_ci  }
13341cb0ef41Sopenharmony_ci
13351cb0ef41Sopenharmony_ci  void vmovmskpd(Register dst, XMMRegister src);
13361cb0ef41Sopenharmony_ci  void vmovmskps(Register dst, XMMRegister src);
13371cb0ef41Sopenharmony_ci
13381cb0ef41Sopenharmony_ci  void vpmovmskb(Register dst, XMMRegister src);
13391cb0ef41Sopenharmony_ci
13401cb0ef41Sopenharmony_ci  void vucomisd(XMMRegister dst, XMMRegister src) {
13411cb0ef41Sopenharmony_ci    vinstr(0x2E, dst, xmm0, src, k66, k0F, kWIG);
13421cb0ef41Sopenharmony_ci  }
13431cb0ef41Sopenharmony_ci  void vucomisd(XMMRegister dst, Operand src) {
13441cb0ef41Sopenharmony_ci    vinstr(0x2E, dst, xmm0, src, k66, k0F, kWIG);
13451cb0ef41Sopenharmony_ci  }
13461cb0ef41Sopenharmony_ci  void vucomiss(XMMRegister dst, XMMRegister src) {
13471cb0ef41Sopenharmony_ci    vinstr(0x2E, dst, xmm0, src, kNoPrefix, k0F, kWIG);
13481cb0ef41Sopenharmony_ci  }
13491cb0ef41Sopenharmony_ci  void vucomiss(XMMRegister dst, Operand src) {
13501cb0ef41Sopenharmony_ci    vinstr(0x2E, dst, xmm0, src, kNoPrefix, k0F, kWIG);
13511cb0ef41Sopenharmony_ci  }
13521cb0ef41Sopenharmony_ci
13531cb0ef41Sopenharmony_ci  // BMI instruction
13541cb0ef41Sopenharmony_ci  void andn(Register dst, Register src1, Register src2) {
13551cb0ef41Sopenharmony_ci    andn(dst, src1, Operand(src2));
13561cb0ef41Sopenharmony_ci  }
13571cb0ef41Sopenharmony_ci  void andn(Register dst, Register src1, Operand src2) {
13581cb0ef41Sopenharmony_ci    bmi1(0xf2, dst, src1, src2);
13591cb0ef41Sopenharmony_ci  }
13601cb0ef41Sopenharmony_ci  void bextr(Register dst, Register src1, Register src2) {
13611cb0ef41Sopenharmony_ci    bextr(dst, Operand(src1), src2);
13621cb0ef41Sopenharmony_ci  }
13631cb0ef41Sopenharmony_ci  void bextr(Register dst, Operand src1, Register src2) {
13641cb0ef41Sopenharmony_ci    bmi1(0xf7, dst, src2, src1);
13651cb0ef41Sopenharmony_ci  }
13661cb0ef41Sopenharmony_ci  void blsi(Register dst, Register src) { blsi(dst, Operand(src)); }
13671cb0ef41Sopenharmony_ci  void blsi(Register dst, Operand src) { bmi1(0xf3, ebx, dst, src); }
13681cb0ef41Sopenharmony_ci  void blsmsk(Register dst, Register src) { blsmsk(dst, Operand(src)); }
13691cb0ef41Sopenharmony_ci  void blsmsk(Register dst, Operand src) { bmi1(0xf3, edx, dst, src); }
13701cb0ef41Sopenharmony_ci  void blsr(Register dst, Register src) { blsr(dst, Operand(src)); }
13711cb0ef41Sopenharmony_ci  void blsr(Register dst, Operand src) { bmi1(0xf3, ecx, dst, src); }
13721cb0ef41Sopenharmony_ci  void tzcnt(Register dst, Register src) { tzcnt(dst, Operand(src)); }
13731cb0ef41Sopenharmony_ci  void tzcnt(Register dst, Operand src);
13741cb0ef41Sopenharmony_ci
13751cb0ef41Sopenharmony_ci  void lzcnt(Register dst, Register src) { lzcnt(dst, Operand(src)); }
13761cb0ef41Sopenharmony_ci  void lzcnt(Register dst, Operand src);
13771cb0ef41Sopenharmony_ci
13781cb0ef41Sopenharmony_ci  void popcnt(Register dst, Register src) { popcnt(dst, Operand(src)); }
13791cb0ef41Sopenharmony_ci  void popcnt(Register dst, Operand src);
13801cb0ef41Sopenharmony_ci
13811cb0ef41Sopenharmony_ci  void bzhi(Register dst, Register src1, Register src2) {
13821cb0ef41Sopenharmony_ci    bzhi(dst, Operand(src1), src2);
13831cb0ef41Sopenharmony_ci  }
13841cb0ef41Sopenharmony_ci  void bzhi(Register dst, Operand src1, Register src2) {
13851cb0ef41Sopenharmony_ci    bmi2(kNoPrefix, 0xf5, dst, src2, src1);
13861cb0ef41Sopenharmony_ci  }
13871cb0ef41Sopenharmony_ci  void mulx(Register dst1, Register dst2, Register src) {
13881cb0ef41Sopenharmony_ci    mulx(dst1, dst2, Operand(src));
13891cb0ef41Sopenharmony_ci  }
13901cb0ef41Sopenharmony_ci  void mulx(Register dst1, Register dst2, Operand src) {
13911cb0ef41Sopenharmony_ci    bmi2(kF2, 0xf6, dst1, dst2, src);
13921cb0ef41Sopenharmony_ci  }
13931cb0ef41Sopenharmony_ci  void pdep(Register dst, Register src1, Register src2) {
13941cb0ef41Sopenharmony_ci    pdep(dst, src1, Operand(src2));
13951cb0ef41Sopenharmony_ci  }
13961cb0ef41Sopenharmony_ci  void pdep(Register dst, Register src1, Operand src2) {
13971cb0ef41Sopenharmony_ci    bmi2(kF2, 0xf5, dst, src1, src2);
13981cb0ef41Sopenharmony_ci  }
13991cb0ef41Sopenharmony_ci  void pext(Register dst, Register src1, Register src2) {
14001cb0ef41Sopenharmony_ci    pext(dst, src1, Operand(src2));
14011cb0ef41Sopenharmony_ci  }
14021cb0ef41Sopenharmony_ci  void pext(Register dst, Register src1, Operand src2) {
14031cb0ef41Sopenharmony_ci    bmi2(kF3, 0xf5, dst, src1, src2);
14041cb0ef41Sopenharmony_ci  }
14051cb0ef41Sopenharmony_ci  void sarx(Register dst, Register src1, Register src2) {
14061cb0ef41Sopenharmony_ci    sarx(dst, Operand(src1), src2);
14071cb0ef41Sopenharmony_ci  }
14081cb0ef41Sopenharmony_ci  void sarx(Register dst, Operand src1, Register src2) {
14091cb0ef41Sopenharmony_ci    bmi2(kF3, 0xf7, dst, src2, src1);
14101cb0ef41Sopenharmony_ci  }
14111cb0ef41Sopenharmony_ci  void shlx(Register dst, Register src1, Register src2) {
14121cb0ef41Sopenharmony_ci    shlx(dst, Operand(src1), src2);
14131cb0ef41Sopenharmony_ci  }
14141cb0ef41Sopenharmony_ci  void shlx(Register dst, Operand src1, Register src2) {
14151cb0ef41Sopenharmony_ci    bmi2(k66, 0xf7, dst, src2, src1);
14161cb0ef41Sopenharmony_ci  }
14171cb0ef41Sopenharmony_ci  void shrx(Register dst, Register src1, Register src2) {
14181cb0ef41Sopenharmony_ci    shrx(dst, Operand(src1), src2);
14191cb0ef41Sopenharmony_ci  }
14201cb0ef41Sopenharmony_ci  void shrx(Register dst, Operand src1, Register src2) {
14211cb0ef41Sopenharmony_ci    bmi2(kF2, 0xf7, dst, src2, src1);
14221cb0ef41Sopenharmony_ci  }
14231cb0ef41Sopenharmony_ci  void rorx(Register dst, Register src, byte imm8) {
14241cb0ef41Sopenharmony_ci    rorx(dst, Operand(src), imm8);
14251cb0ef41Sopenharmony_ci  }
14261cb0ef41Sopenharmony_ci  void rorx(Register dst, Operand src, byte imm8);
14271cb0ef41Sopenharmony_ci
14281cb0ef41Sopenharmony_ci  // Implementation of packed single-precision floating-point SSE instructions.
14291cb0ef41Sopenharmony_ci  void ps(byte op, XMMRegister dst, Operand src);
14301cb0ef41Sopenharmony_ci  // Implementation of packed double-precision floating-point SSE instructions.
14311cb0ef41Sopenharmony_ci  void pd(byte op, XMMRegister dst, Operand src);
14321cb0ef41Sopenharmony_ci
14331cb0ef41Sopenharmony_ci#define PACKED_OP_LIST(V) \
14341cb0ef41Sopenharmony_ci  V(unpckl, 0x14)         \
14351cb0ef41Sopenharmony_ci  V(and, 0x54)            \
14361cb0ef41Sopenharmony_ci  V(andn, 0x55)           \
14371cb0ef41Sopenharmony_ci  V(or, 0x56)             \
14381cb0ef41Sopenharmony_ci  V(xor, 0x57)            \
14391cb0ef41Sopenharmony_ci  V(add, 0x58)            \
14401cb0ef41Sopenharmony_ci  V(mul, 0x59)            \
14411cb0ef41Sopenharmony_ci  V(sub, 0x5c)            \
14421cb0ef41Sopenharmony_ci  V(min, 0x5d)            \
14431cb0ef41Sopenharmony_ci  V(div, 0x5e)            \
14441cb0ef41Sopenharmony_ci  V(max, 0x5f)
14451cb0ef41Sopenharmony_ci
14461cb0ef41Sopenharmony_ci#define SSE_PACKED_OP_DECLARE(name, opcode)                             \
14471cb0ef41Sopenharmony_ci  void name##ps(XMMRegister dst, XMMRegister src) {                     \
14481cb0ef41Sopenharmony_ci    ps(opcode, dst, Operand(src));                                      \
14491cb0ef41Sopenharmony_ci  }                                                                     \
14501cb0ef41Sopenharmony_ci  void name##ps(XMMRegister dst, Operand src) { ps(opcode, dst, src); } \
14511cb0ef41Sopenharmony_ci  void name##pd(XMMRegister dst, XMMRegister src) {                     \
14521cb0ef41Sopenharmony_ci    pd(opcode, dst, Operand(src));                                      \
14531cb0ef41Sopenharmony_ci  }                                                                     \
14541cb0ef41Sopenharmony_ci  void name##pd(XMMRegister dst, Operand src) { pd(opcode, dst, src); }
14551cb0ef41Sopenharmony_ci
14561cb0ef41Sopenharmony_ci  PACKED_OP_LIST(SSE_PACKED_OP_DECLARE)
14571cb0ef41Sopenharmony_ci#undef SSE_PACKED_OP_DECLARE
14581cb0ef41Sopenharmony_ci
14591cb0ef41Sopenharmony_ci#define AVX_PACKED_OP_DECLARE(name, opcode)                               \
14601cb0ef41Sopenharmony_ci  void v##name##ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
14611cb0ef41Sopenharmony_ci    vps(opcode, dst, src1, Operand(src2));                                \
14621cb0ef41Sopenharmony_ci  }                                                                       \
14631cb0ef41Sopenharmony_ci  void v##name##ps(XMMRegister dst, XMMRegister src1, Operand src2) {     \
14641cb0ef41Sopenharmony_ci    vps(opcode, dst, src1, src2);                                         \
14651cb0ef41Sopenharmony_ci  }                                                                       \
14661cb0ef41Sopenharmony_ci  void v##name##pd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
14671cb0ef41Sopenharmony_ci    vpd(opcode, dst, src1, Operand(src2));                                \
14681cb0ef41Sopenharmony_ci  }                                                                       \
14691cb0ef41Sopenharmony_ci  void v##name##pd(XMMRegister dst, XMMRegister src1, Operand src2) {     \
14701cb0ef41Sopenharmony_ci    vpd(opcode, dst, src1, src2);                                         \
14711cb0ef41Sopenharmony_ci  }
14721cb0ef41Sopenharmony_ci
14731cb0ef41Sopenharmony_ci  PACKED_OP_LIST(AVX_PACKED_OP_DECLARE)
14741cb0ef41Sopenharmony_ci#undef AVX_PACKED_OP_DECLARE
14751cb0ef41Sopenharmony_ci#undef PACKED_OP_LIST
14761cb0ef41Sopenharmony_ci
14771cb0ef41Sopenharmony_ci  void vps(byte op, XMMRegister dst, XMMRegister src1, Operand src2);
14781cb0ef41Sopenharmony_ci  void vpd(byte op, XMMRegister dst, XMMRegister src1, Operand src2);
14791cb0ef41Sopenharmony_ci
14801cb0ef41Sopenharmony_ci  void vcmpps(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t cmp);
14811cb0ef41Sopenharmony_ci  void vcmppd(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t cmp);
14821cb0ef41Sopenharmony_ci
14831cb0ef41Sopenharmony_ci#define AVX_CMP_P(instr, imm8)                                             \
14841cb0ef41Sopenharmony_ci  void v##instr##ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
14851cb0ef41Sopenharmony_ci    vcmpps(dst, src1, Operand(src2), imm8);                                \
14861cb0ef41Sopenharmony_ci  }                                                                        \
14871cb0ef41Sopenharmony_ci  void v##instr##ps(XMMRegister dst, XMMRegister src1, Operand src2) {     \
14881cb0ef41Sopenharmony_ci    vcmpps(dst, src1, src2, imm8);                                         \
14891cb0ef41Sopenharmony_ci  }                                                                        \
14901cb0ef41Sopenharmony_ci  void v##instr##pd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
14911cb0ef41Sopenharmony_ci    vcmppd(dst, src1, Operand(src2), imm8);                                \
14921cb0ef41Sopenharmony_ci  }                                                                        \
14931cb0ef41Sopenharmony_ci  void v##instr##pd(XMMRegister dst, XMMRegister src1, Operand src2) {     \
14941cb0ef41Sopenharmony_ci    vcmppd(dst, src1, src2, imm8);                                         \
14951cb0ef41Sopenharmony_ci  }
14961cb0ef41Sopenharmony_ci
14971cb0ef41Sopenharmony_ci  PACKED_CMP_LIST(AVX_CMP_P)
14981cb0ef41Sopenharmony_ci  // vcmpgeps/vcmpgepd only in AVX.
14991cb0ef41Sopenharmony_ci  AVX_CMP_P(cmpge, 0xd)
15001cb0ef41Sopenharmony_ci#undef AVX_CMP_P
15011cb0ef41Sopenharmony_ci#undef PACKED_CMP_LIST
15021cb0ef41Sopenharmony_ci
15031cb0ef41Sopenharmony_ci// Other SSE and AVX instructions
15041cb0ef41Sopenharmony_ci#define DECLARE_SSE_UNOP_AND_AVX(instruction, escape, opcode)       \
15051cb0ef41Sopenharmony_ci  void instruction(XMMRegister dst, XMMRegister src) {              \
15061cb0ef41Sopenharmony_ci    instruction(dst, Operand(src));                                 \
15071cb0ef41Sopenharmony_ci  }                                                                 \
15081cb0ef41Sopenharmony_ci  void instruction(XMMRegister dst, Operand src) {                  \
15091cb0ef41Sopenharmony_ci    sse_instr(dst, src, 0x##escape, 0x##opcode);                    \
15101cb0ef41Sopenharmony_ci  }                                                                 \
15111cb0ef41Sopenharmony_ci  void v##instruction(XMMRegister dst, XMMRegister src) {           \
15121cb0ef41Sopenharmony_ci    v##instruction(dst, Operand(src));                              \
15131cb0ef41Sopenharmony_ci  }                                                                 \
15141cb0ef41Sopenharmony_ci  void v##instruction(XMMRegister dst, Operand src) {               \
15151cb0ef41Sopenharmony_ci    vinstr(0x##opcode, dst, xmm0, src, kNoPrefix, k##escape, kWIG); \
15161cb0ef41Sopenharmony_ci  }
15171cb0ef41Sopenharmony_ci
15181cb0ef41Sopenharmony_ci  SSE_UNOP_INSTRUCTION_LIST(DECLARE_SSE_UNOP_AND_AVX)
15191cb0ef41Sopenharmony_ci#undef DECLARE_SSE_UNOP_AND_AVX
15201cb0ef41Sopenharmony_ci
15211cb0ef41Sopenharmony_ci#define DECLARE_SSE2_INSTRUCTION(instruction, prefix, escape, opcode) \
15221cb0ef41Sopenharmony_ci  void instruction(XMMRegister dst, XMMRegister src) {                \
15231cb0ef41Sopenharmony_ci    instruction(dst, Operand(src));                                   \
15241cb0ef41Sopenharmony_ci  }                                                                   \
15251cb0ef41Sopenharmony_ci  void instruction(XMMRegister dst, Operand src) {                    \
15261cb0ef41Sopenharmony_ci    sse2_instr(dst, src, 0x##prefix, 0x##escape, 0x##opcode);         \
15271cb0ef41Sopenharmony_ci  }
15281cb0ef41Sopenharmony_ci
15291cb0ef41Sopenharmony_ci  SSE2_INSTRUCTION_LIST(DECLARE_SSE2_INSTRUCTION)
15301cb0ef41Sopenharmony_ci  SSE2_INSTRUCTION_LIST_SD(DECLARE_SSE2_INSTRUCTION)
15311cb0ef41Sopenharmony_ci#undef DECLARE_SSE2_INSTRUCTION
15321cb0ef41Sopenharmony_ci
15331cb0ef41Sopenharmony_ci#define DECLARE_SSE2_AVX_INSTRUCTION(instruction, prefix, escape, opcode)    \
15341cb0ef41Sopenharmony_ci  void v##instruction(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
15351cb0ef41Sopenharmony_ci    v##instruction(dst, src1, Operand(src2));                                \
15361cb0ef41Sopenharmony_ci  }                                                                          \
15371cb0ef41Sopenharmony_ci  void v##instruction(XMMRegister dst, XMMRegister src1, Operand src2) {     \
15381cb0ef41Sopenharmony_ci    vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0);          \
15391cb0ef41Sopenharmony_ci  }
15401cb0ef41Sopenharmony_ci
15411cb0ef41Sopenharmony_ci  SSE2_INSTRUCTION_LIST(DECLARE_SSE2_AVX_INSTRUCTION)
15421cb0ef41Sopenharmony_ci  SSE2_INSTRUCTION_LIST_SD(DECLARE_SSE2_AVX_INSTRUCTION)
15431cb0ef41Sopenharmony_ci#undef DECLARE_SSE2_AVX_INSTRUCTION
15441cb0ef41Sopenharmony_ci
15451cb0ef41Sopenharmony_ci#define DECLARE_SSSE3_INSTRUCTION(instruction, prefix, escape1, escape2,     \
15461cb0ef41Sopenharmony_ci                                  opcode)                                    \
15471cb0ef41Sopenharmony_ci  void instruction(XMMRegister dst, XMMRegister src) {                       \
15481cb0ef41Sopenharmony_ci    instruction(dst, Operand(src));                                          \
15491cb0ef41Sopenharmony_ci  }                                                                          \
15501cb0ef41Sopenharmony_ci  void instruction(XMMRegister dst, Operand src) {                           \
15511cb0ef41Sopenharmony_ci    ssse3_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
15521cb0ef41Sopenharmony_ci  }
15531cb0ef41Sopenharmony_ci
15541cb0ef41Sopenharmony_ci  SSSE3_INSTRUCTION_LIST(DECLARE_SSSE3_INSTRUCTION)
15551cb0ef41Sopenharmony_ci  SSSE3_UNOP_INSTRUCTION_LIST(DECLARE_SSSE3_INSTRUCTION)
15561cb0ef41Sopenharmony_ci#undef DECLARE_SSSE3_INSTRUCTION
15571cb0ef41Sopenharmony_ci
15581cb0ef41Sopenharmony_ci#define DECLARE_SSE4_INSTRUCTION(instruction, prefix, escape1, escape2,     \
15591cb0ef41Sopenharmony_ci                                 opcode)                                    \
15601cb0ef41Sopenharmony_ci  void instruction(XMMRegister dst, XMMRegister src) {                      \
15611cb0ef41Sopenharmony_ci    instruction(dst, Operand(src));                                         \
15621cb0ef41Sopenharmony_ci  }                                                                         \
15631cb0ef41Sopenharmony_ci  void instruction(XMMRegister dst, Operand src) {                          \
15641cb0ef41Sopenharmony_ci    sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
15651cb0ef41Sopenharmony_ci  }
15661cb0ef41Sopenharmony_ci
15671cb0ef41Sopenharmony_ci  SSE4_INSTRUCTION_LIST(DECLARE_SSE4_INSTRUCTION)
15681cb0ef41Sopenharmony_ci  SSE4_RM_INSTRUCTION_LIST(DECLARE_SSE4_INSTRUCTION)
15691cb0ef41Sopenharmony_ci  DECLARE_SSE4_INSTRUCTION(blendvps, 66, 0F, 38, 14)
15701cb0ef41Sopenharmony_ci  DECLARE_SSE4_INSTRUCTION(blendvpd, 66, 0F, 38, 15)
15711cb0ef41Sopenharmony_ci  DECLARE_SSE4_INSTRUCTION(pblendvb, 66, 0F, 38, 10)
15721cb0ef41Sopenharmony_ci#undef DECLARE_SSE4_INSTRUCTION
15731cb0ef41Sopenharmony_ci
15741cb0ef41Sopenharmony_ci#define DECLARE_SSE34_AVX_INSTRUCTION(instruction, prefix, escape1, escape2,  \
15751cb0ef41Sopenharmony_ci                                      opcode)                                 \
15761cb0ef41Sopenharmony_ci  void v##instruction(XMMRegister dst, XMMRegister src1, XMMRegister src2) {  \
15771cb0ef41Sopenharmony_ci    v##instruction(dst, src1, Operand(src2));                                 \
15781cb0ef41Sopenharmony_ci  }                                                                           \
15791cb0ef41Sopenharmony_ci  void v##instruction(XMMRegister dst, XMMRegister src1, Operand src2) {      \
15801cb0ef41Sopenharmony_ci    vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0); \
15811cb0ef41Sopenharmony_ci  }
15821cb0ef41Sopenharmony_ci
15831cb0ef41Sopenharmony_ci  SSSE3_INSTRUCTION_LIST(DECLARE_SSE34_AVX_INSTRUCTION)
15841cb0ef41Sopenharmony_ci  SSE4_INSTRUCTION_LIST(DECLARE_SSE34_AVX_INSTRUCTION)
15851cb0ef41Sopenharmony_ci#undef DECLARE_SSE34_AVX_INSTRUCTION
15861cb0ef41Sopenharmony_ci
15871cb0ef41Sopenharmony_ci#define DECLARE_SSE4_AVX_RM_INSTRUCTION(instruction, prefix, escape1, escape2, \
15881cb0ef41Sopenharmony_ci                                        opcode)                                \
15891cb0ef41Sopenharmony_ci  void v##instruction(XMMRegister dst, XMMRegister src) {                      \
15901cb0ef41Sopenharmony_ci    v##instruction(dst, Operand(src));                                         \
15911cb0ef41Sopenharmony_ci  }                                                                            \
15921cb0ef41Sopenharmony_ci  void v##instruction(XMMRegister dst, Operand src) {                          \
15931cb0ef41Sopenharmony_ci    vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0);   \
15941cb0ef41Sopenharmony_ci  }
15951cb0ef41Sopenharmony_ci
15961cb0ef41Sopenharmony_ci  SSSE3_UNOP_INSTRUCTION_LIST(DECLARE_SSE4_AVX_RM_INSTRUCTION)
15971cb0ef41Sopenharmony_ci  SSE4_RM_INSTRUCTION_LIST(DECLARE_SSE4_AVX_RM_INSTRUCTION)
15981cb0ef41Sopenharmony_ci#undef DECLARE_SSE4_AVX_RM_INSTRUCTION
15991cb0ef41Sopenharmony_ci
16001cb0ef41Sopenharmony_ci  // AVX2 instructions
16011cb0ef41Sopenharmony_ci#define AVX2_INSTRUCTION(instr, prefix, escape1, escape2, opcode)           \
16021cb0ef41Sopenharmony_ci  void instr(XMMRegister dst, XMMRegister src) {                            \
16031cb0ef41Sopenharmony_ci    vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0, \
16041cb0ef41Sopenharmony_ci           AVX2);                                                           \
16051cb0ef41Sopenharmony_ci  }                                                                         \
16061cb0ef41Sopenharmony_ci  void instr(XMMRegister dst, Operand src) {                                \
16071cb0ef41Sopenharmony_ci    vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0, \
16081cb0ef41Sopenharmony_ci           AVX2);                                                           \
16091cb0ef41Sopenharmony_ci  }
16101cb0ef41Sopenharmony_ci  AVX2_BROADCAST_LIST(AVX2_INSTRUCTION)
16111cb0ef41Sopenharmony_ci#undef AVX2_INSTRUCTION
16121cb0ef41Sopenharmony_ci
16131cb0ef41Sopenharmony_ci#define FMA(instr, length, prefix, escape1, escape2, extension, opcode) \
16141cb0ef41Sopenharmony_ci  void instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) {     \
16151cb0ef41Sopenharmony_ci    vinstr(0x##opcode, dst, src1, src2, k##length, k##prefix,           \
16161cb0ef41Sopenharmony_ci           k##escape1##escape2, k##extension, FMA3);                    \
16171cb0ef41Sopenharmony_ci  }                                                                     \
16181cb0ef41Sopenharmony_ci  void instr(XMMRegister dst, XMMRegister src1, Operand src2) {         \
16191cb0ef41Sopenharmony_ci    vinstr(0x##opcode, dst, src1, src2, k##length, k##prefix,           \
16201cb0ef41Sopenharmony_ci           k##escape1##escape2, k##extension, FMA3);                    \
16211cb0ef41Sopenharmony_ci  }
16221cb0ef41Sopenharmony_ci  FMA_INSTRUCTION_LIST(FMA)
16231cb0ef41Sopenharmony_ci#undef FMA
16241cb0ef41Sopenharmony_ci
16251cb0ef41Sopenharmony_ci  // Prefetch src position into cache level.
16261cb0ef41Sopenharmony_ci  // Level 1, 2 or 3 specifies CPU cache level. Level 0 specifies a
16271cb0ef41Sopenharmony_ci  // non-temporal
16281cb0ef41Sopenharmony_ci  void prefetch(Operand src, int level);
16291cb0ef41Sopenharmony_ci  // TODO(lrn): Need SFENCE for movnt?
16301cb0ef41Sopenharmony_ci
16311cb0ef41Sopenharmony_ci  // Check the code size generated from label to here.
16321cb0ef41Sopenharmony_ci  int SizeOfCodeGeneratedSince(Label* label) {
16331cb0ef41Sopenharmony_ci    return pc_offset() - label->pos();
16341cb0ef41Sopenharmony_ci  }
16351cb0ef41Sopenharmony_ci
16361cb0ef41Sopenharmony_ci  // Record a deoptimization reason that can be used by a log or cpu profiler.
16371cb0ef41Sopenharmony_ci  // Use --trace-deopt to enable.
16381cb0ef41Sopenharmony_ci  void RecordDeoptReason(DeoptimizeReason reason, uint32_t node_id,
16391cb0ef41Sopenharmony_ci                         SourcePosition position, int id);
16401cb0ef41Sopenharmony_ci
16411cb0ef41Sopenharmony_ci  // Writes a single byte or word of data in the code stream.  Used for
16421cb0ef41Sopenharmony_ci  // inline tables, e.g., jump-tables.
16431cb0ef41Sopenharmony_ci  void db(uint8_t data);
16441cb0ef41Sopenharmony_ci  void dd(uint32_t data, RelocInfo::Mode rmode = RelocInfo::NO_INFO);
16451cb0ef41Sopenharmony_ci  void dq(uint64_t data, RelocInfo::Mode rmode = RelocInfo::NO_INFO);
16461cb0ef41Sopenharmony_ci  void dp(uintptr_t data, RelocInfo::Mode rmode = RelocInfo::NO_INFO) {
16471cb0ef41Sopenharmony_ci    dd(data, rmode);
16481cb0ef41Sopenharmony_ci  }
16491cb0ef41Sopenharmony_ci  void dd(Label* label);
16501cb0ef41Sopenharmony_ci
16511cb0ef41Sopenharmony_ci  // Check if there is less than kGap bytes available in the buffer.
16521cb0ef41Sopenharmony_ci  // If this is the case, we need to grow the buffer before emitting
16531cb0ef41Sopenharmony_ci  // an instruction or relocation information.
16541cb0ef41Sopenharmony_ci  inline bool buffer_overflow() const {
16551cb0ef41Sopenharmony_ci    return pc_ >= reloc_info_writer.pos() - kGap;
16561cb0ef41Sopenharmony_ci  }
16571cb0ef41Sopenharmony_ci
16581cb0ef41Sopenharmony_ci  // Get the number of bytes available in the buffer.
16591cb0ef41Sopenharmony_ci  inline int available_space() const { return reloc_info_writer.pos() - pc_; }
16601cb0ef41Sopenharmony_ci
16611cb0ef41Sopenharmony_ci  static bool IsNop(Address addr);
16621cb0ef41Sopenharmony_ci
16631cb0ef41Sopenharmony_ci  int relocation_writer_size() {
16641cb0ef41Sopenharmony_ci    return (buffer_start_ + buffer_->size()) - reloc_info_writer.pos();
16651cb0ef41Sopenharmony_ci  }
16661cb0ef41Sopenharmony_ci
16671cb0ef41Sopenharmony_ci  // Avoid overflows for displacements etc.
16681cb0ef41Sopenharmony_ci  static constexpr int kMaximalBufferSize = 512 * MB;
16691cb0ef41Sopenharmony_ci
16701cb0ef41Sopenharmony_ci  byte byte_at(int pos) { return buffer_start_[pos]; }
16711cb0ef41Sopenharmony_ci  void set_byte_at(int pos, byte value) { buffer_start_[pos] = value; }
16721cb0ef41Sopenharmony_ci
16731cb0ef41Sopenharmony_ci protected:
16741cb0ef41Sopenharmony_ci  void emit_sse_operand(XMMRegister reg, Operand adr);
16751cb0ef41Sopenharmony_ci  void emit_sse_operand(XMMRegister dst, XMMRegister src);
16761cb0ef41Sopenharmony_ci  void emit_sse_operand(Register dst, XMMRegister src);
16771cb0ef41Sopenharmony_ci  void emit_sse_operand(XMMRegister dst, Register src);
16781cb0ef41Sopenharmony_ci
16791cb0ef41Sopenharmony_ci  Address addr_at(int pos) {
16801cb0ef41Sopenharmony_ci    return reinterpret_cast<Address>(buffer_start_ + pos);
16811cb0ef41Sopenharmony_ci  }
16821cb0ef41Sopenharmony_ci
16831cb0ef41Sopenharmony_ci private:
16841cb0ef41Sopenharmony_ci  uint32_t long_at(int pos) {
16851cb0ef41Sopenharmony_ci    return ReadUnalignedValue<uint32_t>(addr_at(pos));
16861cb0ef41Sopenharmony_ci  }
16871cb0ef41Sopenharmony_ci  void long_at_put(int pos, uint32_t x) {
16881cb0ef41Sopenharmony_ci    WriteUnalignedValue(addr_at(pos), x);
16891cb0ef41Sopenharmony_ci  }
16901cb0ef41Sopenharmony_ci
16911cb0ef41Sopenharmony_ci  // code emission
16921cb0ef41Sopenharmony_ci  void GrowBuffer();
16931cb0ef41Sopenharmony_ci  inline void emit(uint32_t x);
16941cb0ef41Sopenharmony_ci  inline void emit(Handle<HeapObject> handle);
16951cb0ef41Sopenharmony_ci  inline void emit(uint32_t x, RelocInfo::Mode rmode);
16961cb0ef41Sopenharmony_ci  inline void emit(Handle<Code> code, RelocInfo::Mode rmode);
16971cb0ef41Sopenharmony_ci  inline void emit(const Immediate& x);
16981cb0ef41Sopenharmony_ci  inline void emit_b(Immediate x);
16991cb0ef41Sopenharmony_ci  inline void emit_w(const Immediate& x);
17001cb0ef41Sopenharmony_ci  inline void emit_q(uint64_t x);
17011cb0ef41Sopenharmony_ci
17021cb0ef41Sopenharmony_ci  // Emit the code-object-relative offset of the label's position
17031cb0ef41Sopenharmony_ci  inline void emit_code_relative_offset(Label* label);
17041cb0ef41Sopenharmony_ci
17051cb0ef41Sopenharmony_ci  // instruction generation
17061cb0ef41Sopenharmony_ci  void emit_arith_b(int op1, int op2, Register dst, int imm8);
17071cb0ef41Sopenharmony_ci
17081cb0ef41Sopenharmony_ci  // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81)
17091cb0ef41Sopenharmony_ci  // with a given destination expression and an immediate operand.  It attempts
17101cb0ef41Sopenharmony_ci  // to use the shortest encoding possible.
17111cb0ef41Sopenharmony_ci  // sel specifies the /n in the modrm byte (see the Intel PRM).
17121cb0ef41Sopenharmony_ci  void emit_arith(int sel, Operand dst, const Immediate& x);
17131cb0ef41Sopenharmony_ci
17141cb0ef41Sopenharmony_ci  void emit_operand(int code, Operand adr);
17151cb0ef41Sopenharmony_ci  void emit_operand(Register reg, Operand adr);
17161cb0ef41Sopenharmony_ci  void emit_operand(XMMRegister reg, Operand adr);
17171cb0ef41Sopenharmony_ci
17181cb0ef41Sopenharmony_ci  void emit_label(Label* label);
17191cb0ef41Sopenharmony_ci
17201cb0ef41Sopenharmony_ci  void emit_farith(int b1, int b2, int i);
17211cb0ef41Sopenharmony_ci
17221cb0ef41Sopenharmony_ci  // Emit vex prefix
17231cb0ef41Sopenharmony_ci  enum SIMDPrefix { kNoPrefix = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 };
17241cb0ef41Sopenharmony_ci  enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128, kLZ = kL128 };
17251cb0ef41Sopenharmony_ci  enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 };
17261cb0ef41Sopenharmony_ci  enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x3 };
17271cb0ef41Sopenharmony_ci  inline void emit_vex_prefix(XMMRegister v, VectorLength l, SIMDPrefix pp,
17281cb0ef41Sopenharmony_ci                              LeadingOpcode m, VexW w);
17291cb0ef41Sopenharmony_ci  inline void emit_vex_prefix(Register v, VectorLength l, SIMDPrefix pp,
17301cb0ef41Sopenharmony_ci                              LeadingOpcode m, VexW w);
17311cb0ef41Sopenharmony_ci
17321cb0ef41Sopenharmony_ci  // labels
17331cb0ef41Sopenharmony_ci  void print(const Label* L);
17341cb0ef41Sopenharmony_ci  void bind_to(Label* L, int pos);
17351cb0ef41Sopenharmony_ci
17361cb0ef41Sopenharmony_ci  // displacements
17371cb0ef41Sopenharmony_ci  inline Displacement disp_at(Label* L);
17381cb0ef41Sopenharmony_ci  inline void disp_at_put(Label* L, Displacement disp);
17391cb0ef41Sopenharmony_ci  inline void emit_disp(Label* L, Displacement::Type type);
17401cb0ef41Sopenharmony_ci  inline void emit_near_disp(Label* L);
17411cb0ef41Sopenharmony_ci
17421cb0ef41Sopenharmony_ci  void sse_instr(XMMRegister dst, Operand src, byte prefix, byte opcode);
17431cb0ef41Sopenharmony_ci  void sse2_instr(XMMRegister dst, Operand src, byte prefix, byte escape,
17441cb0ef41Sopenharmony_ci                  byte opcode);
17451cb0ef41Sopenharmony_ci  void ssse3_instr(XMMRegister dst, Operand src, byte prefix, byte escape1,
17461cb0ef41Sopenharmony_ci                   byte escape2, byte opcode);
17471cb0ef41Sopenharmony_ci  void sse4_instr(XMMRegister dst, Operand src, byte prefix, byte escape1,
17481cb0ef41Sopenharmony_ci                  byte escape2, byte opcode);
17491cb0ef41Sopenharmony_ci  void vinstr(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2,
17501cb0ef41Sopenharmony_ci              SIMDPrefix pp, LeadingOpcode m, VexW w, CpuFeature = AVX);
17511cb0ef41Sopenharmony_ci  void vinstr(byte op, XMMRegister dst, XMMRegister src1, Operand src2,
17521cb0ef41Sopenharmony_ci              SIMDPrefix pp, LeadingOpcode m, VexW w, CpuFeature = AVX);
17531cb0ef41Sopenharmony_ci  void vinstr(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2,
17541cb0ef41Sopenharmony_ci              VectorLength l, SIMDPrefix pp, LeadingOpcode m, VexW w,
17551cb0ef41Sopenharmony_ci              CpuFeature = AVX);
17561cb0ef41Sopenharmony_ci  void vinstr(byte op, XMMRegister dst, XMMRegister src1, Operand src2,
17571cb0ef41Sopenharmony_ci              VectorLength l, SIMDPrefix pp, LeadingOpcode m, VexW w,
17581cb0ef41Sopenharmony_ci              CpuFeature = AVX);
17591cb0ef41Sopenharmony_ci  // Most BMI instructions are similar.
17601cb0ef41Sopenharmony_ci  void bmi1(byte op, Register reg, Register vreg, Operand rm);
17611cb0ef41Sopenharmony_ci  void bmi2(SIMDPrefix pp, byte op, Register reg, Register vreg, Operand rm);
17621cb0ef41Sopenharmony_ci  void fma_instr(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2,
17631cb0ef41Sopenharmony_ci                 VectorLength l, SIMDPrefix pp, LeadingOpcode m, VexW w);
17641cb0ef41Sopenharmony_ci  void fma_instr(byte op, XMMRegister dst, XMMRegister src1, Operand src2,
17651cb0ef41Sopenharmony_ci                 VectorLength l, SIMDPrefix pp, LeadingOpcode m, VexW w);
17661cb0ef41Sopenharmony_ci
17671cb0ef41Sopenharmony_ci  // record reloc info for current pc_
17681cb0ef41Sopenharmony_ci  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
17691cb0ef41Sopenharmony_ci
17701cb0ef41Sopenharmony_ci  // record the position of jmp/jcc instruction
17711cb0ef41Sopenharmony_ci  void record_farjmp_position(Label* L, int pos);
17721cb0ef41Sopenharmony_ci
17731cb0ef41Sopenharmony_ci  bool is_optimizable_farjmp(int idx);
17741cb0ef41Sopenharmony_ci
17751cb0ef41Sopenharmony_ci  void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
17761cb0ef41Sopenharmony_ci
17771cb0ef41Sopenharmony_ci  int WriteCodeComments();
17781cb0ef41Sopenharmony_ci
17791cb0ef41Sopenharmony_ci  friend class EnsureSpace;
17801cb0ef41Sopenharmony_ci
17811cb0ef41Sopenharmony_ci  // Internal reference positions, required for (potential) patching in
17821cb0ef41Sopenharmony_ci  // GrowBuffer(); contains only those internal references whose labels
17831cb0ef41Sopenharmony_ci  // are already bound.
17841cb0ef41Sopenharmony_ci  std::deque<int> internal_reference_positions_;
17851cb0ef41Sopenharmony_ci
17861cb0ef41Sopenharmony_ci  // code generation
17871cb0ef41Sopenharmony_ci  RelocInfoWriter reloc_info_writer;
17881cb0ef41Sopenharmony_ci
17891cb0ef41Sopenharmony_ci  // Variables for this instance of assembler
17901cb0ef41Sopenharmony_ci  int farjmp_num_ = 0;
17911cb0ef41Sopenharmony_ci  std::deque<int> farjmp_positions_;
17921cb0ef41Sopenharmony_ci  std::map<Label*, std::vector<int>> label_farjmp_maps_;
17931cb0ef41Sopenharmony_ci};
17941cb0ef41Sopenharmony_ci
17951cb0ef41Sopenharmony_ci// Helper class that ensures that there is enough space for generating
17961cb0ef41Sopenharmony_ci// instructions and relocation information.  The constructor makes
17971cb0ef41Sopenharmony_ci// sure that there is enough space and (in debug mode) the destructor
17981cb0ef41Sopenharmony_ci// checks that we did not generate too much.
17991cb0ef41Sopenharmony_ciclass EnsureSpace {
18001cb0ef41Sopenharmony_ci public:
18011cb0ef41Sopenharmony_ci  explicit V8_INLINE EnsureSpace(Assembler* assembler) : assembler_(assembler) {
18021cb0ef41Sopenharmony_ci    if (V8_UNLIKELY(assembler_->buffer_overflow())) assembler_->GrowBuffer();
18031cb0ef41Sopenharmony_ci#ifdef DEBUG
18041cb0ef41Sopenharmony_ci    space_before_ = assembler->available_space();
18051cb0ef41Sopenharmony_ci#endif
18061cb0ef41Sopenharmony_ci  }
18071cb0ef41Sopenharmony_ci
18081cb0ef41Sopenharmony_ci#ifdef DEBUG
18091cb0ef41Sopenharmony_ci  ~EnsureSpace() {
18101cb0ef41Sopenharmony_ci    int bytes_generated = space_before_ - assembler_->available_space();
18111cb0ef41Sopenharmony_ci    DCHECK(bytes_generated < assembler_->kGap);
18121cb0ef41Sopenharmony_ci  }
18131cb0ef41Sopenharmony_ci#endif
18141cb0ef41Sopenharmony_ci
18151cb0ef41Sopenharmony_ci private:
18161cb0ef41Sopenharmony_ci  Assembler* const assembler_;
18171cb0ef41Sopenharmony_ci#ifdef DEBUG
18181cb0ef41Sopenharmony_ci  int space_before_;
18191cb0ef41Sopenharmony_ci#endif
18201cb0ef41Sopenharmony_ci};
18211cb0ef41Sopenharmony_ci
18221cb0ef41Sopenharmony_ci}  // namespace internal
18231cb0ef41Sopenharmony_ci}  // namespace v8
18241cb0ef41Sopenharmony_ci
18251cb0ef41Sopenharmony_ci#endif  // V8_CODEGEN_IA32_ASSEMBLER_IA32_H_
1826