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