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 2012 the V8 project authors. All rights reserved. 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci// A lightweight X64 Assembler. 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci#ifndef V8_CODEGEN_X64_ASSEMBLER_X64_H_ 381cb0ef41Sopenharmony_ci#define V8_CODEGEN_X64_ASSEMBLER_X64_H_ 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci#include <deque> 411cb0ef41Sopenharmony_ci#include <map> 421cb0ef41Sopenharmony_ci#include <memory> 431cb0ef41Sopenharmony_ci#include <vector> 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci#include "src/base/export-template.h" 461cb0ef41Sopenharmony_ci#include "src/codegen/assembler.h" 471cb0ef41Sopenharmony_ci#include "src/codegen/cpu-features.h" 481cb0ef41Sopenharmony_ci#include "src/codegen/label.h" 491cb0ef41Sopenharmony_ci#include "src/codegen/x64/constants-x64.h" 501cb0ef41Sopenharmony_ci#include "src/codegen/x64/fma-instr.h" 511cb0ef41Sopenharmony_ci#include "src/codegen/x64/register-x64.h" 521cb0ef41Sopenharmony_ci#include "src/codegen/x64/sse-instr.h" 531cb0ef41Sopenharmony_ci#include "src/objects/smi.h" 541cb0ef41Sopenharmony_ci#if defined(V8_OS_WIN_X64) 551cb0ef41Sopenharmony_ci#include "src/diagnostics/unwinding-info-win64.h" 561cb0ef41Sopenharmony_ci#endif 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_cinamespace v8 { 591cb0ef41Sopenharmony_cinamespace internal { 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ciclass SafepointTableBuilder; 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci// Utility functions 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_cienum Condition { 661cb0ef41Sopenharmony_ci // any value < 0 is considered no_condition 671cb0ef41Sopenharmony_ci no_condition = -1, 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci overflow = 0, 701cb0ef41Sopenharmony_ci no_overflow = 1, 711cb0ef41Sopenharmony_ci below = 2, 721cb0ef41Sopenharmony_ci above_equal = 3, 731cb0ef41Sopenharmony_ci equal = 4, 741cb0ef41Sopenharmony_ci not_equal = 5, 751cb0ef41Sopenharmony_ci below_equal = 6, 761cb0ef41Sopenharmony_ci above = 7, 771cb0ef41Sopenharmony_ci negative = 8, 781cb0ef41Sopenharmony_ci positive = 9, 791cb0ef41Sopenharmony_ci parity_even = 10, 801cb0ef41Sopenharmony_ci parity_odd = 11, 811cb0ef41Sopenharmony_ci less = 12, 821cb0ef41Sopenharmony_ci greater_equal = 13, 831cb0ef41Sopenharmony_ci less_equal = 14, 841cb0ef41Sopenharmony_ci greater = 15, 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci // Fake conditions that are handled by the 871cb0ef41Sopenharmony_ci // opcodes using them. 881cb0ef41Sopenharmony_ci always = 16, 891cb0ef41Sopenharmony_ci never = 17, 901cb0ef41Sopenharmony_ci // aliases 911cb0ef41Sopenharmony_ci carry = below, 921cb0ef41Sopenharmony_ci not_carry = above_equal, 931cb0ef41Sopenharmony_ci zero = equal, 941cb0ef41Sopenharmony_ci not_zero = not_equal, 951cb0ef41Sopenharmony_ci sign = negative, 961cb0ef41Sopenharmony_ci not_sign = positive, 971cb0ef41Sopenharmony_ci last_condition = greater 981cb0ef41Sopenharmony_ci}; 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci// Returns the equivalent of !cc. 1011cb0ef41Sopenharmony_ci// Negation of the default no_condition (-1) results in a non-default 1021cb0ef41Sopenharmony_ci// no_condition value (-2). As long as tests for no_condition check 1031cb0ef41Sopenharmony_ci// for condition < 0, this will work as expected. 1041cb0ef41Sopenharmony_ciinline Condition NegateCondition(Condition cc) { 1051cb0ef41Sopenharmony_ci return static_cast<Condition>(cc ^ 1); 1061cb0ef41Sopenharmony_ci} 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_cienum RoundingMode { 1091cb0ef41Sopenharmony_ci kRoundToNearest = 0x0, 1101cb0ef41Sopenharmony_ci kRoundDown = 0x1, 1111cb0ef41Sopenharmony_ci kRoundUp = 0x2, 1121cb0ef41Sopenharmony_ci kRoundToZero = 0x3 1131cb0ef41Sopenharmony_ci}; 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------- 1161cb0ef41Sopenharmony_ci// Machine instruction Immediates 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ciclass Immediate { 1191cb0ef41Sopenharmony_ci public: 1201cb0ef41Sopenharmony_ci explicit constexpr Immediate(int32_t value) : value_(value) {} 1211cb0ef41Sopenharmony_ci explicit constexpr Immediate(int32_t value, RelocInfo::Mode rmode) 1221cb0ef41Sopenharmony_ci : value_(value), rmode_(rmode) {} 1231cb0ef41Sopenharmony_ci explicit Immediate(Smi value) 1241cb0ef41Sopenharmony_ci : value_(static_cast<int32_t>(static_cast<intptr_t>(value.ptr()))) { 1251cb0ef41Sopenharmony_ci DCHECK(SmiValuesAre31Bits()); // Only available for 31-bit SMI. 1261cb0ef41Sopenharmony_ci } 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci int32_t value() const { return value_; } 1291cb0ef41Sopenharmony_ci RelocInfo::Mode rmode() const { return rmode_; } 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci private: 1321cb0ef41Sopenharmony_ci const int32_t value_; 1331cb0ef41Sopenharmony_ci const RelocInfo::Mode rmode_ = RelocInfo::NO_INFO; 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci friend class Assembler; 1361cb0ef41Sopenharmony_ci}; 1371cb0ef41Sopenharmony_ciASSERT_TRIVIALLY_COPYABLE(Immediate); 1381cb0ef41Sopenharmony_cistatic_assert(sizeof(Immediate) <= kSystemPointerSize, 1391cb0ef41Sopenharmony_ci "Immediate must be small enough to pass it by value"); 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ciclass Immediate64 { 1421cb0ef41Sopenharmony_ci public: 1431cb0ef41Sopenharmony_ci explicit constexpr Immediate64(int64_t value) : value_(value) {} 1441cb0ef41Sopenharmony_ci explicit constexpr Immediate64(int64_t value, RelocInfo::Mode rmode) 1451cb0ef41Sopenharmony_ci : value_(value), rmode_(rmode) {} 1461cb0ef41Sopenharmony_ci explicit constexpr Immediate64(Address value, RelocInfo::Mode rmode) 1471cb0ef41Sopenharmony_ci : value_(static_cast<int64_t>(value)), rmode_(rmode) {} 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci private: 1501cb0ef41Sopenharmony_ci const int64_t value_; 1511cb0ef41Sopenharmony_ci const RelocInfo::Mode rmode_ = RelocInfo::NO_INFO; 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci friend class Assembler; 1541cb0ef41Sopenharmony_ci}; 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------- 1571cb0ef41Sopenharmony_ci// Machine instruction Operands 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_cienum ScaleFactor : int8_t { 1601cb0ef41Sopenharmony_ci times_1 = 0, 1611cb0ef41Sopenharmony_ci times_2 = 1, 1621cb0ef41Sopenharmony_ci times_4 = 2, 1631cb0ef41Sopenharmony_ci times_8 = 3, 1641cb0ef41Sopenharmony_ci times_int_size = times_4, 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ci times_half_system_pointer_size = times_4, 1671cb0ef41Sopenharmony_ci times_system_pointer_size = times_8, 1681cb0ef41Sopenharmony_ci times_tagged_size = (kTaggedSize == 8) ? times_8 : times_4, 1691cb0ef41Sopenharmony_ci}; 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE Operand { 1721cb0ef41Sopenharmony_ci public: 1731cb0ef41Sopenharmony_ci struct Data { 1741cb0ef41Sopenharmony_ci byte rex = 0; 1751cb0ef41Sopenharmony_ci byte buf[9]; 1761cb0ef41Sopenharmony_ci byte len = 1; // number of bytes of buf_ in use. 1771cb0ef41Sopenharmony_ci int8_t addend; // for rip + offset + addend. 1781cb0ef41Sopenharmony_ci }; 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_ci // [base + disp/r] 1811cb0ef41Sopenharmony_ci V8_INLINE Operand(Register base, int32_t disp) { 1821cb0ef41Sopenharmony_ci if (base == rsp || base == r12) { 1831cb0ef41Sopenharmony_ci // SIB byte is needed to encode (rsp + offset) or (r12 + offset). 1841cb0ef41Sopenharmony_ci set_sib(times_1, rsp, base); 1851cb0ef41Sopenharmony_ci } 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci if (disp == 0 && base != rbp && base != r13) { 1881cb0ef41Sopenharmony_ci set_modrm(0, base); 1891cb0ef41Sopenharmony_ci } else if (is_int8(disp)) { 1901cb0ef41Sopenharmony_ci set_modrm(1, base); 1911cb0ef41Sopenharmony_ci set_disp8(disp); 1921cb0ef41Sopenharmony_ci } else { 1931cb0ef41Sopenharmony_ci set_modrm(2, base); 1941cb0ef41Sopenharmony_ci set_disp32(disp); 1951cb0ef41Sopenharmony_ci } 1961cb0ef41Sopenharmony_ci } 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ci // [base + index*scale + disp/r] 1991cb0ef41Sopenharmony_ci V8_INLINE Operand(Register base, Register index, ScaleFactor scale, 2001cb0ef41Sopenharmony_ci int32_t disp) { 2011cb0ef41Sopenharmony_ci DCHECK(index != rsp); 2021cb0ef41Sopenharmony_ci set_sib(scale, index, base); 2031cb0ef41Sopenharmony_ci if (disp == 0 && base != rbp && base != r13) { 2041cb0ef41Sopenharmony_ci // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits 2051cb0ef41Sopenharmony_ci // possibly set by set_sib. 2061cb0ef41Sopenharmony_ci set_modrm(0, rsp); 2071cb0ef41Sopenharmony_ci } else if (is_int8(disp)) { 2081cb0ef41Sopenharmony_ci set_modrm(1, rsp); 2091cb0ef41Sopenharmony_ci set_disp8(disp); 2101cb0ef41Sopenharmony_ci } else { 2111cb0ef41Sopenharmony_ci set_modrm(2, rsp); 2121cb0ef41Sopenharmony_ci set_disp32(disp); 2131cb0ef41Sopenharmony_ci } 2141cb0ef41Sopenharmony_ci } 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci // [index*scale + disp/r] 2171cb0ef41Sopenharmony_ci V8_INLINE Operand(Register index, ScaleFactor scale, int32_t disp) { 2181cb0ef41Sopenharmony_ci DCHECK(index != rsp); 2191cb0ef41Sopenharmony_ci set_modrm(0, rsp); 2201cb0ef41Sopenharmony_ci set_sib(scale, index, rbp); 2211cb0ef41Sopenharmony_ci set_disp32(disp); 2221cb0ef41Sopenharmony_ci } 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ci // Offset from existing memory operand. 2251cb0ef41Sopenharmony_ci // Offset is added to existing displacement as 32-bit signed values and 2261cb0ef41Sopenharmony_ci // this must not overflow. 2271cb0ef41Sopenharmony_ci Operand(Operand base, int32_t offset); 2281cb0ef41Sopenharmony_ci 2291cb0ef41Sopenharmony_ci // [rip + disp/r] 2301cb0ef41Sopenharmony_ci V8_INLINE explicit Operand(Label* label, int addend = 0) { 2311cb0ef41Sopenharmony_ci data_.addend = addend; 2321cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(label); 2331cb0ef41Sopenharmony_ci DCHECK(addend == 0 || (is_int8(addend) && label->is_bound())); 2341cb0ef41Sopenharmony_ci set_modrm(0, rbp); 2351cb0ef41Sopenharmony_ci set_disp64(reinterpret_cast<intptr_t>(label)); 2361cb0ef41Sopenharmony_ci } 2371cb0ef41Sopenharmony_ci 2381cb0ef41Sopenharmony_ci Operand(const Operand&) V8_NOEXCEPT = default; 2391cb0ef41Sopenharmony_ci Operand& operator=(const Operand&) V8_NOEXCEPT = default; 2401cb0ef41Sopenharmony_ci 2411cb0ef41Sopenharmony_ci const Data& data() const { return data_; } 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ci // Checks whether either base or index register is the given register. 2441cb0ef41Sopenharmony_ci // Does not check the "reg" part of the Operand. 2451cb0ef41Sopenharmony_ci bool AddressUsesRegister(Register reg) const; 2461cb0ef41Sopenharmony_ci 2471cb0ef41Sopenharmony_ci private: 2481cb0ef41Sopenharmony_ci V8_INLINE void set_modrm(int mod, Register rm_reg) { 2491cb0ef41Sopenharmony_ci DCHECK(is_uint2(mod)); 2501cb0ef41Sopenharmony_ci data_.buf[0] = mod << 6 | rm_reg.low_bits(); 2511cb0ef41Sopenharmony_ci // Set REX.B to the high bit of rm.code(). 2521cb0ef41Sopenharmony_ci data_.rex |= rm_reg.high_bit(); 2531cb0ef41Sopenharmony_ci } 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ci V8_INLINE void set_sib(ScaleFactor scale, Register index, Register base) { 2561cb0ef41Sopenharmony_ci DCHECK_EQ(data_.len, 1); 2571cb0ef41Sopenharmony_ci DCHECK(is_uint2(scale)); 2581cb0ef41Sopenharmony_ci // Use SIB with no index register only for base rsp or r12. Otherwise we 2591cb0ef41Sopenharmony_ci // would skip the SIB byte entirely. 2601cb0ef41Sopenharmony_ci DCHECK(index != rsp || base == rsp || base == r12); 2611cb0ef41Sopenharmony_ci data_.buf[1] = (scale << 6) | (index.low_bits() << 3) | base.low_bits(); 2621cb0ef41Sopenharmony_ci data_.rex |= index.high_bit() << 1 | base.high_bit(); 2631cb0ef41Sopenharmony_ci data_.len = 2; 2641cb0ef41Sopenharmony_ci } 2651cb0ef41Sopenharmony_ci 2661cb0ef41Sopenharmony_ci V8_INLINE void set_disp8(int disp) { 2671cb0ef41Sopenharmony_ci DCHECK(is_int8(disp)); 2681cb0ef41Sopenharmony_ci DCHECK(data_.len == 1 || data_.len == 2); 2691cb0ef41Sopenharmony_ci int8_t* p = reinterpret_cast<int8_t*>(&data_.buf[data_.len]); 2701cb0ef41Sopenharmony_ci *p = disp; 2711cb0ef41Sopenharmony_ci data_.len += sizeof(int8_t); 2721cb0ef41Sopenharmony_ci } 2731cb0ef41Sopenharmony_ci 2741cb0ef41Sopenharmony_ci V8_INLINE void set_disp32(int disp) { 2751cb0ef41Sopenharmony_ci DCHECK(data_.len == 1 || data_.len == 2); 2761cb0ef41Sopenharmony_ci Address p = reinterpret_cast<Address>(&data_.buf[data_.len]); 2771cb0ef41Sopenharmony_ci WriteUnalignedValue(p, disp); 2781cb0ef41Sopenharmony_ci data_.len += sizeof(int32_t); 2791cb0ef41Sopenharmony_ci } 2801cb0ef41Sopenharmony_ci 2811cb0ef41Sopenharmony_ci V8_INLINE void set_disp64(int64_t disp) { 2821cb0ef41Sopenharmony_ci DCHECK_EQ(1, data_.len); 2831cb0ef41Sopenharmony_ci Address p = reinterpret_cast<Address>(&data_.buf[data_.len]); 2841cb0ef41Sopenharmony_ci WriteUnalignedValue(p, disp); 2851cb0ef41Sopenharmony_ci data_.len += sizeof(disp); 2861cb0ef41Sopenharmony_ci } 2871cb0ef41Sopenharmony_ci 2881cb0ef41Sopenharmony_ci Data data_; 2891cb0ef41Sopenharmony_ci}; 2901cb0ef41Sopenharmony_ciASSERT_TRIVIALLY_COPYABLE(Operand); 2911cb0ef41Sopenharmony_cistatic_assert(sizeof(Operand) <= 2 * kSystemPointerSize, 2921cb0ef41Sopenharmony_ci "Operand must be small enough to pass it by value"); 2931cb0ef41Sopenharmony_ci 2941cb0ef41Sopenharmony_ci#define ASSEMBLER_INSTRUCTION_LIST(V) \ 2951cb0ef41Sopenharmony_ci V(add) \ 2961cb0ef41Sopenharmony_ci V(and) \ 2971cb0ef41Sopenharmony_ci V(cmp) \ 2981cb0ef41Sopenharmony_ci V(cmpxchg) \ 2991cb0ef41Sopenharmony_ci V(dec) \ 3001cb0ef41Sopenharmony_ci V(idiv) \ 3011cb0ef41Sopenharmony_ci V(div) \ 3021cb0ef41Sopenharmony_ci V(imul) \ 3031cb0ef41Sopenharmony_ci V(inc) \ 3041cb0ef41Sopenharmony_ci V(lea) \ 3051cb0ef41Sopenharmony_ci V(mov) \ 3061cb0ef41Sopenharmony_ci V(movzxb) \ 3071cb0ef41Sopenharmony_ci V(movzxw) \ 3081cb0ef41Sopenharmony_ci V(not) \ 3091cb0ef41Sopenharmony_ci V(or) \ 3101cb0ef41Sopenharmony_ci V(repmovs) \ 3111cb0ef41Sopenharmony_ci V(sbb) \ 3121cb0ef41Sopenharmony_ci V(sub) \ 3131cb0ef41Sopenharmony_ci V(test) \ 3141cb0ef41Sopenharmony_ci V(xchg) \ 3151cb0ef41Sopenharmony_ci V(xor) 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_ci// Shift instructions on operands/registers with kInt32Size and kInt64Size. 3181cb0ef41Sopenharmony_ci#define SHIFT_INSTRUCTION_LIST(V) \ 3191cb0ef41Sopenharmony_ci V(rol, 0x0) \ 3201cb0ef41Sopenharmony_ci V(ror, 0x1) \ 3211cb0ef41Sopenharmony_ci V(rcl, 0x2) \ 3221cb0ef41Sopenharmony_ci V(rcr, 0x3) \ 3231cb0ef41Sopenharmony_ci V(shl, 0x4) \ 3241cb0ef41Sopenharmony_ci V(shr, 0x5) \ 3251cb0ef41Sopenharmony_ci V(sar, 0x7) 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_ci// Partial Constant Pool 3281cb0ef41Sopenharmony_ci// Different from complete constant pool (like arm does), partial constant pool 3291cb0ef41Sopenharmony_ci// only takes effects for shareable constants in order to reduce code size. 3301cb0ef41Sopenharmony_ci// Partial constant pool does not emit constant pool entries at the end of each 3311cb0ef41Sopenharmony_ci// code object. Instead, it keeps the first shareable constant inlined in the 3321cb0ef41Sopenharmony_ci// instructions and uses rip-relative memory loadings for the same constants in 3331cb0ef41Sopenharmony_ci// subsequent instructions. These rip-relative memory loadings will target at 3341cb0ef41Sopenharmony_ci// the position of the first inlined constant. For example: 3351cb0ef41Sopenharmony_ci// 3361cb0ef41Sopenharmony_ci// REX.W movq r10,0x7f9f75a32c20 ; 10 bytes 3371cb0ef41Sopenharmony_ci// … 3381cb0ef41Sopenharmony_ci// REX.W movq r10,0x7f9f75a32c20 ; 10 bytes 3391cb0ef41Sopenharmony_ci// … 3401cb0ef41Sopenharmony_ci// 3411cb0ef41Sopenharmony_ci// turns into 3421cb0ef41Sopenharmony_ci// 3431cb0ef41Sopenharmony_ci// REX.W movq r10,0x7f9f75a32c20 ; 10 bytes 3441cb0ef41Sopenharmony_ci// … 3451cb0ef41Sopenharmony_ci// REX.W movq r10,[rip+0xffffff96] ; 7 bytes 3461cb0ef41Sopenharmony_ci// … 3471cb0ef41Sopenharmony_ci 3481cb0ef41Sopenharmony_ciclass ConstPool { 3491cb0ef41Sopenharmony_ci public: 3501cb0ef41Sopenharmony_ci explicit ConstPool(Assembler* assm) : assm_(assm) {} 3511cb0ef41Sopenharmony_ci // Returns true when partial constant pool is valid for this entry. 3521cb0ef41Sopenharmony_ci bool TryRecordEntry(intptr_t data, RelocInfo::Mode mode); 3531cb0ef41Sopenharmony_ci bool IsEmpty() const { return entries_.empty(); } 3541cb0ef41Sopenharmony_ci 3551cb0ef41Sopenharmony_ci void PatchEntries(); 3561cb0ef41Sopenharmony_ci // Discard any pending pool entries. 3571cb0ef41Sopenharmony_ci void Clear(); 3581cb0ef41Sopenharmony_ci 3591cb0ef41Sopenharmony_ci private: 3601cb0ef41Sopenharmony_ci // Adds a shared entry to entries_. Returns true if this is not the first time 3611cb0ef41Sopenharmony_ci // we add this entry, false otherwise. 3621cb0ef41Sopenharmony_ci bool AddSharedEntry(uint64_t data, int offset); 3631cb0ef41Sopenharmony_ci 3641cb0ef41Sopenharmony_ci // Check if the instruction is a rip-relative move. 3651cb0ef41Sopenharmony_ci bool IsMoveRipRelative(Address instr); 3661cb0ef41Sopenharmony_ci 3671cb0ef41Sopenharmony_ci Assembler* assm_; 3681cb0ef41Sopenharmony_ci 3691cb0ef41Sopenharmony_ci // Values, pc offsets of entries. 3701cb0ef41Sopenharmony_ci using EntryMap = std::multimap<uint64_t, int>; 3711cb0ef41Sopenharmony_ci EntryMap entries_; 3721cb0ef41Sopenharmony_ci 3731cb0ef41Sopenharmony_ci // Number of bytes taken up by the displacement of rip-relative addressing. 3741cb0ef41Sopenharmony_ci static constexpr int kRipRelativeDispSize = 4; // 32-bit displacement. 3751cb0ef41Sopenharmony_ci // Distance between the address of the displacement in the rip-relative move 3761cb0ef41Sopenharmony_ci // instruction and the head address of the instruction. 3771cb0ef41Sopenharmony_ci static constexpr int kMoveRipRelativeDispOffset = 3781cb0ef41Sopenharmony_ci 3; // REX Opcode ModRM Displacement 3791cb0ef41Sopenharmony_ci // Distance between the address of the imm64 in the 'movq reg, imm64' 3801cb0ef41Sopenharmony_ci // instruction and the head address of the instruction. 3811cb0ef41Sopenharmony_ci static constexpr int kMoveImm64Offset = 2; // REX Opcode imm64 3821cb0ef41Sopenharmony_ci // A mask for rip-relative move instruction. 3831cb0ef41Sopenharmony_ci static constexpr uint32_t kMoveRipRelativeMask = 0x00C7FFFB; 3841cb0ef41Sopenharmony_ci // The bits for a rip-relative move instruction after mask. 3851cb0ef41Sopenharmony_ci static constexpr uint32_t kMoveRipRelativeInstr = 0x00058B48; 3861cb0ef41Sopenharmony_ci}; 3871cb0ef41Sopenharmony_ci 3881cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE Assembler : public AssemblerBase { 3891cb0ef41Sopenharmony_ci private: 3901cb0ef41Sopenharmony_ci // We check before assembling an instruction that there is sufficient 3911cb0ef41Sopenharmony_ci // space to write an instruction and its relocation information. 3921cb0ef41Sopenharmony_ci // The relocation writer's position must be kGap bytes above the end of 3931cb0ef41Sopenharmony_ci // the generated instructions. This leaves enough space for the 3941cb0ef41Sopenharmony_ci // longest possible x64 instruction, 15 bytes, and the longest possible 3951cb0ef41Sopenharmony_ci // relocation information encoding, RelocInfoWriter::kMaxLength == 16. 3961cb0ef41Sopenharmony_ci // (There is a 15 byte limit on x64 instruction length that rules out some 3971cb0ef41Sopenharmony_ci // otherwise valid instructions.) 3981cb0ef41Sopenharmony_ci // This allows for a single, fast space check per instruction. 3991cb0ef41Sopenharmony_ci static constexpr int kGap = 32; 4001cb0ef41Sopenharmony_ci STATIC_ASSERT(AssemblerBase::kMinimalBufferSize >= 2 * kGap); 4011cb0ef41Sopenharmony_ci 4021cb0ef41Sopenharmony_ci public: 4031cb0ef41Sopenharmony_ci // Create an assembler. Instructions and relocation information are emitted 4041cb0ef41Sopenharmony_ci // into a buffer, with the instructions starting from the beginning and the 4051cb0ef41Sopenharmony_ci // relocation information starting from the end of the buffer. See CodeDesc 4061cb0ef41Sopenharmony_ci // for a detailed comment on the layout (globals.h). 4071cb0ef41Sopenharmony_ci // 4081cb0ef41Sopenharmony_ci // If the provided buffer is nullptr, the assembler allocates and grows its 4091cb0ef41Sopenharmony_ci // own buffer. Otherwise it takes ownership of the provided buffer. 4101cb0ef41Sopenharmony_ci explicit Assembler(const AssemblerOptions&, 4111cb0ef41Sopenharmony_ci std::unique_ptr<AssemblerBuffer> = {}); 4121cb0ef41Sopenharmony_ci ~Assembler() override = default; 4131cb0ef41Sopenharmony_ci 4141cb0ef41Sopenharmony_ci // GetCode emits any pending (non-emitted) code and fills the descriptor desc. 4151cb0ef41Sopenharmony_ci static constexpr int kNoHandlerTable = 0; 4161cb0ef41Sopenharmony_ci static constexpr SafepointTableBuilder* kNoSafepointTable = nullptr; 4171cb0ef41Sopenharmony_ci void GetCode(Isolate* isolate, CodeDesc* desc, 4181cb0ef41Sopenharmony_ci SafepointTableBuilder* safepoint_table_builder, 4191cb0ef41Sopenharmony_ci int handler_table_offset); 4201cb0ef41Sopenharmony_ci 4211cb0ef41Sopenharmony_ci // Convenience wrapper for code without safepoint or handler tables. 4221cb0ef41Sopenharmony_ci void GetCode(Isolate* isolate, CodeDesc* desc) { 4231cb0ef41Sopenharmony_ci GetCode(isolate, desc, kNoSafepointTable, kNoHandlerTable); 4241cb0ef41Sopenharmony_ci } 4251cb0ef41Sopenharmony_ci 4261cb0ef41Sopenharmony_ci void FinalizeJumpOptimizationInfo(); 4271cb0ef41Sopenharmony_ci 4281cb0ef41Sopenharmony_ci // Unused on this architecture. 4291cb0ef41Sopenharmony_ci void MaybeEmitOutOfLineConstantPool() {} 4301cb0ef41Sopenharmony_ci 4311cb0ef41Sopenharmony_ci // Read/Modify the code target in the relative branch/call instruction at pc. 4321cb0ef41Sopenharmony_ci // On the x64 architecture, we use relative jumps with a 32-bit displacement 4331cb0ef41Sopenharmony_ci // to jump to other Code objects in the Code space in the heap. 4341cb0ef41Sopenharmony_ci // Jumps to C functions are done indirectly through a 64-bit register holding 4351cb0ef41Sopenharmony_ci // the absolute address of the target. 4361cb0ef41Sopenharmony_ci // These functions convert between absolute Addresses of Code objects and 4371cb0ef41Sopenharmony_ci // the relative displacements stored in the code. 4381cb0ef41Sopenharmony_ci // The isolate argument is unused (and may be nullptr) when skipping flushing. 4391cb0ef41Sopenharmony_ci static inline Address target_address_at(Address pc, Address constant_pool); 4401cb0ef41Sopenharmony_ci static inline void set_target_address_at( 4411cb0ef41Sopenharmony_ci Address pc, Address constant_pool, Address target, 4421cb0ef41Sopenharmony_ci ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); 4431cb0ef41Sopenharmony_ci static inline int32_t relative_target_offset(Address target, Address pc); 4441cb0ef41Sopenharmony_ci 4451cb0ef41Sopenharmony_ci // This sets the branch destination (which is in the instruction on x64). 4461cb0ef41Sopenharmony_ci // This is for calls and branches within generated code. 4471cb0ef41Sopenharmony_ci inline static void deserialization_set_special_target_at( 4481cb0ef41Sopenharmony_ci Address instruction_payload, Code code, Address target); 4491cb0ef41Sopenharmony_ci 4501cb0ef41Sopenharmony_ci // Get the size of the special target encoded at 'instruction_payload'. 4511cb0ef41Sopenharmony_ci inline static int deserialization_special_target_size( 4521cb0ef41Sopenharmony_ci Address instruction_payload); 4531cb0ef41Sopenharmony_ci 4541cb0ef41Sopenharmony_ci // This sets the internal reference at the pc. 4551cb0ef41Sopenharmony_ci inline static void deserialization_set_target_internal_reference_at( 4561cb0ef41Sopenharmony_ci Address pc, Address target, 4571cb0ef41Sopenharmony_ci RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 4581cb0ef41Sopenharmony_ci 4591cb0ef41Sopenharmony_ci inline Handle<CodeT> code_target_object_handle_at(Address pc); 4601cb0ef41Sopenharmony_ci inline Handle<HeapObject> compressed_embedded_object_handle_at(Address pc); 4611cb0ef41Sopenharmony_ci inline Address runtime_entry_at(Address pc); 4621cb0ef41Sopenharmony_ci 4631cb0ef41Sopenharmony_ci // Number of bytes taken up by the branch target in the code. 4641cb0ef41Sopenharmony_ci static constexpr int kSpecialTargetSize = 4; // 32-bit displacement. 4651cb0ef41Sopenharmony_ci 4661cb0ef41Sopenharmony_ci // One byte opcode for test eax,0xXXXXXXXX. 4671cb0ef41Sopenharmony_ci static constexpr byte kTestEaxByte = 0xA9; 4681cb0ef41Sopenharmony_ci // One byte opcode for test al, 0xXX. 4691cb0ef41Sopenharmony_ci static constexpr byte kTestAlByte = 0xA8; 4701cb0ef41Sopenharmony_ci // One byte opcode for nop. 4711cb0ef41Sopenharmony_ci static constexpr byte kNopByte = 0x90; 4721cb0ef41Sopenharmony_ci 4731cb0ef41Sopenharmony_ci // One byte prefix for a short conditional jump. 4741cb0ef41Sopenharmony_ci static constexpr byte kJccShortPrefix = 0x70; 4751cb0ef41Sopenharmony_ci static constexpr byte kJncShortOpcode = kJccShortPrefix | not_carry; 4761cb0ef41Sopenharmony_ci static constexpr byte kJcShortOpcode = kJccShortPrefix | carry; 4771cb0ef41Sopenharmony_ci static constexpr byte kJnzShortOpcode = kJccShortPrefix | not_zero; 4781cb0ef41Sopenharmony_ci static constexpr byte kJzShortOpcode = kJccShortPrefix | zero; 4791cb0ef41Sopenharmony_ci 4801cb0ef41Sopenharmony_ci // VEX prefix encodings. 4811cb0ef41Sopenharmony_ci enum SIMDPrefix { kNoPrefix = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 }; 4821cb0ef41Sopenharmony_ci enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128, kLZ = kL128 }; 4831cb0ef41Sopenharmony_ci enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 }; 4841cb0ef41Sopenharmony_ci enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x3 }; 4851cb0ef41Sopenharmony_ci 4861cb0ef41Sopenharmony_ci // --------------------------------------------------------------------------- 4871cb0ef41Sopenharmony_ci // Code generation 4881cb0ef41Sopenharmony_ci // 4891cb0ef41Sopenharmony_ci // Function names correspond one-to-one to x64 instruction mnemonics. 4901cb0ef41Sopenharmony_ci // Unless specified otherwise, instructions operate on 64-bit operands. 4911cb0ef41Sopenharmony_ci // 4921cb0ef41Sopenharmony_ci // If we need versions of an assembly instruction that operate on different 4931cb0ef41Sopenharmony_ci // width arguments, we add a single-letter suffix specifying the width. 4941cb0ef41Sopenharmony_ci // This is done for the following instructions: mov, cmp, inc, dec, 4951cb0ef41Sopenharmony_ci // add, sub, and test. 4961cb0ef41Sopenharmony_ci // There are no versions of these instructions without the suffix. 4971cb0ef41Sopenharmony_ci // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. 4981cb0ef41Sopenharmony_ci // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. 4991cb0ef41Sopenharmony_ci // - Instructions on 32-bit (doubleword) operands/registers use 'l'. 5001cb0ef41Sopenharmony_ci // - Instructions on 64-bit (quadword) operands/registers use 'q'. 5011cb0ef41Sopenharmony_ci // - Instructions on operands/registers with pointer size use 'p'. 5021cb0ef41Sopenharmony_ci 5031cb0ef41Sopenharmony_ci#define DECLARE_INSTRUCTION(instruction) \ 5041cb0ef41Sopenharmony_ci template <typename... Ps> \ 5051cb0ef41Sopenharmony_ci void instruction##_tagged(Ps... ps) { \ 5061cb0ef41Sopenharmony_ci emit_##instruction(ps..., kTaggedSize); \ 5071cb0ef41Sopenharmony_ci } \ 5081cb0ef41Sopenharmony_ci \ 5091cb0ef41Sopenharmony_ci template <typename... Ps> \ 5101cb0ef41Sopenharmony_ci void instruction##l(Ps... ps) { \ 5111cb0ef41Sopenharmony_ci emit_##instruction(ps..., kInt32Size); \ 5121cb0ef41Sopenharmony_ci } \ 5131cb0ef41Sopenharmony_ci \ 5141cb0ef41Sopenharmony_ci template <typename... Ps> \ 5151cb0ef41Sopenharmony_ci void instruction##q(Ps... ps) { \ 5161cb0ef41Sopenharmony_ci emit_##instruction(ps..., kInt64Size); \ 5171cb0ef41Sopenharmony_ci } 5181cb0ef41Sopenharmony_ci ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION) 5191cb0ef41Sopenharmony_ci#undef DECLARE_INSTRUCTION 5201cb0ef41Sopenharmony_ci 5211cb0ef41Sopenharmony_ci // Insert the smallest number of nop instructions 5221cb0ef41Sopenharmony_ci // possible to align the pc offset to a multiple 5231cb0ef41Sopenharmony_ci // of m, where m must be a power of 2. 5241cb0ef41Sopenharmony_ci void Align(int m); 5251cb0ef41Sopenharmony_ci // Insert the smallest number of zero bytes possible to align the pc offset 5261cb0ef41Sopenharmony_ci // to a mulitple of m. m must be a power of 2 (>= 2). 5271cb0ef41Sopenharmony_ci void DataAlign(int m); 5281cb0ef41Sopenharmony_ci void Nop(int bytes = 1); 5291cb0ef41Sopenharmony_ci // Aligns code to something that's optimal for a jump target for the platform. 5301cb0ef41Sopenharmony_ci void CodeTargetAlign(); 5311cb0ef41Sopenharmony_ci void LoopHeaderAlign(); 5321cb0ef41Sopenharmony_ci 5331cb0ef41Sopenharmony_ci // Stack 5341cb0ef41Sopenharmony_ci void pushfq(); 5351cb0ef41Sopenharmony_ci void popfq(); 5361cb0ef41Sopenharmony_ci 5371cb0ef41Sopenharmony_ci void pushq(Immediate value); 5381cb0ef41Sopenharmony_ci // Push a 32 bit integer, and guarantee that it is actually pushed as a 5391cb0ef41Sopenharmony_ci // 32 bit value, the normal push will optimize the 8 bit case. 5401cb0ef41Sopenharmony_ci void pushq_imm32(int32_t imm32); 5411cb0ef41Sopenharmony_ci void pushq(Register src); 5421cb0ef41Sopenharmony_ci void pushq(Operand src); 5431cb0ef41Sopenharmony_ci 5441cb0ef41Sopenharmony_ci void popq(Register dst); 5451cb0ef41Sopenharmony_ci void popq(Operand dst); 5461cb0ef41Sopenharmony_ci 5471cb0ef41Sopenharmony_ci void incsspq(Register number_of_words); 5481cb0ef41Sopenharmony_ci 5491cb0ef41Sopenharmony_ci void leave(); 5501cb0ef41Sopenharmony_ci 5511cb0ef41Sopenharmony_ci // Moves 5521cb0ef41Sopenharmony_ci void movb(Register dst, Operand src); 5531cb0ef41Sopenharmony_ci void movb(Register dst, Immediate imm); 5541cb0ef41Sopenharmony_ci void movb(Operand dst, Register src); 5551cb0ef41Sopenharmony_ci void movb(Operand dst, Immediate imm); 5561cb0ef41Sopenharmony_ci 5571cb0ef41Sopenharmony_ci // Move the low 16 bits of a 64-bit register value to a 16-bit 5581cb0ef41Sopenharmony_ci // memory location. 5591cb0ef41Sopenharmony_ci void movw(Register dst, Operand src); 5601cb0ef41Sopenharmony_ci void movw(Operand dst, Register src); 5611cb0ef41Sopenharmony_ci void movw(Operand dst, Immediate imm); 5621cb0ef41Sopenharmony_ci 5631cb0ef41Sopenharmony_ci // Move the offset of the label location relative to the current 5641cb0ef41Sopenharmony_ci // position (after the move) to the destination. 5651cb0ef41Sopenharmony_ci void movl(Operand dst, Label* src); 5661cb0ef41Sopenharmony_ci 5671cb0ef41Sopenharmony_ci // Load a heap number into a register. 5681cb0ef41Sopenharmony_ci // The heap number will not be allocated and embedded into the code right 5691cb0ef41Sopenharmony_ci // away. Instead, we emit the load of a dummy object. Later, when calling 5701cb0ef41Sopenharmony_ci // Assembler::GetCode, the heap number will be allocated and the code will be 5711cb0ef41Sopenharmony_ci // patched by replacing the dummy with the actual object. The RelocInfo for 5721cb0ef41Sopenharmony_ci // the embedded object gets already recorded correctly when emitting the dummy 5731cb0ef41Sopenharmony_ci // move. 5741cb0ef41Sopenharmony_ci void movq_heap_number(Register dst, double value); 5751cb0ef41Sopenharmony_ci 5761cb0ef41Sopenharmony_ci void movq_string(Register dst, const StringConstantBase* str); 5771cb0ef41Sopenharmony_ci 5781cb0ef41Sopenharmony_ci // Loads a 64-bit immediate into a register, potentially using the constant 5791cb0ef41Sopenharmony_ci // pool. 5801cb0ef41Sopenharmony_ci void movq(Register dst, int64_t value) { movq(dst, Immediate64(value)); } 5811cb0ef41Sopenharmony_ci void movq(Register dst, uint64_t value) { 5821cb0ef41Sopenharmony_ci movq(dst, Immediate64(static_cast<int64_t>(value))); 5831cb0ef41Sopenharmony_ci } 5841cb0ef41Sopenharmony_ci 5851cb0ef41Sopenharmony_ci // Loads a 64-bit immediate into a register without using the constant pool. 5861cb0ef41Sopenharmony_ci void movq_imm64(Register dst, int64_t value); 5871cb0ef41Sopenharmony_ci 5881cb0ef41Sopenharmony_ci void movsxbl(Register dst, Register src); 5891cb0ef41Sopenharmony_ci void movsxbl(Register dst, Operand src); 5901cb0ef41Sopenharmony_ci void movsxbq(Register dst, Register src); 5911cb0ef41Sopenharmony_ci void movsxbq(Register dst, Operand src); 5921cb0ef41Sopenharmony_ci void movsxwl(Register dst, Register src); 5931cb0ef41Sopenharmony_ci void movsxwl(Register dst, Operand src); 5941cb0ef41Sopenharmony_ci void movsxwq(Register dst, Register src); 5951cb0ef41Sopenharmony_ci void movsxwq(Register dst, Operand src); 5961cb0ef41Sopenharmony_ci void movsxlq(Register dst, Register src); 5971cb0ef41Sopenharmony_ci void movsxlq(Register dst, Operand src); 5981cb0ef41Sopenharmony_ci 5991cb0ef41Sopenharmony_ci // Repeated moves. 6001cb0ef41Sopenharmony_ci void repmovsb(); 6011cb0ef41Sopenharmony_ci void repmovsw(); 6021cb0ef41Sopenharmony_ci void repmovsl() { emit_repmovs(kInt32Size); } 6031cb0ef41Sopenharmony_ci void repmovsq() { emit_repmovs(kInt64Size); } 6041cb0ef41Sopenharmony_ci 6051cb0ef41Sopenharmony_ci // Repeated store of doublewords (fill (E)CX bytes at ES:[(E)DI] with EAX). 6061cb0ef41Sopenharmony_ci void repstosl(); 6071cb0ef41Sopenharmony_ci // Repeated store of quadwords (fill RCX quadwords at [RDI] with RAX). 6081cb0ef41Sopenharmony_ci void repstosq(); 6091cb0ef41Sopenharmony_ci 6101cb0ef41Sopenharmony_ci // Instruction to load from an immediate 64-bit pointer into RAX. 6111cb0ef41Sopenharmony_ci void load_rax(Address value, RelocInfo::Mode rmode); 6121cb0ef41Sopenharmony_ci void load_rax(ExternalReference ext); 6131cb0ef41Sopenharmony_ci 6141cb0ef41Sopenharmony_ci // Conditional moves. 6151cb0ef41Sopenharmony_ci void cmovq(Condition cc, Register dst, Register src); 6161cb0ef41Sopenharmony_ci void cmovq(Condition cc, Register dst, Operand src); 6171cb0ef41Sopenharmony_ci void cmovl(Condition cc, Register dst, Register src); 6181cb0ef41Sopenharmony_ci void cmovl(Condition cc, Register dst, Operand src); 6191cb0ef41Sopenharmony_ci 6201cb0ef41Sopenharmony_ci void cmpb(Register dst, Immediate src) { 6211cb0ef41Sopenharmony_ci immediate_arithmetic_op_8(0x7, dst, src); 6221cb0ef41Sopenharmony_ci } 6231cb0ef41Sopenharmony_ci 6241cb0ef41Sopenharmony_ci void cmpb_al(Immediate src); 6251cb0ef41Sopenharmony_ci 6261cb0ef41Sopenharmony_ci void cmpb(Register dst, Register src) { arithmetic_op_8(0x3A, dst, src); } 6271cb0ef41Sopenharmony_ci 6281cb0ef41Sopenharmony_ci void cmpb(Register dst, Operand src) { arithmetic_op_8(0x3A, dst, src); } 6291cb0ef41Sopenharmony_ci 6301cb0ef41Sopenharmony_ci void cmpb(Operand dst, Register src) { arithmetic_op_8(0x38, src, dst); } 6311cb0ef41Sopenharmony_ci 6321cb0ef41Sopenharmony_ci void cmpb(Operand dst, Immediate src) { 6331cb0ef41Sopenharmony_ci immediate_arithmetic_op_8(0x7, dst, src); 6341cb0ef41Sopenharmony_ci } 6351cb0ef41Sopenharmony_ci 6361cb0ef41Sopenharmony_ci void cmpw(Operand dst, Immediate src) { 6371cb0ef41Sopenharmony_ci immediate_arithmetic_op_16(0x7, dst, src); 6381cb0ef41Sopenharmony_ci } 6391cb0ef41Sopenharmony_ci 6401cb0ef41Sopenharmony_ci void cmpw(Register dst, Immediate src) { 6411cb0ef41Sopenharmony_ci immediate_arithmetic_op_16(0x7, dst, src); 6421cb0ef41Sopenharmony_ci } 6431cb0ef41Sopenharmony_ci 6441cb0ef41Sopenharmony_ci void cmpw(Register dst, Operand src) { arithmetic_op_16(0x3B, dst, src); } 6451cb0ef41Sopenharmony_ci 6461cb0ef41Sopenharmony_ci void cmpw(Register dst, Register src) { arithmetic_op_16(0x3B, dst, src); } 6471cb0ef41Sopenharmony_ci 6481cb0ef41Sopenharmony_ci void cmpw(Operand dst, Register src) { arithmetic_op_16(0x39, src, dst); } 6491cb0ef41Sopenharmony_ci 6501cb0ef41Sopenharmony_ci void testb(Register reg, Operand op) { testb(op, reg); } 6511cb0ef41Sopenharmony_ci 6521cb0ef41Sopenharmony_ci void testw(Register reg, Operand op) { testw(op, reg); } 6531cb0ef41Sopenharmony_ci 6541cb0ef41Sopenharmony_ci void andb(Register dst, Immediate src) { 6551cb0ef41Sopenharmony_ci immediate_arithmetic_op_8(0x4, dst, src); 6561cb0ef41Sopenharmony_ci } 6571cb0ef41Sopenharmony_ci 6581cb0ef41Sopenharmony_ci void decb(Register dst); 6591cb0ef41Sopenharmony_ci void decb(Operand dst); 6601cb0ef41Sopenharmony_ci 6611cb0ef41Sopenharmony_ci // Lock prefix. 6621cb0ef41Sopenharmony_ci void lock(); 6631cb0ef41Sopenharmony_ci 6641cb0ef41Sopenharmony_ci void xchgb(Register reg, Operand op); 6651cb0ef41Sopenharmony_ci void xchgw(Register reg, Operand op); 6661cb0ef41Sopenharmony_ci 6671cb0ef41Sopenharmony_ci void xaddb(Operand dst, Register src); 6681cb0ef41Sopenharmony_ci void xaddw(Operand dst, Register src); 6691cb0ef41Sopenharmony_ci void xaddl(Operand dst, Register src); 6701cb0ef41Sopenharmony_ci void xaddq(Operand dst, Register src); 6711cb0ef41Sopenharmony_ci 6721cb0ef41Sopenharmony_ci void negb(Register reg); 6731cb0ef41Sopenharmony_ci void negw(Register reg); 6741cb0ef41Sopenharmony_ci void negl(Register reg); 6751cb0ef41Sopenharmony_ci void negq(Register reg); 6761cb0ef41Sopenharmony_ci void negb(Operand op); 6771cb0ef41Sopenharmony_ci void negw(Operand op); 6781cb0ef41Sopenharmony_ci void negl(Operand op); 6791cb0ef41Sopenharmony_ci void negq(Operand op); 6801cb0ef41Sopenharmony_ci 6811cb0ef41Sopenharmony_ci void cmpxchgb(Operand dst, Register src); 6821cb0ef41Sopenharmony_ci void cmpxchgw(Operand dst, Register src); 6831cb0ef41Sopenharmony_ci 6841cb0ef41Sopenharmony_ci // Sign-extends rax into rdx:rax. 6851cb0ef41Sopenharmony_ci void cqo(); 6861cb0ef41Sopenharmony_ci // Sign-extends eax into edx:eax. 6871cb0ef41Sopenharmony_ci void cdq(); 6881cb0ef41Sopenharmony_ci 6891cb0ef41Sopenharmony_ci // Multiply eax by src, put the result in edx:eax. 6901cb0ef41Sopenharmony_ci void mull(Register src); 6911cb0ef41Sopenharmony_ci void mull(Operand src); 6921cb0ef41Sopenharmony_ci // Multiply rax by src, put the result in rdx:rax. 6931cb0ef41Sopenharmony_ci void mulq(Register src); 6941cb0ef41Sopenharmony_ci 6951cb0ef41Sopenharmony_ci#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode) \ 6961cb0ef41Sopenharmony_ci void instruction##l(Register dst, Immediate imm8) { \ 6971cb0ef41Sopenharmony_ci shift(dst, imm8, subcode, kInt32Size); \ 6981cb0ef41Sopenharmony_ci } \ 6991cb0ef41Sopenharmony_ci \ 7001cb0ef41Sopenharmony_ci void instruction##q(Register dst, Immediate imm8) { \ 7011cb0ef41Sopenharmony_ci shift(dst, imm8, subcode, kInt64Size); \ 7021cb0ef41Sopenharmony_ci } \ 7031cb0ef41Sopenharmony_ci \ 7041cb0ef41Sopenharmony_ci void instruction##l(Operand dst, Immediate imm8) { \ 7051cb0ef41Sopenharmony_ci shift(dst, imm8, subcode, kInt32Size); \ 7061cb0ef41Sopenharmony_ci } \ 7071cb0ef41Sopenharmony_ci \ 7081cb0ef41Sopenharmony_ci void instruction##q(Operand dst, Immediate imm8) { \ 7091cb0ef41Sopenharmony_ci shift(dst, imm8, subcode, kInt64Size); \ 7101cb0ef41Sopenharmony_ci } \ 7111cb0ef41Sopenharmony_ci \ 7121cb0ef41Sopenharmony_ci void instruction##l_cl(Register dst) { shift(dst, subcode, kInt32Size); } \ 7131cb0ef41Sopenharmony_ci \ 7141cb0ef41Sopenharmony_ci void instruction##q_cl(Register dst) { shift(dst, subcode, kInt64Size); } \ 7151cb0ef41Sopenharmony_ci \ 7161cb0ef41Sopenharmony_ci void instruction##l_cl(Operand dst) { shift(dst, subcode, kInt32Size); } \ 7171cb0ef41Sopenharmony_ci \ 7181cb0ef41Sopenharmony_ci void instruction##q_cl(Operand dst) { shift(dst, subcode, kInt64Size); } 7191cb0ef41Sopenharmony_ci SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION) 7201cb0ef41Sopenharmony_ci#undef DECLARE_SHIFT_INSTRUCTION 7211cb0ef41Sopenharmony_ci 7221cb0ef41Sopenharmony_ci // Shifts dst:src left by cl bits, affecting only dst. 7231cb0ef41Sopenharmony_ci void shld(Register dst, Register src); 7241cb0ef41Sopenharmony_ci 7251cb0ef41Sopenharmony_ci // Shifts src:dst right by cl bits, affecting only dst. 7261cb0ef41Sopenharmony_ci void shrd(Register dst, Register src); 7271cb0ef41Sopenharmony_ci 7281cb0ef41Sopenharmony_ci void store_rax(Address dst, RelocInfo::Mode mode); 7291cb0ef41Sopenharmony_ci void store_rax(ExternalReference ref); 7301cb0ef41Sopenharmony_ci 7311cb0ef41Sopenharmony_ci void subb(Register dst, Immediate src) { 7321cb0ef41Sopenharmony_ci immediate_arithmetic_op_8(0x5, dst, src); 7331cb0ef41Sopenharmony_ci } 7341cb0ef41Sopenharmony_ci 7351cb0ef41Sopenharmony_ci void sub_sp_32(uint32_t imm); 7361cb0ef41Sopenharmony_ci 7371cb0ef41Sopenharmony_ci void testb(Register dst, Register src); 7381cb0ef41Sopenharmony_ci void testb(Register reg, Immediate mask); 7391cb0ef41Sopenharmony_ci void testb(Operand op, Immediate mask); 7401cb0ef41Sopenharmony_ci void testb(Operand op, Register reg); 7411cb0ef41Sopenharmony_ci 7421cb0ef41Sopenharmony_ci void testw(Register dst, Register src); 7431cb0ef41Sopenharmony_ci void testw(Register reg, Immediate mask); 7441cb0ef41Sopenharmony_ci void testw(Operand op, Immediate mask); 7451cb0ef41Sopenharmony_ci void testw(Operand op, Register reg); 7461cb0ef41Sopenharmony_ci 7471cb0ef41Sopenharmony_ci // Bit operations. 7481cb0ef41Sopenharmony_ci void bswapl(Register dst); 7491cb0ef41Sopenharmony_ci void bswapq(Register dst); 7501cb0ef41Sopenharmony_ci void btq(Operand dst, Register src); 7511cb0ef41Sopenharmony_ci void btsq(Operand dst, Register src); 7521cb0ef41Sopenharmony_ci void btsq(Register dst, Immediate imm8); 7531cb0ef41Sopenharmony_ci void btrq(Register dst, Immediate imm8); 7541cb0ef41Sopenharmony_ci void bsrq(Register dst, Register src); 7551cb0ef41Sopenharmony_ci void bsrq(Register dst, Operand src); 7561cb0ef41Sopenharmony_ci void bsrl(Register dst, Register src); 7571cb0ef41Sopenharmony_ci void bsrl(Register dst, Operand src); 7581cb0ef41Sopenharmony_ci void bsfq(Register dst, Register src); 7591cb0ef41Sopenharmony_ci void bsfq(Register dst, Operand src); 7601cb0ef41Sopenharmony_ci void bsfl(Register dst, Register src); 7611cb0ef41Sopenharmony_ci void bsfl(Register dst, Operand src); 7621cb0ef41Sopenharmony_ci 7631cb0ef41Sopenharmony_ci // Miscellaneous 7641cb0ef41Sopenharmony_ci void clc(); 7651cb0ef41Sopenharmony_ci void cld(); 7661cb0ef41Sopenharmony_ci void cpuid(); 7671cb0ef41Sopenharmony_ci void hlt(); 7681cb0ef41Sopenharmony_ci void int3(); 7691cb0ef41Sopenharmony_ci void nop(); 7701cb0ef41Sopenharmony_ci void ret(int imm16); 7711cb0ef41Sopenharmony_ci void ud2(); 7721cb0ef41Sopenharmony_ci void setcc(Condition cc, Register reg); 7731cb0ef41Sopenharmony_ci 7741cb0ef41Sopenharmony_ci void pblendw(XMMRegister dst, Operand src, uint8_t mask); 7751cb0ef41Sopenharmony_ci void pblendw(XMMRegister dst, XMMRegister src, uint8_t mask); 7761cb0ef41Sopenharmony_ci void palignr(XMMRegister dst, Operand src, uint8_t mask); 7771cb0ef41Sopenharmony_ci void palignr(XMMRegister dst, XMMRegister src, uint8_t mask); 7781cb0ef41Sopenharmony_ci 7791cb0ef41Sopenharmony_ci // Label operations & relative jumps (PPUM Appendix D) 7801cb0ef41Sopenharmony_ci // 7811cb0ef41Sopenharmony_ci // Takes a branch opcode (cc) and a label (L) and generates 7821cb0ef41Sopenharmony_ci // either a backward branch or a forward branch and links it 7831cb0ef41Sopenharmony_ci // to the label fixup chain. Usage: 7841cb0ef41Sopenharmony_ci // 7851cb0ef41Sopenharmony_ci // Label L; // unbound label 7861cb0ef41Sopenharmony_ci // j(cc, &L); // forward branch to unbound label 7871cb0ef41Sopenharmony_ci // bind(&L); // bind label to the current pc 7881cb0ef41Sopenharmony_ci // j(cc, &L); // backward branch to bound label 7891cb0ef41Sopenharmony_ci // bind(&L); // illegal: a label may be bound only once 7901cb0ef41Sopenharmony_ci // 7911cb0ef41Sopenharmony_ci // Note: The same Label can be used for forward and backward branches 7921cb0ef41Sopenharmony_ci // but it may be bound only once. 7931cb0ef41Sopenharmony_ci 7941cb0ef41Sopenharmony_ci void bind(Label* L); // binds an unbound label L to the current code position 7951cb0ef41Sopenharmony_ci 7961cb0ef41Sopenharmony_ci // Calls 7971cb0ef41Sopenharmony_ci // Call near relative 32-bit displacement, relative to next instruction. 7981cb0ef41Sopenharmony_ci void call(Label* L); 7991cb0ef41Sopenharmony_ci void call(Address entry, RelocInfo::Mode rmode); 8001cb0ef41Sopenharmony_ci 8011cb0ef41Sopenharmony_ci // Explicitly emit a near call / near jump. The displacement is relative to 8021cb0ef41Sopenharmony_ci // the next instructions (which starts at {pc_offset() + kNearJmpInstrSize}). 8031cb0ef41Sopenharmony_ci static constexpr int kNearJmpInstrSize = 5; 8041cb0ef41Sopenharmony_ci void near_call(intptr_t disp, RelocInfo::Mode rmode); 8051cb0ef41Sopenharmony_ci void near_jmp(intptr_t disp, RelocInfo::Mode rmode); 8061cb0ef41Sopenharmony_ci 8071cb0ef41Sopenharmony_ci void call(Handle<CodeT> target, 8081cb0ef41Sopenharmony_ci RelocInfo::Mode rmode = RelocInfo::CODE_TARGET); 8091cb0ef41Sopenharmony_ci 8101cb0ef41Sopenharmony_ci // Call near absolute indirect, address in register 8111cb0ef41Sopenharmony_ci void call(Register adr); 8121cb0ef41Sopenharmony_ci 8131cb0ef41Sopenharmony_ci // Jumps 8141cb0ef41Sopenharmony_ci // Jump short or near relative. 8151cb0ef41Sopenharmony_ci // Use a 32-bit signed displacement. 8161cb0ef41Sopenharmony_ci // Unconditional jump to L 8171cb0ef41Sopenharmony_ci void jmp(Label* L, Label::Distance distance = Label::kFar); 8181cb0ef41Sopenharmony_ci void jmp(Handle<CodeT> target, RelocInfo::Mode rmode); 8191cb0ef41Sopenharmony_ci void jmp(Address entry, RelocInfo::Mode rmode); 8201cb0ef41Sopenharmony_ci 8211cb0ef41Sopenharmony_ci // Jump near absolute indirect (r64) 8221cb0ef41Sopenharmony_ci void jmp(Register adr); 8231cb0ef41Sopenharmony_ci void jmp(Operand src); 8241cb0ef41Sopenharmony_ci 8251cb0ef41Sopenharmony_ci // Unconditional jump relative to the current address. Low-level routine, 8261cb0ef41Sopenharmony_ci // use with caution! 8271cb0ef41Sopenharmony_ci void jmp_rel(int offset); 8281cb0ef41Sopenharmony_ci 8291cb0ef41Sopenharmony_ci // Conditional jumps 8301cb0ef41Sopenharmony_ci void j(Condition cc, Label* L, Label::Distance distance = Label::kFar); 8311cb0ef41Sopenharmony_ci void j(Condition cc, Address entry, RelocInfo::Mode rmode); 8321cb0ef41Sopenharmony_ci void j(Condition cc, Handle<CodeT> target, RelocInfo::Mode rmode); 8331cb0ef41Sopenharmony_ci 8341cb0ef41Sopenharmony_ci // Floating-point operations 8351cb0ef41Sopenharmony_ci void fld(int i); 8361cb0ef41Sopenharmony_ci 8371cb0ef41Sopenharmony_ci void fld1(); 8381cb0ef41Sopenharmony_ci void fldz(); 8391cb0ef41Sopenharmony_ci void fldpi(); 8401cb0ef41Sopenharmony_ci void fldln2(); 8411cb0ef41Sopenharmony_ci 8421cb0ef41Sopenharmony_ci void fld_s(Operand adr); 8431cb0ef41Sopenharmony_ci void fld_d(Operand adr); 8441cb0ef41Sopenharmony_ci 8451cb0ef41Sopenharmony_ci void fstp_s(Operand adr); 8461cb0ef41Sopenharmony_ci void fstp_d(Operand adr); 8471cb0ef41Sopenharmony_ci void fstp(int index); 8481cb0ef41Sopenharmony_ci 8491cb0ef41Sopenharmony_ci void fild_s(Operand adr); 8501cb0ef41Sopenharmony_ci void fild_d(Operand adr); 8511cb0ef41Sopenharmony_ci 8521cb0ef41Sopenharmony_ci void fist_s(Operand adr); 8531cb0ef41Sopenharmony_ci 8541cb0ef41Sopenharmony_ci void fistp_s(Operand adr); 8551cb0ef41Sopenharmony_ci void fistp_d(Operand adr); 8561cb0ef41Sopenharmony_ci 8571cb0ef41Sopenharmony_ci void fisttp_s(Operand adr); 8581cb0ef41Sopenharmony_ci void fisttp_d(Operand adr); 8591cb0ef41Sopenharmony_ci 8601cb0ef41Sopenharmony_ci void fabs(); 8611cb0ef41Sopenharmony_ci void fchs(); 8621cb0ef41Sopenharmony_ci 8631cb0ef41Sopenharmony_ci void fadd(int i); 8641cb0ef41Sopenharmony_ci void fsub(int i); 8651cb0ef41Sopenharmony_ci void fmul(int i); 8661cb0ef41Sopenharmony_ci void fdiv(int i); 8671cb0ef41Sopenharmony_ci 8681cb0ef41Sopenharmony_ci void fisub_s(Operand adr); 8691cb0ef41Sopenharmony_ci 8701cb0ef41Sopenharmony_ci void faddp(int i = 1); 8711cb0ef41Sopenharmony_ci void fsubp(int i = 1); 8721cb0ef41Sopenharmony_ci void fsubrp(int i = 1); 8731cb0ef41Sopenharmony_ci void fmulp(int i = 1); 8741cb0ef41Sopenharmony_ci void fdivp(int i = 1); 8751cb0ef41Sopenharmony_ci void fprem(); 8761cb0ef41Sopenharmony_ci void fprem1(); 8771cb0ef41Sopenharmony_ci 8781cb0ef41Sopenharmony_ci void fxch(int i = 1); 8791cb0ef41Sopenharmony_ci void fincstp(); 8801cb0ef41Sopenharmony_ci void ffree(int i = 0); 8811cb0ef41Sopenharmony_ci 8821cb0ef41Sopenharmony_ci void ftst(); 8831cb0ef41Sopenharmony_ci void fucomp(int i); 8841cb0ef41Sopenharmony_ci void fucompp(); 8851cb0ef41Sopenharmony_ci void fucomi(int i); 8861cb0ef41Sopenharmony_ci void fucomip(); 8871cb0ef41Sopenharmony_ci 8881cb0ef41Sopenharmony_ci void fcompp(); 8891cb0ef41Sopenharmony_ci void fnstsw_ax(); 8901cb0ef41Sopenharmony_ci void fwait(); 8911cb0ef41Sopenharmony_ci void fnclex(); 8921cb0ef41Sopenharmony_ci 8931cb0ef41Sopenharmony_ci void fsin(); 8941cb0ef41Sopenharmony_ci void fcos(); 8951cb0ef41Sopenharmony_ci void fptan(); 8961cb0ef41Sopenharmony_ci void fyl2x(); 8971cb0ef41Sopenharmony_ci void f2xm1(); 8981cb0ef41Sopenharmony_ci void fscale(); 8991cb0ef41Sopenharmony_ci void fninit(); 9001cb0ef41Sopenharmony_ci 9011cb0ef41Sopenharmony_ci void frndint(); 9021cb0ef41Sopenharmony_ci 9031cb0ef41Sopenharmony_ci void sahf(); 9041cb0ef41Sopenharmony_ci 9051cb0ef41Sopenharmony_ci void ucomiss(XMMRegister dst, XMMRegister src); 9061cb0ef41Sopenharmony_ci void ucomiss(XMMRegister dst, Operand src); 9071cb0ef41Sopenharmony_ci void movaps(XMMRegister dst, XMMRegister src); 9081cb0ef41Sopenharmony_ci void movaps(XMMRegister dst, Operand src); 9091cb0ef41Sopenharmony_ci 9101cb0ef41Sopenharmony_ci // Don't use this unless it's important to keep the 9111cb0ef41Sopenharmony_ci // top half of the destination register unchanged. 9121cb0ef41Sopenharmony_ci // Use movaps when moving float values and movd for integer 9131cb0ef41Sopenharmony_ci // values in xmm registers. 9141cb0ef41Sopenharmony_ci void movss(XMMRegister dst, XMMRegister src); 9151cb0ef41Sopenharmony_ci 9161cb0ef41Sopenharmony_ci void movss(XMMRegister dst, Operand src); 9171cb0ef41Sopenharmony_ci void movss(Operand dst, XMMRegister src); 9181cb0ef41Sopenharmony_ci 9191cb0ef41Sopenharmony_ci void movlps(XMMRegister dst, Operand src); 9201cb0ef41Sopenharmony_ci void movlps(Operand dst, XMMRegister src); 9211cb0ef41Sopenharmony_ci 9221cb0ef41Sopenharmony_ci void movhps(XMMRegister dst, Operand src); 9231cb0ef41Sopenharmony_ci void movhps(Operand dst, XMMRegister src); 9241cb0ef41Sopenharmony_ci 9251cb0ef41Sopenharmony_ci void shufps(XMMRegister dst, XMMRegister src, byte imm8); 9261cb0ef41Sopenharmony_ci 9271cb0ef41Sopenharmony_ci void cvttss2si(Register dst, Operand src); 9281cb0ef41Sopenharmony_ci void cvttss2si(Register dst, XMMRegister src); 9291cb0ef41Sopenharmony_ci void cvtlsi2ss(XMMRegister dst, Operand src); 9301cb0ef41Sopenharmony_ci void cvtlsi2ss(XMMRegister dst, Register src); 9311cb0ef41Sopenharmony_ci 9321cb0ef41Sopenharmony_ci void movmskps(Register dst, XMMRegister src); 9331cb0ef41Sopenharmony_ci 9341cb0ef41Sopenharmony_ci void vinstr(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2, 9351cb0ef41Sopenharmony_ci SIMDPrefix pp, LeadingOpcode m, VexW w, CpuFeature feature = AVX); 9361cb0ef41Sopenharmony_ci void vinstr(byte op, XMMRegister dst, XMMRegister src1, Operand src2, 9371cb0ef41Sopenharmony_ci SIMDPrefix pp, LeadingOpcode m, VexW w, CpuFeature feature = AVX); 9381cb0ef41Sopenharmony_ci 9391cb0ef41Sopenharmony_ci template <typename Reg1, typename Reg2, typename Op> 9401cb0ef41Sopenharmony_ci void vinstr(byte op, Reg1 dst, Reg2 src1, Op src2, SIMDPrefix pp, 9411cb0ef41Sopenharmony_ci LeadingOpcode m, VexW w, CpuFeature feature = AVX2); 9421cb0ef41Sopenharmony_ci 9431cb0ef41Sopenharmony_ci // SSE instructions 9441cb0ef41Sopenharmony_ci void sse_instr(XMMRegister dst, XMMRegister src, byte escape, byte opcode); 9451cb0ef41Sopenharmony_ci void sse_instr(XMMRegister dst, Operand src, byte escape, byte opcode); 9461cb0ef41Sopenharmony_ci#define DECLARE_SSE_INSTRUCTION(instruction, escape, opcode) \ 9471cb0ef41Sopenharmony_ci void instruction(XMMRegister dst, XMMRegister src) { \ 9481cb0ef41Sopenharmony_ci sse_instr(dst, src, 0x##escape, 0x##opcode); \ 9491cb0ef41Sopenharmony_ci } \ 9501cb0ef41Sopenharmony_ci void instruction(XMMRegister dst, Operand src) { \ 9511cb0ef41Sopenharmony_ci sse_instr(dst, src, 0x##escape, 0x##opcode); \ 9521cb0ef41Sopenharmony_ci } 9531cb0ef41Sopenharmony_ci 9541cb0ef41Sopenharmony_ci SSE_UNOP_INSTRUCTION_LIST(DECLARE_SSE_INSTRUCTION) 9551cb0ef41Sopenharmony_ci SSE_BINOP_INSTRUCTION_LIST(DECLARE_SSE_INSTRUCTION) 9561cb0ef41Sopenharmony_ci#undef DECLARE_SSE_INSTRUCTION 9571cb0ef41Sopenharmony_ci 9581cb0ef41Sopenharmony_ci // SSE instructions with prefix and SSE2 instructions 9591cb0ef41Sopenharmony_ci void sse2_instr(XMMRegister dst, XMMRegister src, byte prefix, byte escape, 9601cb0ef41Sopenharmony_ci byte opcode); 9611cb0ef41Sopenharmony_ci void sse2_instr(XMMRegister dst, Operand src, byte prefix, byte escape, 9621cb0ef41Sopenharmony_ci byte opcode); 9631cb0ef41Sopenharmony_ci#define DECLARE_SSE2_INSTRUCTION(instruction, prefix, escape, opcode) \ 9641cb0ef41Sopenharmony_ci void instruction(XMMRegister dst, XMMRegister src) { \ 9651cb0ef41Sopenharmony_ci sse2_instr(dst, src, 0x##prefix, 0x##escape, 0x##opcode); \ 9661cb0ef41Sopenharmony_ci } \ 9671cb0ef41Sopenharmony_ci void instruction(XMMRegister dst, Operand src) { \ 9681cb0ef41Sopenharmony_ci sse2_instr(dst, src, 0x##prefix, 0x##escape, 0x##opcode); \ 9691cb0ef41Sopenharmony_ci } 9701cb0ef41Sopenharmony_ci 9711cb0ef41Sopenharmony_ci // These SSE instructions have the same encoding as the SSE2 instructions. 9721cb0ef41Sopenharmony_ci SSE_INSTRUCTION_LIST_SS(DECLARE_SSE2_INSTRUCTION) 9731cb0ef41Sopenharmony_ci SSE2_INSTRUCTION_LIST(DECLARE_SSE2_INSTRUCTION) 9741cb0ef41Sopenharmony_ci SSE2_INSTRUCTION_LIST_SD(DECLARE_SSE2_INSTRUCTION) 9751cb0ef41Sopenharmony_ci SSE2_UNOP_INSTRUCTION_LIST(DECLARE_SSE2_INSTRUCTION) 9761cb0ef41Sopenharmony_ci#undef DECLARE_SSE2_INSTRUCTION 9771cb0ef41Sopenharmony_ci 9781cb0ef41Sopenharmony_ci void sse2_instr(XMMRegister reg, byte imm8, byte prefix, byte escape, 9791cb0ef41Sopenharmony_ci byte opcode, int extension) { 9801cb0ef41Sopenharmony_ci XMMRegister ext_reg = XMMRegister::from_code(extension); 9811cb0ef41Sopenharmony_ci sse2_instr(ext_reg, reg, prefix, escape, opcode); 9821cb0ef41Sopenharmony_ci emit(imm8); 9831cb0ef41Sopenharmony_ci } 9841cb0ef41Sopenharmony_ci 9851cb0ef41Sopenharmony_ci#define DECLARE_SSE2_SHIFT_IMM(instruction, prefix, escape, opcode, extension) \ 9861cb0ef41Sopenharmony_ci void instruction(XMMRegister reg, byte imm8) { \ 9871cb0ef41Sopenharmony_ci sse2_instr(reg, imm8, 0x##prefix, 0x##escape, 0x##opcode, 0x##extension); \ 9881cb0ef41Sopenharmony_ci } 9891cb0ef41Sopenharmony_ci SSE2_INSTRUCTION_LIST_SHIFT_IMM(DECLARE_SSE2_SHIFT_IMM) 9901cb0ef41Sopenharmony_ci#undef DECLARE_SSE2_SHIFT_IMM 9911cb0ef41Sopenharmony_ci 9921cb0ef41Sopenharmony_ci#define DECLARE_SSE2_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \ 9931cb0ef41Sopenharmony_ci void v##instruction(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ 9941cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0); \ 9951cb0ef41Sopenharmony_ci } \ 9961cb0ef41Sopenharmony_ci void v##instruction(XMMRegister dst, XMMRegister src1, Operand src2) { \ 9971cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0); \ 9981cb0ef41Sopenharmony_ci } 9991cb0ef41Sopenharmony_ci 10001cb0ef41Sopenharmony_ci#define DECLARE_SSE2_PD_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \ 10011cb0ef41Sopenharmony_ci DECLARE_SSE2_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \ 10021cb0ef41Sopenharmony_ci void v##instruction(YMMRegister dst, YMMRegister src1, YMMRegister src2) { \ 10031cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0, AVX); \ 10041cb0ef41Sopenharmony_ci } \ 10051cb0ef41Sopenharmony_ci void v##instruction(YMMRegister dst, YMMRegister src1, Operand src2) { \ 10061cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0, AVX); \ 10071cb0ef41Sopenharmony_ci } 10081cb0ef41Sopenharmony_ci 10091cb0ef41Sopenharmony_ci SSE2_INSTRUCTION_LIST_PD(DECLARE_SSE2_PD_AVX_INSTRUCTION) 10101cb0ef41Sopenharmony_ci#undef DECLARE_SSE2_PD_AVX_INSTRUCTION 10111cb0ef41Sopenharmony_ci 10121cb0ef41Sopenharmony_ci#define DECLARE_SSE2_PI_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \ 10131cb0ef41Sopenharmony_ci DECLARE_SSE2_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \ 10141cb0ef41Sopenharmony_ci void v##instruction(YMMRegister dst, YMMRegister src1, YMMRegister src2) { \ 10151cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0, AVX2); \ 10161cb0ef41Sopenharmony_ci } \ 10171cb0ef41Sopenharmony_ci void v##instruction(YMMRegister dst, YMMRegister src1, Operand src2) { \ 10181cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0, AVX2); \ 10191cb0ef41Sopenharmony_ci } 10201cb0ef41Sopenharmony_ci 10211cb0ef41Sopenharmony_ci SSE2_INSTRUCTION_LIST_PI(DECLARE_SSE2_PI_AVX_INSTRUCTION) 10221cb0ef41Sopenharmony_ci#undef DECLARE_SSE2_PI_AVX_INSTRUCTION 10231cb0ef41Sopenharmony_ci 10241cb0ef41Sopenharmony_ci#define DECLARE_SSE2_SHIFT_AVX_INSTRUCTION(instruction, prefix, escape, \ 10251cb0ef41Sopenharmony_ci opcode) \ 10261cb0ef41Sopenharmony_ci DECLARE_SSE2_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \ 10271cb0ef41Sopenharmony_ci void v##instruction(YMMRegister dst, YMMRegister src1, XMMRegister src2) { \ 10281cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0, AVX2); \ 10291cb0ef41Sopenharmony_ci } \ 10301cb0ef41Sopenharmony_ci void v##instruction(YMMRegister dst, YMMRegister src1, Operand src2) { \ 10311cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0, AVX2); \ 10321cb0ef41Sopenharmony_ci } 10331cb0ef41Sopenharmony_ci 10341cb0ef41Sopenharmony_ci SSE2_INSTRUCTION_LIST_SHIFT(DECLARE_SSE2_SHIFT_AVX_INSTRUCTION) 10351cb0ef41Sopenharmony_ci#undef DECLARE_SSE2_SHIFT_AVX_INSTRUCTION 10361cb0ef41Sopenharmony_ci#undef DECLARE_SSE2_AVX_INSTRUCTION 10371cb0ef41Sopenharmony_ci 10381cb0ef41Sopenharmony_ci#define DECLARE_SSE2_UNOP_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \ 10391cb0ef41Sopenharmony_ci void v##instruction(XMMRegister dst, XMMRegister src) { \ 10401cb0ef41Sopenharmony_ci vpd(0x##opcode, dst, xmm0, src); \ 10411cb0ef41Sopenharmony_ci } \ 10421cb0ef41Sopenharmony_ci void v##instruction(XMMRegister dst, Operand src) { \ 10431cb0ef41Sopenharmony_ci vpd(0x##opcode, dst, xmm0, src); \ 10441cb0ef41Sopenharmony_ci } 10451cb0ef41Sopenharmony_ci 10461cb0ef41Sopenharmony_ci SSE2_UNOP_INSTRUCTION_LIST(DECLARE_SSE2_UNOP_AVX_INSTRUCTION) 10471cb0ef41Sopenharmony_ci#undef DECLARE_SSE2_UNOP_AVX_INSTRUCTION 10481cb0ef41Sopenharmony_ci 10491cb0ef41Sopenharmony_ci // SSE3 10501cb0ef41Sopenharmony_ci void lddqu(XMMRegister dst, Operand src); 10511cb0ef41Sopenharmony_ci void movddup(XMMRegister dst, Operand src); 10521cb0ef41Sopenharmony_ci void movddup(XMMRegister dst, XMMRegister src); 10531cb0ef41Sopenharmony_ci void movshdup(XMMRegister dst, XMMRegister src); 10541cb0ef41Sopenharmony_ci 10551cb0ef41Sopenharmony_ci // SSSE3 10561cb0ef41Sopenharmony_ci void ssse3_instr(XMMRegister dst, XMMRegister src, byte prefix, byte escape1, 10571cb0ef41Sopenharmony_ci byte escape2, byte opcode); 10581cb0ef41Sopenharmony_ci void ssse3_instr(XMMRegister dst, Operand src, byte prefix, byte escape1, 10591cb0ef41Sopenharmony_ci byte escape2, byte opcode); 10601cb0ef41Sopenharmony_ci 10611cb0ef41Sopenharmony_ci#define DECLARE_SSSE3_INSTRUCTION(instruction, prefix, escape1, escape2, \ 10621cb0ef41Sopenharmony_ci opcode) \ 10631cb0ef41Sopenharmony_ci void instruction(XMMRegister dst, XMMRegister src) { \ 10641cb0ef41Sopenharmony_ci ssse3_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \ 10651cb0ef41Sopenharmony_ci } \ 10661cb0ef41Sopenharmony_ci void instruction(XMMRegister dst, Operand src) { \ 10671cb0ef41Sopenharmony_ci ssse3_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \ 10681cb0ef41Sopenharmony_ci } 10691cb0ef41Sopenharmony_ci 10701cb0ef41Sopenharmony_ci SSSE3_INSTRUCTION_LIST(DECLARE_SSSE3_INSTRUCTION) 10711cb0ef41Sopenharmony_ci SSSE3_UNOP_INSTRUCTION_LIST(DECLARE_SSSE3_INSTRUCTION) 10721cb0ef41Sopenharmony_ci#undef DECLARE_SSSE3_INSTRUCTION 10731cb0ef41Sopenharmony_ci 10741cb0ef41Sopenharmony_ci // SSE4 10751cb0ef41Sopenharmony_ci void sse4_instr(Register dst, XMMRegister src, byte prefix, byte escape1, 10761cb0ef41Sopenharmony_ci byte escape2, byte opcode, int8_t imm8); 10771cb0ef41Sopenharmony_ci void sse4_instr(Operand dst, XMMRegister src, byte prefix, byte escape1, 10781cb0ef41Sopenharmony_ci byte escape2, byte opcode, int8_t imm8); 10791cb0ef41Sopenharmony_ci void sse4_instr(XMMRegister dst, Register src, byte prefix, byte escape1, 10801cb0ef41Sopenharmony_ci byte escape2, byte opcode, int8_t imm8); 10811cb0ef41Sopenharmony_ci void sse4_instr(XMMRegister dst, XMMRegister src, byte prefix, byte escape1, 10821cb0ef41Sopenharmony_ci byte escape2, byte opcode); 10831cb0ef41Sopenharmony_ci void sse4_instr(XMMRegister dst, Operand src, byte prefix, byte escape1, 10841cb0ef41Sopenharmony_ci byte escape2, byte opcode); 10851cb0ef41Sopenharmony_ci#define DECLARE_SSE4_INSTRUCTION(instruction, prefix, escape1, escape2, \ 10861cb0ef41Sopenharmony_ci opcode) \ 10871cb0ef41Sopenharmony_ci void instruction(XMMRegister dst, XMMRegister src) { \ 10881cb0ef41Sopenharmony_ci sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \ 10891cb0ef41Sopenharmony_ci } \ 10901cb0ef41Sopenharmony_ci void instruction(XMMRegister dst, Operand src) { \ 10911cb0ef41Sopenharmony_ci sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \ 10921cb0ef41Sopenharmony_ci } 10931cb0ef41Sopenharmony_ci 10941cb0ef41Sopenharmony_ci SSE4_INSTRUCTION_LIST(DECLARE_SSE4_INSTRUCTION) 10951cb0ef41Sopenharmony_ci SSE4_UNOP_INSTRUCTION_LIST(DECLARE_SSE4_INSTRUCTION) 10961cb0ef41Sopenharmony_ci DECLARE_SSE4_INSTRUCTION(pblendvb, 66, 0F, 38, 10) 10971cb0ef41Sopenharmony_ci DECLARE_SSE4_INSTRUCTION(blendvps, 66, 0F, 38, 14) 10981cb0ef41Sopenharmony_ci DECLARE_SSE4_INSTRUCTION(blendvpd, 66, 0F, 38, 15) 10991cb0ef41Sopenharmony_ci#undef DECLARE_SSE4_INSTRUCTION 11001cb0ef41Sopenharmony_ci 11011cb0ef41Sopenharmony_ci#define DECLARE_SSE4_EXTRACT_INSTRUCTION(instruction, prefix, escape1, \ 11021cb0ef41Sopenharmony_ci escape2, opcode) \ 11031cb0ef41Sopenharmony_ci void instruction(Register dst, XMMRegister src, uint8_t imm8) { \ 11041cb0ef41Sopenharmony_ci sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode, \ 11051cb0ef41Sopenharmony_ci imm8); \ 11061cb0ef41Sopenharmony_ci } \ 11071cb0ef41Sopenharmony_ci void instruction(Operand dst, XMMRegister src, uint8_t imm8) { \ 11081cb0ef41Sopenharmony_ci sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode, \ 11091cb0ef41Sopenharmony_ci imm8); \ 11101cb0ef41Sopenharmony_ci } 11111cb0ef41Sopenharmony_ci 11121cb0ef41Sopenharmony_ci SSE4_EXTRACT_INSTRUCTION_LIST(DECLARE_SSE4_EXTRACT_INSTRUCTION) 11131cb0ef41Sopenharmony_ci#undef DECLARE_SSE4_EXTRACT_INSTRUCTION 11141cb0ef41Sopenharmony_ci 11151cb0ef41Sopenharmony_ci // SSE4.2 11161cb0ef41Sopenharmony_ci void sse4_2_instr(XMMRegister dst, XMMRegister src, byte prefix, byte escape1, 11171cb0ef41Sopenharmony_ci byte escape2, byte opcode); 11181cb0ef41Sopenharmony_ci void sse4_2_instr(XMMRegister dst, Operand src, byte prefix, byte escape1, 11191cb0ef41Sopenharmony_ci byte escape2, byte opcode); 11201cb0ef41Sopenharmony_ci#define DECLARE_SSE4_2_INSTRUCTION(instruction, prefix, escape1, escape2, \ 11211cb0ef41Sopenharmony_ci opcode) \ 11221cb0ef41Sopenharmony_ci void instruction(XMMRegister dst, XMMRegister src) { \ 11231cb0ef41Sopenharmony_ci sse4_2_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \ 11241cb0ef41Sopenharmony_ci } \ 11251cb0ef41Sopenharmony_ci void instruction(XMMRegister dst, Operand src) { \ 11261cb0ef41Sopenharmony_ci sse4_2_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \ 11271cb0ef41Sopenharmony_ci } 11281cb0ef41Sopenharmony_ci 11291cb0ef41Sopenharmony_ci SSE4_2_INSTRUCTION_LIST(DECLARE_SSE4_2_INSTRUCTION) 11301cb0ef41Sopenharmony_ci#undef DECLARE_SSE4_2_INSTRUCTION 11311cb0ef41Sopenharmony_ci 11321cb0ef41Sopenharmony_ci#define DECLARE_SSE34_AVX_INSTRUCTION(instruction, prefix, escape1, escape2, \ 11331cb0ef41Sopenharmony_ci opcode) \ 11341cb0ef41Sopenharmony_ci void v##instruction(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ 11351cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0); \ 11361cb0ef41Sopenharmony_ci } \ 11371cb0ef41Sopenharmony_ci void v##instruction(XMMRegister dst, XMMRegister src1, Operand src2) { \ 11381cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0); \ 11391cb0ef41Sopenharmony_ci } \ 11401cb0ef41Sopenharmony_ci void v##instruction(YMMRegister dst, YMMRegister src1, YMMRegister src2) { \ 11411cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0, \ 11421cb0ef41Sopenharmony_ci AVX2); \ 11431cb0ef41Sopenharmony_ci } \ 11441cb0ef41Sopenharmony_ci void v##instruction(YMMRegister dst, YMMRegister src1, Operand src2) { \ 11451cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0, \ 11461cb0ef41Sopenharmony_ci AVX2); \ 11471cb0ef41Sopenharmony_ci } 11481cb0ef41Sopenharmony_ci 11491cb0ef41Sopenharmony_ci SSSE3_INSTRUCTION_LIST(DECLARE_SSE34_AVX_INSTRUCTION) 11501cb0ef41Sopenharmony_ci SSE4_INSTRUCTION_LIST(DECLARE_SSE34_AVX_INSTRUCTION) 11511cb0ef41Sopenharmony_ci SSE4_2_INSTRUCTION_LIST(DECLARE_SSE34_AVX_INSTRUCTION) 11521cb0ef41Sopenharmony_ci#undef DECLARE_SSE34_AVX_INSTRUCTION 11531cb0ef41Sopenharmony_ci 11541cb0ef41Sopenharmony_ci#define DECLARE_SSSE3_UNOP_AVX_INSTRUCTION(instruction, prefix, escape1, \ 11551cb0ef41Sopenharmony_ci escape2, opcode) \ 11561cb0ef41Sopenharmony_ci void v##instruction(XMMRegister dst, XMMRegister src) { \ 11571cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0); \ 11581cb0ef41Sopenharmony_ci } \ 11591cb0ef41Sopenharmony_ci void v##instruction(XMMRegister dst, Operand src) { \ 11601cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0); \ 11611cb0ef41Sopenharmony_ci } \ 11621cb0ef41Sopenharmony_ci void v##instruction(YMMRegister dst, YMMRegister src) { \ 11631cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, ymm0, src, k##prefix, k##escape1##escape2, kW0); \ 11641cb0ef41Sopenharmony_ci } \ 11651cb0ef41Sopenharmony_ci void v##instruction(YMMRegister dst, Operand src) { \ 11661cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, ymm0, src, k##prefix, k##escape1##escape2, kW0); \ 11671cb0ef41Sopenharmony_ci } 11681cb0ef41Sopenharmony_ci 11691cb0ef41Sopenharmony_ci SSSE3_UNOP_INSTRUCTION_LIST(DECLARE_SSSE3_UNOP_AVX_INSTRUCTION) 11701cb0ef41Sopenharmony_ci#undef DECLARE_SSSE3_UNOP_AVX_INSTRUCTION 11711cb0ef41Sopenharmony_ci 11721cb0ef41Sopenharmony_ci void vpblendvb(XMMRegister dst, XMMRegister src1, XMMRegister src2, 11731cb0ef41Sopenharmony_ci XMMRegister mask) { 11741cb0ef41Sopenharmony_ci vinstr(0x4C, dst, src1, src2, k66, k0F3A, kW0); 11751cb0ef41Sopenharmony_ci // The mask operand is encoded in bits[7:4] of the immediate byte. 11761cb0ef41Sopenharmony_ci emit(mask.code() << 4); 11771cb0ef41Sopenharmony_ci } 11781cb0ef41Sopenharmony_ci void vpblendvb(YMMRegister dst, YMMRegister src1, YMMRegister src2, 11791cb0ef41Sopenharmony_ci YMMRegister mask) { 11801cb0ef41Sopenharmony_ci vinstr(0x4C, dst, src1, src2, k66, k0F3A, kW0, AVX2); 11811cb0ef41Sopenharmony_ci // The mask operand is encoded in bits[7:4] of the immediate byte. 11821cb0ef41Sopenharmony_ci emit(mask.code() << 4); 11831cb0ef41Sopenharmony_ci } 11841cb0ef41Sopenharmony_ci 11851cb0ef41Sopenharmony_ci void vblendvps(XMMRegister dst, XMMRegister src1, XMMRegister src2, 11861cb0ef41Sopenharmony_ci XMMRegister mask) { 11871cb0ef41Sopenharmony_ci vinstr(0x4A, dst, src1, src2, k66, k0F3A, kW0); 11881cb0ef41Sopenharmony_ci // The mask operand is encoded in bits[7:4] of the immediate byte. 11891cb0ef41Sopenharmony_ci emit(mask.code() << 4); 11901cb0ef41Sopenharmony_ci } 11911cb0ef41Sopenharmony_ci void vblendvps(YMMRegister dst, YMMRegister src1, YMMRegister src2, 11921cb0ef41Sopenharmony_ci YMMRegister mask) { 11931cb0ef41Sopenharmony_ci vinstr(0x4A, dst, src1, src2, k66, k0F3A, kW0, AVX); 11941cb0ef41Sopenharmony_ci // The mask operand is encoded in bits[7:4] of the immediate byte. 11951cb0ef41Sopenharmony_ci emit(mask.code() << 4); 11961cb0ef41Sopenharmony_ci } 11971cb0ef41Sopenharmony_ci 11981cb0ef41Sopenharmony_ci void vblendvpd(XMMRegister dst, XMMRegister src1, XMMRegister src2, 11991cb0ef41Sopenharmony_ci XMMRegister mask) { 12001cb0ef41Sopenharmony_ci vinstr(0x4B, dst, src1, src2, k66, k0F3A, kW0); 12011cb0ef41Sopenharmony_ci // The mask operand is encoded in bits[7:4] of the immediate byte. 12021cb0ef41Sopenharmony_ci emit(mask.code() << 4); 12031cb0ef41Sopenharmony_ci } 12041cb0ef41Sopenharmony_ci void vblendvpd(YMMRegister dst, YMMRegister src1, YMMRegister src2, 12051cb0ef41Sopenharmony_ci YMMRegister mask) { 12061cb0ef41Sopenharmony_ci vinstr(0x4B, dst, src1, src2, k66, k0F3A, kW0, AVX); 12071cb0ef41Sopenharmony_ci // The mask operand is encoded in bits[7:4] of the immediate byte. 12081cb0ef41Sopenharmony_ci emit(mask.code() << 4); 12091cb0ef41Sopenharmony_ci } 12101cb0ef41Sopenharmony_ci 12111cb0ef41Sopenharmony_ci#define DECLARE_SSE4_PMOV_AVX_INSTRUCTION(instruction, prefix, escape1, \ 12121cb0ef41Sopenharmony_ci escape2, opcode) \ 12131cb0ef41Sopenharmony_ci void v##instruction(XMMRegister dst, XMMRegister src) { \ 12141cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0); \ 12151cb0ef41Sopenharmony_ci } \ 12161cb0ef41Sopenharmony_ci void v##instruction(XMMRegister dst, Operand src) { \ 12171cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0); \ 12181cb0ef41Sopenharmony_ci } 12191cb0ef41Sopenharmony_ci SSE4_UNOP_INSTRUCTION_LIST(DECLARE_SSE4_PMOV_AVX_INSTRUCTION) 12201cb0ef41Sopenharmony_ci#undef DECLARE_SSE4_PMOV_AVX_INSTRUCTION 12211cb0ef41Sopenharmony_ci 12221cb0ef41Sopenharmony_ci#define DECLARE_AVX_INSTRUCTION(instruction, prefix, escape1, escape2, opcode) \ 12231cb0ef41Sopenharmony_ci void v##instruction(Register dst, XMMRegister src, uint8_t imm8) { \ 12241cb0ef41Sopenharmony_ci XMMRegister idst = XMMRegister::from_code(dst.code()); \ 12251cb0ef41Sopenharmony_ci vinstr(0x##opcode, src, xmm0, idst, k##prefix, k##escape1##escape2, kW0); \ 12261cb0ef41Sopenharmony_ci emit(imm8); \ 12271cb0ef41Sopenharmony_ci } \ 12281cb0ef41Sopenharmony_ci void v##instruction(Operand dst, XMMRegister src, uint8_t imm8) { \ 12291cb0ef41Sopenharmony_ci vinstr(0x##opcode, src, xmm0, dst, k##prefix, k##escape1##escape2, kW0); \ 12301cb0ef41Sopenharmony_ci emit(imm8); \ 12311cb0ef41Sopenharmony_ci } 12321cb0ef41Sopenharmony_ci 12331cb0ef41Sopenharmony_ci SSE4_EXTRACT_INSTRUCTION_LIST(DECLARE_AVX_INSTRUCTION) 12341cb0ef41Sopenharmony_ci#undef DECLARE_AVX_INSTRUCTION 12351cb0ef41Sopenharmony_ci 12361cb0ef41Sopenharmony_ci void movd(XMMRegister dst, Register src); 12371cb0ef41Sopenharmony_ci void movd(XMMRegister dst, Operand src); 12381cb0ef41Sopenharmony_ci void movd(Register dst, XMMRegister src); 12391cb0ef41Sopenharmony_ci void movq(XMMRegister dst, Register src); 12401cb0ef41Sopenharmony_ci void movq(XMMRegister dst, Operand src); 12411cb0ef41Sopenharmony_ci void movq(Register dst, XMMRegister src); 12421cb0ef41Sopenharmony_ci void movq(XMMRegister dst, XMMRegister src); 12431cb0ef41Sopenharmony_ci 12441cb0ef41Sopenharmony_ci // Don't use this unless it's important to keep the 12451cb0ef41Sopenharmony_ci // top half of the destination register unchanged. 12461cb0ef41Sopenharmony_ci // Use movapd when moving double values and movq for integer 12471cb0ef41Sopenharmony_ci // values in xmm registers. 12481cb0ef41Sopenharmony_ci void movsd(XMMRegister dst, XMMRegister src); 12491cb0ef41Sopenharmony_ci 12501cb0ef41Sopenharmony_ci void movsd(Operand dst, XMMRegister src); 12511cb0ef41Sopenharmony_ci void movsd(XMMRegister dst, Operand src); 12521cb0ef41Sopenharmony_ci 12531cb0ef41Sopenharmony_ci void movdqa(Operand dst, XMMRegister src); 12541cb0ef41Sopenharmony_ci void movdqa(XMMRegister dst, Operand src); 12551cb0ef41Sopenharmony_ci void movdqa(XMMRegister dst, XMMRegister src); 12561cb0ef41Sopenharmony_ci 12571cb0ef41Sopenharmony_ci void movdqu(Operand dst, XMMRegister src); 12581cb0ef41Sopenharmony_ci void movdqu(XMMRegister dst, Operand src); 12591cb0ef41Sopenharmony_ci void movdqu(XMMRegister dst, XMMRegister src); 12601cb0ef41Sopenharmony_ci 12611cb0ef41Sopenharmony_ci void movapd(XMMRegister dst, XMMRegister src); 12621cb0ef41Sopenharmony_ci void movupd(XMMRegister dst, Operand src); 12631cb0ef41Sopenharmony_ci void movupd(Operand dst, XMMRegister src); 12641cb0ef41Sopenharmony_ci 12651cb0ef41Sopenharmony_ci void cvtdq2pd(XMMRegister dst, XMMRegister src); 12661cb0ef41Sopenharmony_ci 12671cb0ef41Sopenharmony_ci void cvttsd2si(Register dst, Operand src); 12681cb0ef41Sopenharmony_ci void cvttsd2si(Register dst, XMMRegister src); 12691cb0ef41Sopenharmony_ci void cvttss2siq(Register dst, XMMRegister src); 12701cb0ef41Sopenharmony_ci void cvttss2siq(Register dst, Operand src); 12711cb0ef41Sopenharmony_ci void cvttsd2siq(Register dst, XMMRegister src); 12721cb0ef41Sopenharmony_ci void cvttsd2siq(Register dst, Operand src); 12731cb0ef41Sopenharmony_ci void cvttps2dq(XMMRegister dst, Operand src); 12741cb0ef41Sopenharmony_ci void cvttps2dq(XMMRegister dst, XMMRegister src); 12751cb0ef41Sopenharmony_ci 12761cb0ef41Sopenharmony_ci void cvtlsi2sd(XMMRegister dst, Operand src); 12771cb0ef41Sopenharmony_ci void cvtlsi2sd(XMMRegister dst, Register src); 12781cb0ef41Sopenharmony_ci 12791cb0ef41Sopenharmony_ci void cvtqsi2ss(XMMRegister dst, Operand src); 12801cb0ef41Sopenharmony_ci void cvtqsi2ss(XMMRegister dst, Register src); 12811cb0ef41Sopenharmony_ci 12821cb0ef41Sopenharmony_ci void cvtqsi2sd(XMMRegister dst, Operand src); 12831cb0ef41Sopenharmony_ci void cvtqsi2sd(XMMRegister dst, Register src); 12841cb0ef41Sopenharmony_ci 12851cb0ef41Sopenharmony_ci void cvtsd2si(Register dst, XMMRegister src); 12861cb0ef41Sopenharmony_ci void cvtsd2siq(Register dst, XMMRegister src); 12871cb0ef41Sopenharmony_ci 12881cb0ef41Sopenharmony_ci void haddps(XMMRegister dst, XMMRegister src); 12891cb0ef41Sopenharmony_ci void haddps(XMMRegister dst, Operand src); 12901cb0ef41Sopenharmony_ci 12911cb0ef41Sopenharmony_ci void cmpeqsd(XMMRegister dst, XMMRegister src); 12921cb0ef41Sopenharmony_ci void cmpeqss(XMMRegister dst, XMMRegister src); 12931cb0ef41Sopenharmony_ci void cmpltsd(XMMRegister dst, XMMRegister src); 12941cb0ef41Sopenharmony_ci 12951cb0ef41Sopenharmony_ci void movmskpd(Register dst, XMMRegister src); 12961cb0ef41Sopenharmony_ci 12971cb0ef41Sopenharmony_ci void pmovmskb(Register dst, XMMRegister src); 12981cb0ef41Sopenharmony_ci 12991cb0ef41Sopenharmony_ci void pinsrw(XMMRegister dst, Register src, uint8_t imm8); 13001cb0ef41Sopenharmony_ci void pinsrw(XMMRegister dst, Operand src, uint8_t imm8); 13011cb0ef41Sopenharmony_ci 13021cb0ef41Sopenharmony_ci // SSE 4.1 instruction 13031cb0ef41Sopenharmony_ci void insertps(XMMRegister dst, XMMRegister src, byte imm8); 13041cb0ef41Sopenharmony_ci void insertps(XMMRegister dst, Operand src, byte imm8); 13051cb0ef41Sopenharmony_ci void pextrq(Register dst, XMMRegister src, int8_t imm8); 13061cb0ef41Sopenharmony_ci void pinsrb(XMMRegister dst, Register src, uint8_t imm8); 13071cb0ef41Sopenharmony_ci void pinsrb(XMMRegister dst, Operand src, uint8_t imm8); 13081cb0ef41Sopenharmony_ci void pinsrd(XMMRegister dst, Register src, uint8_t imm8); 13091cb0ef41Sopenharmony_ci void pinsrd(XMMRegister dst, Operand src, uint8_t imm8); 13101cb0ef41Sopenharmony_ci void pinsrq(XMMRegister dst, Register src, uint8_t imm8); 13111cb0ef41Sopenharmony_ci void pinsrq(XMMRegister dst, Operand src, uint8_t imm8); 13121cb0ef41Sopenharmony_ci 13131cb0ef41Sopenharmony_ci void roundss(XMMRegister dst, XMMRegister src, RoundingMode mode); 13141cb0ef41Sopenharmony_ci void roundss(XMMRegister dst, Operand src, RoundingMode mode); 13151cb0ef41Sopenharmony_ci void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode); 13161cb0ef41Sopenharmony_ci void roundsd(XMMRegister dst, Operand src, RoundingMode mode); 13171cb0ef41Sopenharmony_ci void roundps(XMMRegister dst, XMMRegister src, RoundingMode mode); 13181cb0ef41Sopenharmony_ci void roundpd(XMMRegister dst, XMMRegister src, RoundingMode mode); 13191cb0ef41Sopenharmony_ci 13201cb0ef41Sopenharmony_ci void cmpps(XMMRegister dst, XMMRegister src, int8_t cmp); 13211cb0ef41Sopenharmony_ci void cmpps(XMMRegister dst, Operand src, int8_t cmp); 13221cb0ef41Sopenharmony_ci void cmppd(XMMRegister dst, XMMRegister src, int8_t cmp); 13231cb0ef41Sopenharmony_ci void cmppd(XMMRegister dst, Operand src, int8_t cmp); 13241cb0ef41Sopenharmony_ci 13251cb0ef41Sopenharmony_ci#define SSE_CMP_P(instr, imm8) \ 13261cb0ef41Sopenharmony_ci void instr##ps(XMMRegister dst, XMMRegister src) { cmpps(dst, src, imm8); } \ 13271cb0ef41Sopenharmony_ci void instr##ps(XMMRegister dst, Operand src) { cmpps(dst, src, imm8); } \ 13281cb0ef41Sopenharmony_ci void instr##pd(XMMRegister dst, XMMRegister src) { cmppd(dst, src, imm8); } \ 13291cb0ef41Sopenharmony_ci void instr##pd(XMMRegister dst, Operand src) { cmppd(dst, src, imm8); } 13301cb0ef41Sopenharmony_ci 13311cb0ef41Sopenharmony_ci SSE_CMP_P(cmpeq, 0x0) 13321cb0ef41Sopenharmony_ci SSE_CMP_P(cmplt, 0x1) 13331cb0ef41Sopenharmony_ci SSE_CMP_P(cmple, 0x2) 13341cb0ef41Sopenharmony_ci SSE_CMP_P(cmpunord, 0x3) 13351cb0ef41Sopenharmony_ci SSE_CMP_P(cmpneq, 0x4) 13361cb0ef41Sopenharmony_ci SSE_CMP_P(cmpnlt, 0x5) 13371cb0ef41Sopenharmony_ci SSE_CMP_P(cmpnle, 0x6) 13381cb0ef41Sopenharmony_ci 13391cb0ef41Sopenharmony_ci#undef SSE_CMP_P 13401cb0ef41Sopenharmony_ci 13411cb0ef41Sopenharmony_ci void movups(XMMRegister dst, XMMRegister src); 13421cb0ef41Sopenharmony_ci void movups(XMMRegister dst, Operand src); 13431cb0ef41Sopenharmony_ci void movups(Operand dst, XMMRegister src); 13441cb0ef41Sopenharmony_ci void psrldq(XMMRegister dst, uint8_t shift); 13451cb0ef41Sopenharmony_ci void pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle); 13461cb0ef41Sopenharmony_ci void pshufd(XMMRegister dst, Operand src, uint8_t shuffle); 13471cb0ef41Sopenharmony_ci void pshufhw(XMMRegister dst, XMMRegister src, uint8_t shuffle); 13481cb0ef41Sopenharmony_ci void pshufhw(XMMRegister dst, Operand src, uint8_t shuffle); 13491cb0ef41Sopenharmony_ci void pshuflw(XMMRegister dst, XMMRegister src, uint8_t shuffle); 13501cb0ef41Sopenharmony_ci void pshuflw(XMMRegister dst, Operand src, uint8_t shuffle); 13511cb0ef41Sopenharmony_ci 13521cb0ef41Sopenharmony_ci void movhlps(XMMRegister dst, XMMRegister src) { 13531cb0ef41Sopenharmony_ci sse_instr(dst, src, 0x0F, 0x12); 13541cb0ef41Sopenharmony_ci } 13551cb0ef41Sopenharmony_ci void movlhps(XMMRegister dst, XMMRegister src) { 13561cb0ef41Sopenharmony_ci sse_instr(dst, src, 0x0F, 0x16); 13571cb0ef41Sopenharmony_ci } 13581cb0ef41Sopenharmony_ci 13591cb0ef41Sopenharmony_ci // AVX instruction 13601cb0ef41Sopenharmony_ci void vmovddup(XMMRegister dst, XMMRegister src); 13611cb0ef41Sopenharmony_ci void vmovddup(XMMRegister dst, Operand src); 13621cb0ef41Sopenharmony_ci void vmovddup(YMMRegister dst, YMMRegister src); 13631cb0ef41Sopenharmony_ci void vmovddup(YMMRegister dst, Operand src); 13641cb0ef41Sopenharmony_ci void vmovshdup(XMMRegister dst, XMMRegister src); 13651cb0ef41Sopenharmony_ci void vmovshdup(YMMRegister dst, YMMRegister src); 13661cb0ef41Sopenharmony_ci void vbroadcastss(XMMRegister dst, Operand src); 13671cb0ef41Sopenharmony_ci void vbroadcastss(XMMRegister dst, XMMRegister src); 13681cb0ef41Sopenharmony_ci void vbroadcastss(YMMRegister dst, Operand src); 13691cb0ef41Sopenharmony_ci void vbroadcastss(YMMRegister dst, XMMRegister src); 13701cb0ef41Sopenharmony_ci 13711cb0ef41Sopenharmony_ci void fma_instr(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2, 13721cb0ef41Sopenharmony_ci VectorLength l, SIMDPrefix pp, LeadingOpcode m, VexW w); 13731cb0ef41Sopenharmony_ci void fma_instr(byte op, XMMRegister dst, XMMRegister src1, Operand src2, 13741cb0ef41Sopenharmony_ci VectorLength l, SIMDPrefix pp, LeadingOpcode m, VexW w); 13751cb0ef41Sopenharmony_ci 13761cb0ef41Sopenharmony_ci#define FMA(instr, length, prefix, escape1, escape2, extension, opcode) \ 13771cb0ef41Sopenharmony_ci void instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ 13781cb0ef41Sopenharmony_ci fma_instr(0x##opcode, dst, src1, src2, k##length, k##prefix, \ 13791cb0ef41Sopenharmony_ci k##escape1##escape2, k##extension); \ 13801cb0ef41Sopenharmony_ci } \ 13811cb0ef41Sopenharmony_ci void instr(XMMRegister dst, XMMRegister src1, Operand src2) { \ 13821cb0ef41Sopenharmony_ci fma_instr(0x##opcode, dst, src1, src2, k##length, k##prefix, \ 13831cb0ef41Sopenharmony_ci k##escape1##escape2, k##extension); \ 13841cb0ef41Sopenharmony_ci } 13851cb0ef41Sopenharmony_ci FMA_INSTRUCTION_LIST(FMA) 13861cb0ef41Sopenharmony_ci#undef FMA 13871cb0ef41Sopenharmony_ci 13881cb0ef41Sopenharmony_ci void vmovd(XMMRegister dst, Register src); 13891cb0ef41Sopenharmony_ci void vmovd(XMMRegister dst, Operand src); 13901cb0ef41Sopenharmony_ci void vmovd(Register dst, XMMRegister src); 13911cb0ef41Sopenharmony_ci void vmovq(XMMRegister dst, Register src); 13921cb0ef41Sopenharmony_ci void vmovq(XMMRegister dst, Operand src); 13931cb0ef41Sopenharmony_ci void vmovq(Register dst, XMMRegister src); 13941cb0ef41Sopenharmony_ci 13951cb0ef41Sopenharmony_ci void vmovsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 13961cb0ef41Sopenharmony_ci vsd(0x10, dst, src1, src2); 13971cb0ef41Sopenharmony_ci } 13981cb0ef41Sopenharmony_ci void vmovsd(XMMRegister dst, Operand src) { vsd(0x10, dst, xmm0, src); } 13991cb0ef41Sopenharmony_ci void vmovsd(Operand dst, XMMRegister src) { vsd(0x11, src, xmm0, dst); } 14001cb0ef41Sopenharmony_ci void vmovdqa(XMMRegister dst, Operand src); 14011cb0ef41Sopenharmony_ci void vmovdqa(XMMRegister dst, XMMRegister src); 14021cb0ef41Sopenharmony_ci void vmovdqa(YMMRegister dst, Operand src); 14031cb0ef41Sopenharmony_ci void vmovdqa(YMMRegister dst, YMMRegister src); 14041cb0ef41Sopenharmony_ci void vmovdqu(XMMRegister dst, Operand src); 14051cb0ef41Sopenharmony_ci void vmovdqu(Operand dst, XMMRegister src); 14061cb0ef41Sopenharmony_ci void vmovdqu(XMMRegister dst, XMMRegister src); 14071cb0ef41Sopenharmony_ci void vmovdqu(YMMRegister dst, Operand src); 14081cb0ef41Sopenharmony_ci void vmovdqu(Operand dst, YMMRegister src); 14091cb0ef41Sopenharmony_ci void vmovdqu(YMMRegister dst, YMMRegister src); 14101cb0ef41Sopenharmony_ci 14111cb0ef41Sopenharmony_ci void vmovlps(XMMRegister dst, XMMRegister src1, Operand src2); 14121cb0ef41Sopenharmony_ci void vmovlps(Operand dst, XMMRegister src); 14131cb0ef41Sopenharmony_ci 14141cb0ef41Sopenharmony_ci void vmovhps(XMMRegister dst, XMMRegister src1, Operand src2); 14151cb0ef41Sopenharmony_ci void vmovhps(Operand dst, XMMRegister src); 14161cb0ef41Sopenharmony_ci 14171cb0ef41Sopenharmony_ci#define AVX_SSE_UNOP(instr, escape, opcode) \ 14181cb0ef41Sopenharmony_ci void v##instr(XMMRegister dst, XMMRegister src2) { \ 14191cb0ef41Sopenharmony_ci vps(0x##opcode, dst, xmm0, src2); \ 14201cb0ef41Sopenharmony_ci } \ 14211cb0ef41Sopenharmony_ci void v##instr(XMMRegister dst, Operand src2) { \ 14221cb0ef41Sopenharmony_ci vps(0x##opcode, dst, xmm0, src2); \ 14231cb0ef41Sopenharmony_ci } \ 14241cb0ef41Sopenharmony_ci void v##instr(YMMRegister dst, YMMRegister src2) { \ 14251cb0ef41Sopenharmony_ci vps(0x##opcode, dst, ymm0, src2); \ 14261cb0ef41Sopenharmony_ci } \ 14271cb0ef41Sopenharmony_ci void v##instr(YMMRegister dst, Operand src2) { \ 14281cb0ef41Sopenharmony_ci vps(0x##opcode, dst, ymm0, src2); \ 14291cb0ef41Sopenharmony_ci } 14301cb0ef41Sopenharmony_ci SSE_UNOP_INSTRUCTION_LIST(AVX_SSE_UNOP) 14311cb0ef41Sopenharmony_ci#undef AVX_SSE_UNOP 14321cb0ef41Sopenharmony_ci 14331cb0ef41Sopenharmony_ci#define AVX_SSE_BINOP(instr, escape, opcode) \ 14341cb0ef41Sopenharmony_ci void v##instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ 14351cb0ef41Sopenharmony_ci vps(0x##opcode, dst, src1, src2); \ 14361cb0ef41Sopenharmony_ci } \ 14371cb0ef41Sopenharmony_ci void v##instr(XMMRegister dst, XMMRegister src1, Operand src2) { \ 14381cb0ef41Sopenharmony_ci vps(0x##opcode, dst, src1, src2); \ 14391cb0ef41Sopenharmony_ci } \ 14401cb0ef41Sopenharmony_ci void v##instr(YMMRegister dst, YMMRegister src1, YMMRegister src2) { \ 14411cb0ef41Sopenharmony_ci vps(0x##opcode, dst, src1, src2); \ 14421cb0ef41Sopenharmony_ci } \ 14431cb0ef41Sopenharmony_ci void v##instr(YMMRegister dst, YMMRegister src1, Operand src2) { \ 14441cb0ef41Sopenharmony_ci vps(0x##opcode, dst, src1, src2); \ 14451cb0ef41Sopenharmony_ci } 14461cb0ef41Sopenharmony_ci SSE_BINOP_INSTRUCTION_LIST(AVX_SSE_BINOP) 14471cb0ef41Sopenharmony_ci#undef AVX_SSE_BINOP 14481cb0ef41Sopenharmony_ci 14491cb0ef41Sopenharmony_ci#define AVX_3(instr, opcode, impl, SIMDRegister) \ 14501cb0ef41Sopenharmony_ci void instr(SIMDRegister dst, SIMDRegister src1, SIMDRegister src2) { \ 14511cb0ef41Sopenharmony_ci impl(opcode, dst, src1, src2); \ 14521cb0ef41Sopenharmony_ci } \ 14531cb0ef41Sopenharmony_ci void instr(SIMDRegister dst, SIMDRegister src1, Operand src2) { \ 14541cb0ef41Sopenharmony_ci impl(opcode, dst, src1, src2); \ 14551cb0ef41Sopenharmony_ci } 14561cb0ef41Sopenharmony_ci 14571cb0ef41Sopenharmony_ci AVX_3(vhaddps, 0x7c, vsd, XMMRegister) 14581cb0ef41Sopenharmony_ci AVX_3(vhaddps, 0x7c, vsd, YMMRegister) 14591cb0ef41Sopenharmony_ci 14601cb0ef41Sopenharmony_ci#define AVX_SCALAR(instr, prefix, escape, opcode) \ 14611cb0ef41Sopenharmony_ci void v##instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ 14621cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kWIG); \ 14631cb0ef41Sopenharmony_ci } \ 14641cb0ef41Sopenharmony_ci void v##instr(XMMRegister dst, XMMRegister src1, Operand src2) { \ 14651cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kWIG); \ 14661cb0ef41Sopenharmony_ci } 14671cb0ef41Sopenharmony_ci SSE_INSTRUCTION_LIST_SS(AVX_SCALAR) 14681cb0ef41Sopenharmony_ci SSE2_INSTRUCTION_LIST_SD(AVX_SCALAR) 14691cb0ef41Sopenharmony_ci#undef AVX_SCALAR 14701cb0ef41Sopenharmony_ci 14711cb0ef41Sopenharmony_ci#undef AVX_3 14721cb0ef41Sopenharmony_ci 14731cb0ef41Sopenharmony_ci#define AVX_SSE2_SHIFT_IMM(instr, prefix, escape, opcode, extension) \ 14741cb0ef41Sopenharmony_ci void v##instr(XMMRegister dst, XMMRegister src, byte imm8) { \ 14751cb0ef41Sopenharmony_ci XMMRegister ext_reg = XMMRegister::from_code(extension); \ 14761cb0ef41Sopenharmony_ci vinstr(0x##opcode, ext_reg, dst, src, k##prefix, k##escape, kWIG); \ 14771cb0ef41Sopenharmony_ci emit(imm8); \ 14781cb0ef41Sopenharmony_ci } 14791cb0ef41Sopenharmony_ci SSE2_INSTRUCTION_LIST_SHIFT_IMM(AVX_SSE2_SHIFT_IMM) 14801cb0ef41Sopenharmony_ci#undef AVX_SSE2_SHIFT_IMM 14811cb0ef41Sopenharmony_ci 14821cb0ef41Sopenharmony_ci void vmovlhps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 14831cb0ef41Sopenharmony_ci vinstr(0x16, dst, src1, src2, kNoPrefix, k0F, kWIG); 14841cb0ef41Sopenharmony_ci } 14851cb0ef41Sopenharmony_ci void vmovhlps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 14861cb0ef41Sopenharmony_ci vinstr(0x12, dst, src1, src2, kNoPrefix, k0F, kWIG); 14871cb0ef41Sopenharmony_ci } 14881cb0ef41Sopenharmony_ci void vcvtdq2pd(XMMRegister dst, XMMRegister src) { 14891cb0ef41Sopenharmony_ci vinstr(0xe6, dst, xmm0, src, kF3, k0F, kWIG); 14901cb0ef41Sopenharmony_ci } 14911cb0ef41Sopenharmony_ci void vcvttps2dq(XMMRegister dst, XMMRegister src) { 14921cb0ef41Sopenharmony_ci vinstr(0x5b, dst, xmm0, src, kF3, k0F, kWIG); 14931cb0ef41Sopenharmony_ci } 14941cb0ef41Sopenharmony_ci void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, Register src2) { 14951cb0ef41Sopenharmony_ci XMMRegister isrc2 = XMMRegister::from_code(src2.code()); 14961cb0ef41Sopenharmony_ci vinstr(0x2a, dst, src1, isrc2, kF2, k0F, kW0); 14971cb0ef41Sopenharmony_ci } 14981cb0ef41Sopenharmony_ci void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, Operand src2) { 14991cb0ef41Sopenharmony_ci vinstr(0x2a, dst, src1, src2, kF2, k0F, kW0); 15001cb0ef41Sopenharmony_ci } 15011cb0ef41Sopenharmony_ci void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, Register src2) { 15021cb0ef41Sopenharmony_ci XMMRegister isrc2 = XMMRegister::from_code(src2.code()); 15031cb0ef41Sopenharmony_ci vinstr(0x2a, dst, src1, isrc2, kF3, k0F, kW0); 15041cb0ef41Sopenharmony_ci } 15051cb0ef41Sopenharmony_ci void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, Operand src2) { 15061cb0ef41Sopenharmony_ci vinstr(0x2a, dst, src1, src2, kF3, k0F, kW0); 15071cb0ef41Sopenharmony_ci } 15081cb0ef41Sopenharmony_ci void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Register src2) { 15091cb0ef41Sopenharmony_ci XMMRegister isrc2 = XMMRegister::from_code(src2.code()); 15101cb0ef41Sopenharmony_ci vinstr(0x2a, dst, src1, isrc2, kF3, k0F, kW1); 15111cb0ef41Sopenharmony_ci } 15121cb0ef41Sopenharmony_ci void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Operand src2) { 15131cb0ef41Sopenharmony_ci vinstr(0x2a, dst, src1, src2, kF3, k0F, kW1); 15141cb0ef41Sopenharmony_ci } 15151cb0ef41Sopenharmony_ci void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, Register src2) { 15161cb0ef41Sopenharmony_ci XMMRegister isrc2 = XMMRegister::from_code(src2.code()); 15171cb0ef41Sopenharmony_ci vinstr(0x2a, dst, src1, isrc2, kF2, k0F, kW1); 15181cb0ef41Sopenharmony_ci } 15191cb0ef41Sopenharmony_ci void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, Operand src2) { 15201cb0ef41Sopenharmony_ci vinstr(0x2a, dst, src1, src2, kF2, k0F, kW1); 15211cb0ef41Sopenharmony_ci } 15221cb0ef41Sopenharmony_ci void vcvttss2si(Register dst, XMMRegister src) { 15231cb0ef41Sopenharmony_ci XMMRegister idst = XMMRegister::from_code(dst.code()); 15241cb0ef41Sopenharmony_ci vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW0); 15251cb0ef41Sopenharmony_ci } 15261cb0ef41Sopenharmony_ci void vcvttss2si(Register dst, Operand src) { 15271cb0ef41Sopenharmony_ci XMMRegister idst = XMMRegister::from_code(dst.code()); 15281cb0ef41Sopenharmony_ci vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW0); 15291cb0ef41Sopenharmony_ci } 15301cb0ef41Sopenharmony_ci void vcvttsd2si(Register dst, XMMRegister src) { 15311cb0ef41Sopenharmony_ci XMMRegister idst = XMMRegister::from_code(dst.code()); 15321cb0ef41Sopenharmony_ci vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW0); 15331cb0ef41Sopenharmony_ci } 15341cb0ef41Sopenharmony_ci void vcvttsd2si(Register dst, Operand src) { 15351cb0ef41Sopenharmony_ci XMMRegister idst = XMMRegister::from_code(dst.code()); 15361cb0ef41Sopenharmony_ci vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW0); 15371cb0ef41Sopenharmony_ci } 15381cb0ef41Sopenharmony_ci void vcvttss2siq(Register dst, XMMRegister src) { 15391cb0ef41Sopenharmony_ci XMMRegister idst = XMMRegister::from_code(dst.code()); 15401cb0ef41Sopenharmony_ci vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW1); 15411cb0ef41Sopenharmony_ci } 15421cb0ef41Sopenharmony_ci void vcvttss2siq(Register dst, Operand src) { 15431cb0ef41Sopenharmony_ci XMMRegister idst = XMMRegister::from_code(dst.code()); 15441cb0ef41Sopenharmony_ci vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW1); 15451cb0ef41Sopenharmony_ci } 15461cb0ef41Sopenharmony_ci void vcvttsd2siq(Register dst, XMMRegister src) { 15471cb0ef41Sopenharmony_ci XMMRegister idst = XMMRegister::from_code(dst.code()); 15481cb0ef41Sopenharmony_ci vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW1); 15491cb0ef41Sopenharmony_ci } 15501cb0ef41Sopenharmony_ci void vcvttsd2siq(Register dst, Operand src) { 15511cb0ef41Sopenharmony_ci XMMRegister idst = XMMRegister::from_code(dst.code()); 15521cb0ef41Sopenharmony_ci vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW1); 15531cb0ef41Sopenharmony_ci } 15541cb0ef41Sopenharmony_ci void vcvtsd2si(Register dst, XMMRegister src) { 15551cb0ef41Sopenharmony_ci XMMRegister idst = XMMRegister::from_code(dst.code()); 15561cb0ef41Sopenharmony_ci vinstr(0x2d, idst, xmm0, src, kF2, k0F, kW0); 15571cb0ef41Sopenharmony_ci } 15581cb0ef41Sopenharmony_ci void vroundss(XMMRegister dst, XMMRegister src1, XMMRegister src2, 15591cb0ef41Sopenharmony_ci RoundingMode mode) { 15601cb0ef41Sopenharmony_ci vinstr(0x0a, dst, src1, src2, k66, k0F3A, kWIG); 15611cb0ef41Sopenharmony_ci emit(static_cast<byte>(mode) | 0x8); // Mask precision exception. 15621cb0ef41Sopenharmony_ci } 15631cb0ef41Sopenharmony_ci void vroundss(XMMRegister dst, XMMRegister src1, Operand src2, 15641cb0ef41Sopenharmony_ci RoundingMode mode) { 15651cb0ef41Sopenharmony_ci vinstr(0x0a, dst, src1, src2, k66, k0F3A, kWIG); 15661cb0ef41Sopenharmony_ci emit(static_cast<byte>(mode) | 0x8); // Mask precision exception. 15671cb0ef41Sopenharmony_ci } 15681cb0ef41Sopenharmony_ci void vroundsd(XMMRegister dst, XMMRegister src1, XMMRegister src2, 15691cb0ef41Sopenharmony_ci RoundingMode mode) { 15701cb0ef41Sopenharmony_ci vinstr(0x0b, dst, src1, src2, k66, k0F3A, kWIG); 15711cb0ef41Sopenharmony_ci emit(static_cast<byte>(mode) | 0x8); // Mask precision exception. 15721cb0ef41Sopenharmony_ci } 15731cb0ef41Sopenharmony_ci void vroundsd(XMMRegister dst, XMMRegister src1, Operand src2, 15741cb0ef41Sopenharmony_ci RoundingMode mode) { 15751cb0ef41Sopenharmony_ci vinstr(0x0b, dst, src1, src2, k66, k0F3A, kWIG); 15761cb0ef41Sopenharmony_ci emit(static_cast<byte>(mode) | 0x8); // Mask precision exception. 15771cb0ef41Sopenharmony_ci } 15781cb0ef41Sopenharmony_ci void vroundps(XMMRegister dst, XMMRegister src, RoundingMode mode) { 15791cb0ef41Sopenharmony_ci vinstr(0x08, dst, xmm0, src, k66, k0F3A, kWIG); 15801cb0ef41Sopenharmony_ci emit(static_cast<byte>(mode) | 0x8); // Mask precision exception. 15811cb0ef41Sopenharmony_ci } 15821cb0ef41Sopenharmony_ci void vroundps(YMMRegister dst, YMMRegister src, RoundingMode mode) { 15831cb0ef41Sopenharmony_ci vinstr(0x08, dst, ymm0, src, k66, k0F3A, kWIG, AVX); 15841cb0ef41Sopenharmony_ci emit(static_cast<byte>(mode) | 0x8); // Mask precision exception. 15851cb0ef41Sopenharmony_ci } 15861cb0ef41Sopenharmony_ci void vroundpd(XMMRegister dst, XMMRegister src, RoundingMode mode) { 15871cb0ef41Sopenharmony_ci vinstr(0x09, dst, xmm0, src, k66, k0F3A, kWIG); 15881cb0ef41Sopenharmony_ci emit(static_cast<byte>(mode) | 0x8); // Mask precision exception. 15891cb0ef41Sopenharmony_ci } 15901cb0ef41Sopenharmony_ci void vroundpd(YMMRegister dst, YMMRegister src, RoundingMode mode) { 15911cb0ef41Sopenharmony_ci vinstr(0x09, dst, ymm0, src, k66, k0F3A, kWIG, AVX); 15921cb0ef41Sopenharmony_ci emit(static_cast<byte>(mode) | 0x8); // Mask precision exception. 15931cb0ef41Sopenharmony_ci } 15941cb0ef41Sopenharmony_ci 15951cb0ef41Sopenharmony_ci template <typename Reg, typename Op> 15961cb0ef41Sopenharmony_ci void vsd(byte op, Reg dst, Reg src1, Op src2) { 15971cb0ef41Sopenharmony_ci vinstr(op, dst, src1, src2, kF2, k0F, kWIG, AVX); 15981cb0ef41Sopenharmony_ci } 15991cb0ef41Sopenharmony_ci 16001cb0ef41Sopenharmony_ci void vmovss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 16011cb0ef41Sopenharmony_ci vss(0x10, dst, src1, src2); 16021cb0ef41Sopenharmony_ci } 16031cb0ef41Sopenharmony_ci void vmovss(XMMRegister dst, Operand src) { vss(0x10, dst, xmm0, src); } 16041cb0ef41Sopenharmony_ci void vmovss(Operand dst, XMMRegister src) { vss(0x11, src, xmm0, dst); } 16051cb0ef41Sopenharmony_ci void vucomiss(XMMRegister dst, XMMRegister src); 16061cb0ef41Sopenharmony_ci void vucomiss(XMMRegister dst, Operand src); 16071cb0ef41Sopenharmony_ci void vss(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 16081cb0ef41Sopenharmony_ci void vss(byte op, XMMRegister dst, XMMRegister src1, Operand src2); 16091cb0ef41Sopenharmony_ci 16101cb0ef41Sopenharmony_ci void vshufps(XMMRegister dst, XMMRegister src1, XMMRegister src2, byte imm8) { 16111cb0ef41Sopenharmony_ci vps(0xC6, dst, src1, src2, imm8); 16121cb0ef41Sopenharmony_ci } 16131cb0ef41Sopenharmony_ci void vshufps(YMMRegister dst, YMMRegister src1, YMMRegister src2, byte imm8) { 16141cb0ef41Sopenharmony_ci vps(0xC6, dst, src1, src2, imm8); 16151cb0ef41Sopenharmony_ci } 16161cb0ef41Sopenharmony_ci 16171cb0ef41Sopenharmony_ci void vmovaps(XMMRegister dst, XMMRegister src) { vps(0x28, dst, xmm0, src); } 16181cb0ef41Sopenharmony_ci void vmovaps(YMMRegister dst, YMMRegister src) { vps(0x28, dst, ymm0, src); } 16191cb0ef41Sopenharmony_ci void vmovaps(XMMRegister dst, Operand src) { vps(0x28, dst, xmm0, src); } 16201cb0ef41Sopenharmony_ci void vmovaps(YMMRegister dst, Operand src) { vps(0x28, dst, ymm0, src); } 16211cb0ef41Sopenharmony_ci void vmovups(XMMRegister dst, XMMRegister src) { vps(0x10, dst, xmm0, src); } 16221cb0ef41Sopenharmony_ci void vmovups(YMMRegister dst, YMMRegister src) { vps(0x10, dst, ymm0, src); } 16231cb0ef41Sopenharmony_ci void vmovups(XMMRegister dst, Operand src) { vps(0x10, dst, xmm0, src); } 16241cb0ef41Sopenharmony_ci void vmovups(YMMRegister dst, Operand src) { vps(0x10, dst, ymm0, src); } 16251cb0ef41Sopenharmony_ci void vmovups(Operand dst, XMMRegister src) { vps(0x11, src, xmm0, dst); } 16261cb0ef41Sopenharmony_ci void vmovups(Operand dst, YMMRegister src) { vps(0x11, src, ymm0, dst); } 16271cb0ef41Sopenharmony_ci void vmovapd(XMMRegister dst, XMMRegister src) { vpd(0x28, dst, xmm0, src); } 16281cb0ef41Sopenharmony_ci void vmovapd(YMMRegister dst, YMMRegister src) { vpd(0x28, dst, ymm0, src); } 16291cb0ef41Sopenharmony_ci void vmovupd(XMMRegister dst, Operand src) { vpd(0x10, dst, xmm0, src); } 16301cb0ef41Sopenharmony_ci void vmovupd(YMMRegister dst, Operand src) { vpd(0x10, dst, ymm0, src); } 16311cb0ef41Sopenharmony_ci void vmovupd(Operand dst, XMMRegister src) { vpd(0x11, src, xmm0, dst); } 16321cb0ef41Sopenharmony_ci void vmovupd(Operand dst, YMMRegister src) { vpd(0x11, src, ymm0, dst); } 16331cb0ef41Sopenharmony_ci void vmovmskps(Register dst, XMMRegister src) { 16341cb0ef41Sopenharmony_ci XMMRegister idst = XMMRegister::from_code(dst.code()); 16351cb0ef41Sopenharmony_ci vps(0x50, idst, xmm0, src); 16361cb0ef41Sopenharmony_ci } 16371cb0ef41Sopenharmony_ci void vmovmskpd(Register dst, XMMRegister src) { 16381cb0ef41Sopenharmony_ci XMMRegister idst = XMMRegister::from_code(dst.code()); 16391cb0ef41Sopenharmony_ci vpd(0x50, idst, xmm0, src); 16401cb0ef41Sopenharmony_ci } 16411cb0ef41Sopenharmony_ci void vpmovmskb(Register dst, XMMRegister src); 16421cb0ef41Sopenharmony_ci void vcmpeqss(XMMRegister dst, XMMRegister src) { 16431cb0ef41Sopenharmony_ci vss(0xC2, dst, dst, src); 16441cb0ef41Sopenharmony_ci emit(0x00); // EQ == 0 16451cb0ef41Sopenharmony_ci } 16461cb0ef41Sopenharmony_ci void vcmpeqsd(XMMRegister dst, XMMRegister src) { 16471cb0ef41Sopenharmony_ci vsd(0xC2, dst, dst, src); 16481cb0ef41Sopenharmony_ci emit(0x00); // EQ == 0 16491cb0ef41Sopenharmony_ci } 16501cb0ef41Sopenharmony_ci void vcmpps(XMMRegister dst, XMMRegister src1, XMMRegister src2, int8_t cmp) { 16511cb0ef41Sopenharmony_ci vps(0xC2, dst, src1, src2); 16521cb0ef41Sopenharmony_ci emit(cmp); 16531cb0ef41Sopenharmony_ci } 16541cb0ef41Sopenharmony_ci void vcmpps(YMMRegister dst, YMMRegister src1, YMMRegister src2, int8_t cmp) { 16551cb0ef41Sopenharmony_ci vps(0xC2, dst, src1, src2); 16561cb0ef41Sopenharmony_ci emit(cmp); 16571cb0ef41Sopenharmony_ci } 16581cb0ef41Sopenharmony_ci void vcmpps(XMMRegister dst, XMMRegister src1, Operand src2, int8_t cmp) { 16591cb0ef41Sopenharmony_ci vps(0xC2, dst, src1, src2); 16601cb0ef41Sopenharmony_ci emit(cmp); 16611cb0ef41Sopenharmony_ci } 16621cb0ef41Sopenharmony_ci void vcmpps(YMMRegister dst, YMMRegister src1, Operand src2, int8_t cmp) { 16631cb0ef41Sopenharmony_ci vps(0xC2, dst, src1, src2); 16641cb0ef41Sopenharmony_ci emit(cmp); 16651cb0ef41Sopenharmony_ci } 16661cb0ef41Sopenharmony_ci void vcmppd(XMMRegister dst, XMMRegister src1, XMMRegister src2, int8_t cmp) { 16671cb0ef41Sopenharmony_ci vpd(0xC2, dst, src1, src2); 16681cb0ef41Sopenharmony_ci emit(cmp); 16691cb0ef41Sopenharmony_ci } 16701cb0ef41Sopenharmony_ci void vcmppd(YMMRegister dst, YMMRegister src1, YMMRegister src2, int8_t cmp) { 16711cb0ef41Sopenharmony_ci vpd(0xC2, dst, src1, src2); 16721cb0ef41Sopenharmony_ci emit(cmp); 16731cb0ef41Sopenharmony_ci } 16741cb0ef41Sopenharmony_ci void vcmppd(XMMRegister dst, XMMRegister src1, Operand src2, int8_t cmp) { 16751cb0ef41Sopenharmony_ci vpd(0xC2, dst, src1, src2); 16761cb0ef41Sopenharmony_ci emit(cmp); 16771cb0ef41Sopenharmony_ci } 16781cb0ef41Sopenharmony_ci void vcmppd(YMMRegister dst, YMMRegister src1, Operand src2, int8_t cmp) { 16791cb0ef41Sopenharmony_ci vpd(0xC2, dst, src1, src2); 16801cb0ef41Sopenharmony_ci emit(cmp); 16811cb0ef41Sopenharmony_ci } 16821cb0ef41Sopenharmony_ci#define AVX_CMP_P(instr, imm8, SIMDRegister) \ 16831cb0ef41Sopenharmony_ci void instr##ps(SIMDRegister dst, SIMDRegister src1, SIMDRegister src2) { \ 16841cb0ef41Sopenharmony_ci vcmpps(dst, src1, src2, imm8); \ 16851cb0ef41Sopenharmony_ci } \ 16861cb0ef41Sopenharmony_ci void instr##ps(SIMDRegister dst, SIMDRegister src1, Operand src2) { \ 16871cb0ef41Sopenharmony_ci vcmpps(dst, src1, src2, imm8); \ 16881cb0ef41Sopenharmony_ci } \ 16891cb0ef41Sopenharmony_ci void instr##pd(SIMDRegister dst, SIMDRegister src1, SIMDRegister src2) { \ 16901cb0ef41Sopenharmony_ci vcmppd(dst, src1, src2, imm8); \ 16911cb0ef41Sopenharmony_ci } \ 16921cb0ef41Sopenharmony_ci void instr##pd(SIMDRegister dst, SIMDRegister src1, Operand src2) { \ 16931cb0ef41Sopenharmony_ci vcmppd(dst, src1, src2, imm8); \ 16941cb0ef41Sopenharmony_ci } 16951cb0ef41Sopenharmony_ci 16961cb0ef41Sopenharmony_ci AVX_CMP_P(vcmpeq, 0x0, XMMRegister) 16971cb0ef41Sopenharmony_ci AVX_CMP_P(vcmpeq, 0x0, YMMRegister) 16981cb0ef41Sopenharmony_ci AVX_CMP_P(vcmplt, 0x1, XMMRegister) 16991cb0ef41Sopenharmony_ci AVX_CMP_P(vcmplt, 0x1, YMMRegister) 17001cb0ef41Sopenharmony_ci AVX_CMP_P(vcmple, 0x2, XMMRegister) 17011cb0ef41Sopenharmony_ci AVX_CMP_P(vcmple, 0x2, YMMRegister) 17021cb0ef41Sopenharmony_ci AVX_CMP_P(vcmpunord, 0x3, XMMRegister) 17031cb0ef41Sopenharmony_ci AVX_CMP_P(vcmpunord, 0x3, YMMRegister) 17041cb0ef41Sopenharmony_ci AVX_CMP_P(vcmpneq, 0x4, XMMRegister) 17051cb0ef41Sopenharmony_ci AVX_CMP_P(vcmpneq, 0x4, YMMRegister) 17061cb0ef41Sopenharmony_ci AVX_CMP_P(vcmpnlt, 0x5, XMMRegister) 17071cb0ef41Sopenharmony_ci AVX_CMP_P(vcmpnlt, 0x5, YMMRegister) 17081cb0ef41Sopenharmony_ci AVX_CMP_P(vcmpnle, 0x6, XMMRegister) 17091cb0ef41Sopenharmony_ci AVX_CMP_P(vcmpnle, 0x6, YMMRegister) 17101cb0ef41Sopenharmony_ci AVX_CMP_P(vcmpge, 0xd, XMMRegister) 17111cb0ef41Sopenharmony_ci AVX_CMP_P(vcmpge, 0xd, YMMRegister) 17121cb0ef41Sopenharmony_ci 17131cb0ef41Sopenharmony_ci#undef AVX_CMP_P 17141cb0ef41Sopenharmony_ci 17151cb0ef41Sopenharmony_ci void vlddqu(XMMRegister dst, Operand src) { 17161cb0ef41Sopenharmony_ci vinstr(0xF0, dst, xmm0, src, kF2, k0F, kWIG); 17171cb0ef41Sopenharmony_ci } 17181cb0ef41Sopenharmony_ci void vinsertps(XMMRegister dst, XMMRegister src1, XMMRegister src2, 17191cb0ef41Sopenharmony_ci byte imm8) { 17201cb0ef41Sopenharmony_ci vinstr(0x21, dst, src1, src2, k66, k0F3A, kWIG); 17211cb0ef41Sopenharmony_ci emit(imm8); 17221cb0ef41Sopenharmony_ci } 17231cb0ef41Sopenharmony_ci void vinsertps(XMMRegister dst, XMMRegister src1, Operand src2, byte imm8) { 17241cb0ef41Sopenharmony_ci vinstr(0x21, dst, src1, src2, k66, k0F3A, kWIG); 17251cb0ef41Sopenharmony_ci emit(imm8); 17261cb0ef41Sopenharmony_ci } 17271cb0ef41Sopenharmony_ci void vpextrq(Register dst, XMMRegister src, int8_t imm8) { 17281cb0ef41Sopenharmony_ci XMMRegister idst = XMMRegister::from_code(dst.code()); 17291cb0ef41Sopenharmony_ci vinstr(0x16, src, xmm0, idst, k66, k0F3A, kW1); 17301cb0ef41Sopenharmony_ci emit(imm8); 17311cb0ef41Sopenharmony_ci } 17321cb0ef41Sopenharmony_ci void vpinsrb(XMMRegister dst, XMMRegister src1, Register src2, uint8_t imm8) { 17331cb0ef41Sopenharmony_ci XMMRegister isrc = XMMRegister::from_code(src2.code()); 17341cb0ef41Sopenharmony_ci vinstr(0x20, dst, src1, isrc, k66, k0F3A, kW0); 17351cb0ef41Sopenharmony_ci emit(imm8); 17361cb0ef41Sopenharmony_ci } 17371cb0ef41Sopenharmony_ci void vpinsrb(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8) { 17381cb0ef41Sopenharmony_ci vinstr(0x20, dst, src1, src2, k66, k0F3A, kW0); 17391cb0ef41Sopenharmony_ci emit(imm8); 17401cb0ef41Sopenharmony_ci } 17411cb0ef41Sopenharmony_ci void vpinsrw(XMMRegister dst, XMMRegister src1, Register src2, uint8_t imm8) { 17421cb0ef41Sopenharmony_ci XMMRegister isrc = XMMRegister::from_code(src2.code()); 17431cb0ef41Sopenharmony_ci vinstr(0xc4, dst, src1, isrc, k66, k0F, kW0); 17441cb0ef41Sopenharmony_ci emit(imm8); 17451cb0ef41Sopenharmony_ci } 17461cb0ef41Sopenharmony_ci void vpinsrw(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8) { 17471cb0ef41Sopenharmony_ci vinstr(0xc4, dst, src1, src2, k66, k0F, kW0); 17481cb0ef41Sopenharmony_ci emit(imm8); 17491cb0ef41Sopenharmony_ci } 17501cb0ef41Sopenharmony_ci void vpinsrd(XMMRegister dst, XMMRegister src1, Register src2, uint8_t imm8) { 17511cb0ef41Sopenharmony_ci XMMRegister isrc = XMMRegister::from_code(src2.code()); 17521cb0ef41Sopenharmony_ci vinstr(0x22, dst, src1, isrc, k66, k0F3A, kW0); 17531cb0ef41Sopenharmony_ci emit(imm8); 17541cb0ef41Sopenharmony_ci } 17551cb0ef41Sopenharmony_ci void vpinsrd(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8) { 17561cb0ef41Sopenharmony_ci vinstr(0x22, dst, src1, src2, k66, k0F3A, kW0); 17571cb0ef41Sopenharmony_ci emit(imm8); 17581cb0ef41Sopenharmony_ci } 17591cb0ef41Sopenharmony_ci void vpinsrq(XMMRegister dst, XMMRegister src1, Register src2, uint8_t imm8) { 17601cb0ef41Sopenharmony_ci XMMRegister isrc = XMMRegister::from_code(src2.code()); 17611cb0ef41Sopenharmony_ci vinstr(0x22, dst, src1, isrc, k66, k0F3A, kW1); 17621cb0ef41Sopenharmony_ci emit(imm8); 17631cb0ef41Sopenharmony_ci } 17641cb0ef41Sopenharmony_ci void vpinsrq(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8) { 17651cb0ef41Sopenharmony_ci vinstr(0x22, dst, src1, src2, k66, k0F3A, kW1); 17661cb0ef41Sopenharmony_ci emit(imm8); 17671cb0ef41Sopenharmony_ci } 17681cb0ef41Sopenharmony_ci 17691cb0ef41Sopenharmony_ci void vpshufd(XMMRegister dst, XMMRegister src, uint8_t imm8) { 17701cb0ef41Sopenharmony_ci vinstr(0x70, dst, xmm0, src, k66, k0F, kWIG); 17711cb0ef41Sopenharmony_ci emit(imm8); 17721cb0ef41Sopenharmony_ci } 17731cb0ef41Sopenharmony_ci void vpshufd(YMMRegister dst, YMMRegister src, uint8_t imm8) { 17741cb0ef41Sopenharmony_ci vinstr(0x70, dst, ymm0, src, k66, k0F, kWIG); 17751cb0ef41Sopenharmony_ci emit(imm8); 17761cb0ef41Sopenharmony_ci } 17771cb0ef41Sopenharmony_ci void vpshufd(XMMRegister dst, Operand src, uint8_t imm8) { 17781cb0ef41Sopenharmony_ci vinstr(0x70, dst, xmm0, src, k66, k0F, kWIG); 17791cb0ef41Sopenharmony_ci emit(imm8); 17801cb0ef41Sopenharmony_ci } 17811cb0ef41Sopenharmony_ci void vpshufd(YMMRegister dst, Operand src, uint8_t imm8) { 17821cb0ef41Sopenharmony_ci vinstr(0x70, dst, ymm0, src, k66, k0F, kWIG); 17831cb0ef41Sopenharmony_ci emit(imm8); 17841cb0ef41Sopenharmony_ci } 17851cb0ef41Sopenharmony_ci void vpshuflw(XMMRegister dst, XMMRegister src, uint8_t imm8) { 17861cb0ef41Sopenharmony_ci vinstr(0x70, dst, xmm0, src, kF2, k0F, kWIG); 17871cb0ef41Sopenharmony_ci emit(imm8); 17881cb0ef41Sopenharmony_ci } 17891cb0ef41Sopenharmony_ci void vpshuflw(YMMRegister dst, YMMRegister src, uint8_t imm8) { 17901cb0ef41Sopenharmony_ci vinstr(0x70, dst, ymm0, src, kF2, k0F, kWIG); 17911cb0ef41Sopenharmony_ci emit(imm8); 17921cb0ef41Sopenharmony_ci } 17931cb0ef41Sopenharmony_ci void vpshuflw(XMMRegister dst, Operand src, uint8_t imm8) { 17941cb0ef41Sopenharmony_ci vinstr(0x70, dst, xmm0, src, kF2, k0F, kWIG); 17951cb0ef41Sopenharmony_ci emit(imm8); 17961cb0ef41Sopenharmony_ci } 17971cb0ef41Sopenharmony_ci void vpshuflw(YMMRegister dst, Operand src, uint8_t imm8) { 17981cb0ef41Sopenharmony_ci vinstr(0x70, dst, ymm0, src, kF2, k0F, kWIG); 17991cb0ef41Sopenharmony_ci emit(imm8); 18001cb0ef41Sopenharmony_ci } 18011cb0ef41Sopenharmony_ci void vpshufhw(XMMRegister dst, XMMRegister src, uint8_t imm8) { 18021cb0ef41Sopenharmony_ci vinstr(0x70, dst, xmm0, src, kF3, k0F, kWIG); 18031cb0ef41Sopenharmony_ci emit(imm8); 18041cb0ef41Sopenharmony_ci } 18051cb0ef41Sopenharmony_ci void vpshufhw(YMMRegister dst, YMMRegister src, uint8_t imm8) { 18061cb0ef41Sopenharmony_ci vinstr(0x70, dst, ymm0, src, kF3, k0F, kWIG); 18071cb0ef41Sopenharmony_ci emit(imm8); 18081cb0ef41Sopenharmony_ci } 18091cb0ef41Sopenharmony_ci void vpshufhw(XMMRegister dst, Operand src, uint8_t imm8) { 18101cb0ef41Sopenharmony_ci vinstr(0x70, dst, xmm0, src, kF3, k0F, kWIG); 18111cb0ef41Sopenharmony_ci emit(imm8); 18121cb0ef41Sopenharmony_ci } 18131cb0ef41Sopenharmony_ci void vpshufhw(YMMRegister dst, Operand src, uint8_t imm8) { 18141cb0ef41Sopenharmony_ci vinstr(0x70, dst, ymm0, src, kF3, k0F, kWIG); 18151cb0ef41Sopenharmony_ci emit(imm8); 18161cb0ef41Sopenharmony_ci } 18171cb0ef41Sopenharmony_ci 18181cb0ef41Sopenharmony_ci void vpblendw(XMMRegister dst, XMMRegister src1, XMMRegister src2, 18191cb0ef41Sopenharmony_ci uint8_t mask) { 18201cb0ef41Sopenharmony_ci vinstr(0x0E, dst, src1, src2, k66, k0F3A, kWIG); 18211cb0ef41Sopenharmony_ci emit(mask); 18221cb0ef41Sopenharmony_ci } 18231cb0ef41Sopenharmony_ci void vpblendw(YMMRegister dst, YMMRegister src1, YMMRegister src2, 18241cb0ef41Sopenharmony_ci uint8_t mask) { 18251cb0ef41Sopenharmony_ci vinstr(0x0E, dst, src1, src2, k66, k0F3A, kWIG); 18261cb0ef41Sopenharmony_ci emit(mask); 18271cb0ef41Sopenharmony_ci } 18281cb0ef41Sopenharmony_ci void vpblendw(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t mask) { 18291cb0ef41Sopenharmony_ci vinstr(0x0E, dst, src1, src2, k66, k0F3A, kWIG); 18301cb0ef41Sopenharmony_ci emit(mask); 18311cb0ef41Sopenharmony_ci } 18321cb0ef41Sopenharmony_ci void vpblendw(YMMRegister dst, YMMRegister src1, Operand src2, uint8_t mask) { 18331cb0ef41Sopenharmony_ci vinstr(0x0E, dst, src1, src2, k66, k0F3A, kWIG); 18341cb0ef41Sopenharmony_ci emit(mask); 18351cb0ef41Sopenharmony_ci } 18361cb0ef41Sopenharmony_ci 18371cb0ef41Sopenharmony_ci void vpalignr(XMMRegister dst, XMMRegister src1, XMMRegister src2, 18381cb0ef41Sopenharmony_ci uint8_t imm8) { 18391cb0ef41Sopenharmony_ci vinstr(0x0F, dst, src1, src2, k66, k0F3A, kWIG); 18401cb0ef41Sopenharmony_ci emit(imm8); 18411cb0ef41Sopenharmony_ci } 18421cb0ef41Sopenharmony_ci void vpalignr(YMMRegister dst, YMMRegister src1, YMMRegister src2, 18431cb0ef41Sopenharmony_ci uint8_t imm8) { 18441cb0ef41Sopenharmony_ci vinstr(0x0F, dst, src1, src2, k66, k0F3A, kWIG); 18451cb0ef41Sopenharmony_ci emit(imm8); 18461cb0ef41Sopenharmony_ci } 18471cb0ef41Sopenharmony_ci void vpalignr(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8) { 18481cb0ef41Sopenharmony_ci vinstr(0x0F, dst, src1, src2, k66, k0F3A, kWIG); 18491cb0ef41Sopenharmony_ci emit(imm8); 18501cb0ef41Sopenharmony_ci } 18511cb0ef41Sopenharmony_ci void vpalignr(YMMRegister dst, YMMRegister src1, Operand src2, uint8_t imm8) { 18521cb0ef41Sopenharmony_ci vinstr(0x0F, dst, src1, src2, k66, k0F3A, kWIG); 18531cb0ef41Sopenharmony_ci emit(imm8); 18541cb0ef41Sopenharmony_ci } 18551cb0ef41Sopenharmony_ci 18561cb0ef41Sopenharmony_ci void vps(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 18571cb0ef41Sopenharmony_ci void vps(byte op, YMMRegister dst, YMMRegister src1, YMMRegister src2); 18581cb0ef41Sopenharmony_ci void vps(byte op, XMMRegister dst, XMMRegister src1, Operand src2); 18591cb0ef41Sopenharmony_ci void vps(byte op, YMMRegister dst, YMMRegister src1, Operand src2); 18601cb0ef41Sopenharmony_ci void vps(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2, 18611cb0ef41Sopenharmony_ci byte imm8); 18621cb0ef41Sopenharmony_ci void vps(byte op, YMMRegister dst, YMMRegister src1, YMMRegister src2, 18631cb0ef41Sopenharmony_ci byte imm8); 18641cb0ef41Sopenharmony_ci void vpd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 18651cb0ef41Sopenharmony_ci void vpd(byte op, YMMRegister dst, YMMRegister src1, YMMRegister src2); 18661cb0ef41Sopenharmony_ci void vpd(byte op, XMMRegister dst, XMMRegister src1, Operand src2); 18671cb0ef41Sopenharmony_ci void vpd(byte op, YMMRegister dst, YMMRegister src1, Operand src2); 18681cb0ef41Sopenharmony_ci 18691cb0ef41Sopenharmony_ci // AVX2 instructions 18701cb0ef41Sopenharmony_ci#define AVX2_INSTRUCTION(instr, prefix, escape1, escape2, opcode) \ 18711cb0ef41Sopenharmony_ci template <typename Reg, typename Op> \ 18721cb0ef41Sopenharmony_ci void instr(Reg dst, Op src) { \ 18731cb0ef41Sopenharmony_ci vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0, \ 18741cb0ef41Sopenharmony_ci AVX2); \ 18751cb0ef41Sopenharmony_ci } 18761cb0ef41Sopenharmony_ci AVX2_BROADCAST_LIST(AVX2_INSTRUCTION) 18771cb0ef41Sopenharmony_ci#undef AVX2_INSTRUCTION 18781cb0ef41Sopenharmony_ci 18791cb0ef41Sopenharmony_ci // BMI instruction 18801cb0ef41Sopenharmony_ci void andnq(Register dst, Register src1, Register src2) { 18811cb0ef41Sopenharmony_ci bmi1q(0xf2, dst, src1, src2); 18821cb0ef41Sopenharmony_ci } 18831cb0ef41Sopenharmony_ci void andnq(Register dst, Register src1, Operand src2) { 18841cb0ef41Sopenharmony_ci bmi1q(0xf2, dst, src1, src2); 18851cb0ef41Sopenharmony_ci } 18861cb0ef41Sopenharmony_ci void andnl(Register dst, Register src1, Register src2) { 18871cb0ef41Sopenharmony_ci bmi1l(0xf2, dst, src1, src2); 18881cb0ef41Sopenharmony_ci } 18891cb0ef41Sopenharmony_ci void andnl(Register dst, Register src1, Operand src2) { 18901cb0ef41Sopenharmony_ci bmi1l(0xf2, dst, src1, src2); 18911cb0ef41Sopenharmony_ci } 18921cb0ef41Sopenharmony_ci void bextrq(Register dst, Register src1, Register src2) { 18931cb0ef41Sopenharmony_ci bmi1q(0xf7, dst, src2, src1); 18941cb0ef41Sopenharmony_ci } 18951cb0ef41Sopenharmony_ci void bextrq(Register dst, Operand src1, Register src2) { 18961cb0ef41Sopenharmony_ci bmi1q(0xf7, dst, src2, src1); 18971cb0ef41Sopenharmony_ci } 18981cb0ef41Sopenharmony_ci void bextrl(Register dst, Register src1, Register src2) { 18991cb0ef41Sopenharmony_ci bmi1l(0xf7, dst, src2, src1); 19001cb0ef41Sopenharmony_ci } 19011cb0ef41Sopenharmony_ci void bextrl(Register dst, Operand src1, Register src2) { 19021cb0ef41Sopenharmony_ci bmi1l(0xf7, dst, src2, src1); 19031cb0ef41Sopenharmony_ci } 19041cb0ef41Sopenharmony_ci void blsiq(Register dst, Register src) { bmi1q(0xf3, rbx, dst, src); } 19051cb0ef41Sopenharmony_ci void blsiq(Register dst, Operand src) { bmi1q(0xf3, rbx, dst, src); } 19061cb0ef41Sopenharmony_ci void blsil(Register dst, Register src) { bmi1l(0xf3, rbx, dst, src); } 19071cb0ef41Sopenharmony_ci void blsil(Register dst, Operand src) { bmi1l(0xf3, rbx, dst, src); } 19081cb0ef41Sopenharmony_ci void blsmskq(Register dst, Register src) { bmi1q(0xf3, rdx, dst, src); } 19091cb0ef41Sopenharmony_ci void blsmskq(Register dst, Operand src) { bmi1q(0xf3, rdx, dst, src); } 19101cb0ef41Sopenharmony_ci void blsmskl(Register dst, Register src) { bmi1l(0xf3, rdx, dst, src); } 19111cb0ef41Sopenharmony_ci void blsmskl(Register dst, Operand src) { bmi1l(0xf3, rdx, dst, src); } 19121cb0ef41Sopenharmony_ci void blsrq(Register dst, Register src) { bmi1q(0xf3, rcx, dst, src); } 19131cb0ef41Sopenharmony_ci void blsrq(Register dst, Operand src) { bmi1q(0xf3, rcx, dst, src); } 19141cb0ef41Sopenharmony_ci void blsrl(Register dst, Register src) { bmi1l(0xf3, rcx, dst, src); } 19151cb0ef41Sopenharmony_ci void blsrl(Register dst, Operand src) { bmi1l(0xf3, rcx, dst, src); } 19161cb0ef41Sopenharmony_ci void tzcntq(Register dst, Register src); 19171cb0ef41Sopenharmony_ci void tzcntq(Register dst, Operand src); 19181cb0ef41Sopenharmony_ci void tzcntl(Register dst, Register src); 19191cb0ef41Sopenharmony_ci void tzcntl(Register dst, Operand src); 19201cb0ef41Sopenharmony_ci 19211cb0ef41Sopenharmony_ci void lzcntq(Register dst, Register src); 19221cb0ef41Sopenharmony_ci void lzcntq(Register dst, Operand src); 19231cb0ef41Sopenharmony_ci void lzcntl(Register dst, Register src); 19241cb0ef41Sopenharmony_ci void lzcntl(Register dst, Operand src); 19251cb0ef41Sopenharmony_ci 19261cb0ef41Sopenharmony_ci void popcntq(Register dst, Register src); 19271cb0ef41Sopenharmony_ci void popcntq(Register dst, Operand src); 19281cb0ef41Sopenharmony_ci void popcntl(Register dst, Register src); 19291cb0ef41Sopenharmony_ci void popcntl(Register dst, Operand src); 19301cb0ef41Sopenharmony_ci 19311cb0ef41Sopenharmony_ci void bzhiq(Register dst, Register src1, Register src2) { 19321cb0ef41Sopenharmony_ci bmi2q(kNoPrefix, 0xf5, dst, src2, src1); 19331cb0ef41Sopenharmony_ci } 19341cb0ef41Sopenharmony_ci void bzhiq(Register dst, Operand src1, Register src2) { 19351cb0ef41Sopenharmony_ci bmi2q(kNoPrefix, 0xf5, dst, src2, src1); 19361cb0ef41Sopenharmony_ci } 19371cb0ef41Sopenharmony_ci void bzhil(Register dst, Register src1, Register src2) { 19381cb0ef41Sopenharmony_ci bmi2l(kNoPrefix, 0xf5, dst, src2, src1); 19391cb0ef41Sopenharmony_ci } 19401cb0ef41Sopenharmony_ci void bzhil(Register dst, Operand src1, Register src2) { 19411cb0ef41Sopenharmony_ci bmi2l(kNoPrefix, 0xf5, dst, src2, src1); 19421cb0ef41Sopenharmony_ci } 19431cb0ef41Sopenharmony_ci void mulxq(Register dst1, Register dst2, Register src) { 19441cb0ef41Sopenharmony_ci bmi2q(kF2, 0xf6, dst1, dst2, src); 19451cb0ef41Sopenharmony_ci } 19461cb0ef41Sopenharmony_ci void mulxq(Register dst1, Register dst2, Operand src) { 19471cb0ef41Sopenharmony_ci bmi2q(kF2, 0xf6, dst1, dst2, src); 19481cb0ef41Sopenharmony_ci } 19491cb0ef41Sopenharmony_ci void mulxl(Register dst1, Register dst2, Register src) { 19501cb0ef41Sopenharmony_ci bmi2l(kF2, 0xf6, dst1, dst2, src); 19511cb0ef41Sopenharmony_ci } 19521cb0ef41Sopenharmony_ci void mulxl(Register dst1, Register dst2, Operand src) { 19531cb0ef41Sopenharmony_ci bmi2l(kF2, 0xf6, dst1, dst2, src); 19541cb0ef41Sopenharmony_ci } 19551cb0ef41Sopenharmony_ci void pdepq(Register dst, Register src1, Register src2) { 19561cb0ef41Sopenharmony_ci bmi2q(kF2, 0xf5, dst, src1, src2); 19571cb0ef41Sopenharmony_ci } 19581cb0ef41Sopenharmony_ci void pdepq(Register dst, Register src1, Operand src2) { 19591cb0ef41Sopenharmony_ci bmi2q(kF2, 0xf5, dst, src1, src2); 19601cb0ef41Sopenharmony_ci } 19611cb0ef41Sopenharmony_ci void pdepl(Register dst, Register src1, Register src2) { 19621cb0ef41Sopenharmony_ci bmi2l(kF2, 0xf5, dst, src1, src2); 19631cb0ef41Sopenharmony_ci } 19641cb0ef41Sopenharmony_ci void pdepl(Register dst, Register src1, Operand src2) { 19651cb0ef41Sopenharmony_ci bmi2l(kF2, 0xf5, dst, src1, src2); 19661cb0ef41Sopenharmony_ci } 19671cb0ef41Sopenharmony_ci void pextq(Register dst, Register src1, Register src2) { 19681cb0ef41Sopenharmony_ci bmi2q(kF3, 0xf5, dst, src1, src2); 19691cb0ef41Sopenharmony_ci } 19701cb0ef41Sopenharmony_ci void pextq(Register dst, Register src1, Operand src2) { 19711cb0ef41Sopenharmony_ci bmi2q(kF3, 0xf5, dst, src1, src2); 19721cb0ef41Sopenharmony_ci } 19731cb0ef41Sopenharmony_ci void pextl(Register dst, Register src1, Register src2) { 19741cb0ef41Sopenharmony_ci bmi2l(kF3, 0xf5, dst, src1, src2); 19751cb0ef41Sopenharmony_ci } 19761cb0ef41Sopenharmony_ci void pextl(Register dst, Register src1, Operand src2) { 19771cb0ef41Sopenharmony_ci bmi2l(kF3, 0xf5, dst, src1, src2); 19781cb0ef41Sopenharmony_ci } 19791cb0ef41Sopenharmony_ci void sarxq(Register dst, Register src1, Register src2) { 19801cb0ef41Sopenharmony_ci bmi2q(kF3, 0xf7, dst, src2, src1); 19811cb0ef41Sopenharmony_ci } 19821cb0ef41Sopenharmony_ci void sarxq(Register dst, Operand src1, Register src2) { 19831cb0ef41Sopenharmony_ci bmi2q(kF3, 0xf7, dst, src2, src1); 19841cb0ef41Sopenharmony_ci } 19851cb0ef41Sopenharmony_ci void sarxl(Register dst, Register src1, Register src2) { 19861cb0ef41Sopenharmony_ci bmi2l(kF3, 0xf7, dst, src2, src1); 19871cb0ef41Sopenharmony_ci } 19881cb0ef41Sopenharmony_ci void sarxl(Register dst, Operand src1, Register src2) { 19891cb0ef41Sopenharmony_ci bmi2l(kF3, 0xf7, dst, src2, src1); 19901cb0ef41Sopenharmony_ci } 19911cb0ef41Sopenharmony_ci void shlxq(Register dst, Register src1, Register src2) { 19921cb0ef41Sopenharmony_ci bmi2q(k66, 0xf7, dst, src2, src1); 19931cb0ef41Sopenharmony_ci } 19941cb0ef41Sopenharmony_ci void shlxq(Register dst, Operand src1, Register src2) { 19951cb0ef41Sopenharmony_ci bmi2q(k66, 0xf7, dst, src2, src1); 19961cb0ef41Sopenharmony_ci } 19971cb0ef41Sopenharmony_ci void shlxl(Register dst, Register src1, Register src2) { 19981cb0ef41Sopenharmony_ci bmi2l(k66, 0xf7, dst, src2, src1); 19991cb0ef41Sopenharmony_ci } 20001cb0ef41Sopenharmony_ci void shlxl(Register dst, Operand src1, Register src2) { 20011cb0ef41Sopenharmony_ci bmi2l(k66, 0xf7, dst, src2, src1); 20021cb0ef41Sopenharmony_ci } 20031cb0ef41Sopenharmony_ci void shrxq(Register dst, Register src1, Register src2) { 20041cb0ef41Sopenharmony_ci bmi2q(kF2, 0xf7, dst, src2, src1); 20051cb0ef41Sopenharmony_ci } 20061cb0ef41Sopenharmony_ci void shrxq(Register dst, Operand src1, Register src2) { 20071cb0ef41Sopenharmony_ci bmi2q(kF2, 0xf7, dst, src2, src1); 20081cb0ef41Sopenharmony_ci } 20091cb0ef41Sopenharmony_ci void shrxl(Register dst, Register src1, Register src2) { 20101cb0ef41Sopenharmony_ci bmi2l(kF2, 0xf7, dst, src2, src1); 20111cb0ef41Sopenharmony_ci } 20121cb0ef41Sopenharmony_ci void shrxl(Register dst, Operand src1, Register src2) { 20131cb0ef41Sopenharmony_ci bmi2l(kF2, 0xf7, dst, src2, src1); 20141cb0ef41Sopenharmony_ci } 20151cb0ef41Sopenharmony_ci void rorxq(Register dst, Register src, byte imm8); 20161cb0ef41Sopenharmony_ci void rorxq(Register dst, Operand src, byte imm8); 20171cb0ef41Sopenharmony_ci void rorxl(Register dst, Register src, byte imm8); 20181cb0ef41Sopenharmony_ci void rorxl(Register dst, Operand src, byte imm8); 20191cb0ef41Sopenharmony_ci 20201cb0ef41Sopenharmony_ci void mfence(); 20211cb0ef41Sopenharmony_ci void lfence(); 20221cb0ef41Sopenharmony_ci void pause(); 20231cb0ef41Sopenharmony_ci 20241cb0ef41Sopenharmony_ci // Check the code size generated from label to here. 20251cb0ef41Sopenharmony_ci int SizeOfCodeGeneratedSince(Label* label) { 20261cb0ef41Sopenharmony_ci return pc_offset() - label->pos(); 20271cb0ef41Sopenharmony_ci } 20281cb0ef41Sopenharmony_ci 20291cb0ef41Sopenharmony_ci // Record a deoptimization reason that can be used by a log or cpu profiler. 20301cb0ef41Sopenharmony_ci // Use --trace-deopt to enable. 20311cb0ef41Sopenharmony_ci void RecordDeoptReason(DeoptimizeReason reason, uint32_t node_id, 20321cb0ef41Sopenharmony_ci SourcePosition position, int id); 20331cb0ef41Sopenharmony_ci 20341cb0ef41Sopenharmony_ci // Writes a single word of data in the code stream. 20351cb0ef41Sopenharmony_ci // Used for inline tables, e.g., jump-tables. 20361cb0ef41Sopenharmony_ci void db(uint8_t data); 20371cb0ef41Sopenharmony_ci void dd(uint32_t data, RelocInfo::Mode rmode = RelocInfo::NO_INFO); 20381cb0ef41Sopenharmony_ci void dq(uint64_t data, RelocInfo::Mode rmode = RelocInfo::NO_INFO); 20391cb0ef41Sopenharmony_ci void dp(uintptr_t data, RelocInfo::Mode rmode = RelocInfo::NO_INFO) { 20401cb0ef41Sopenharmony_ci dq(data, rmode); 20411cb0ef41Sopenharmony_ci } 20421cb0ef41Sopenharmony_ci void dq(Label* label); 20431cb0ef41Sopenharmony_ci 20441cb0ef41Sopenharmony_ci // Patch entries for partial constant pool. 20451cb0ef41Sopenharmony_ci void PatchConstPool(); 20461cb0ef41Sopenharmony_ci 20471cb0ef41Sopenharmony_ci // Check if use partial constant pool for this rmode. 20481cb0ef41Sopenharmony_ci static bool UseConstPoolFor(RelocInfo::Mode rmode); 20491cb0ef41Sopenharmony_ci 20501cb0ef41Sopenharmony_ci // Check if there is less than kGap bytes available in the buffer. 20511cb0ef41Sopenharmony_ci // If this is the case, we need to grow the buffer before emitting 20521cb0ef41Sopenharmony_ci // an instruction or relocation information. 20531cb0ef41Sopenharmony_ci inline bool buffer_overflow() const { 20541cb0ef41Sopenharmony_ci return pc_ >= reloc_info_writer.pos() - kGap; 20551cb0ef41Sopenharmony_ci } 20561cb0ef41Sopenharmony_ci 20571cb0ef41Sopenharmony_ci // Get the number of bytes available in the buffer. 20581cb0ef41Sopenharmony_ci inline int available_space() const { 20591cb0ef41Sopenharmony_ci return static_cast<int>(reloc_info_writer.pos() - pc_); 20601cb0ef41Sopenharmony_ci } 20611cb0ef41Sopenharmony_ci 20621cb0ef41Sopenharmony_ci static bool IsNop(Address addr); 20631cb0ef41Sopenharmony_ci 20641cb0ef41Sopenharmony_ci // Avoid overflows for displacements etc. 20651cb0ef41Sopenharmony_ci static constexpr int kMaximalBufferSize = 512 * MB; 20661cb0ef41Sopenharmony_ci 20671cb0ef41Sopenharmony_ci byte byte_at(int pos) { return buffer_start_[pos]; } 20681cb0ef41Sopenharmony_ci void set_byte_at(int pos, byte value) { buffer_start_[pos] = value; } 20691cb0ef41Sopenharmony_ci 20701cb0ef41Sopenharmony_ci#if defined(V8_OS_WIN_X64) 20711cb0ef41Sopenharmony_ci win64_unwindinfo::BuiltinUnwindInfo GetUnwindInfo() const; 20721cb0ef41Sopenharmony_ci#endif 20731cb0ef41Sopenharmony_ci 20741cb0ef41Sopenharmony_ci protected: 20751cb0ef41Sopenharmony_ci // Call near indirect 20761cb0ef41Sopenharmony_ci void call(Operand operand); 20771cb0ef41Sopenharmony_ci 20781cb0ef41Sopenharmony_ci private: 20791cb0ef41Sopenharmony_ci Address addr_at(int pos) { 20801cb0ef41Sopenharmony_ci return reinterpret_cast<Address>(buffer_start_ + pos); 20811cb0ef41Sopenharmony_ci } 20821cb0ef41Sopenharmony_ci uint32_t long_at(int pos) { 20831cb0ef41Sopenharmony_ci return ReadUnalignedValue<uint32_t>(addr_at(pos)); 20841cb0ef41Sopenharmony_ci } 20851cb0ef41Sopenharmony_ci void long_at_put(int pos, uint32_t x) { 20861cb0ef41Sopenharmony_ci WriteUnalignedValue(addr_at(pos), x); 20871cb0ef41Sopenharmony_ci } 20881cb0ef41Sopenharmony_ci 20891cb0ef41Sopenharmony_ci // code emission 20901cb0ef41Sopenharmony_ci void GrowBuffer(); 20911cb0ef41Sopenharmony_ci 20921cb0ef41Sopenharmony_ci void emit(byte x) { *pc_++ = x; } 20931cb0ef41Sopenharmony_ci inline void emitl(uint32_t x); 20941cb0ef41Sopenharmony_ci inline void emitq(uint64_t x); 20951cb0ef41Sopenharmony_ci inline void emitw(uint16_t x); 20961cb0ef41Sopenharmony_ci inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode); 20971cb0ef41Sopenharmony_ci inline void emit(Immediate x); 20981cb0ef41Sopenharmony_ci inline void emit(Immediate64 x); 20991cb0ef41Sopenharmony_ci 21001cb0ef41Sopenharmony_ci // Emits a REX prefix that encodes a 64-bit operand size and 21011cb0ef41Sopenharmony_ci // the top bit of both register codes. 21021cb0ef41Sopenharmony_ci // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 21031cb0ef41Sopenharmony_ci // REX.W is set. 21041cb0ef41Sopenharmony_ci inline void emit_rex_64(XMMRegister reg, Register rm_reg); 21051cb0ef41Sopenharmony_ci inline void emit_rex_64(Register reg, XMMRegister rm_reg); 21061cb0ef41Sopenharmony_ci inline void emit_rex_64(Register reg, Register rm_reg); 21071cb0ef41Sopenharmony_ci inline void emit_rex_64(XMMRegister reg, XMMRegister rm_reg); 21081cb0ef41Sopenharmony_ci 21091cb0ef41Sopenharmony_ci // Emits a REX prefix that encodes a 64-bit operand size and 21101cb0ef41Sopenharmony_ci // the top bit of the destination, index, and base register codes. 21111cb0ef41Sopenharmony_ci // The high bit of reg is used for REX.R, the high bit of op's base 21121cb0ef41Sopenharmony_ci // register is used for REX.B, and the high bit of op's index register 21131cb0ef41Sopenharmony_ci // is used for REX.X. REX.W is set. 21141cb0ef41Sopenharmony_ci inline void emit_rex_64(Register reg, Operand op); 21151cb0ef41Sopenharmony_ci inline void emit_rex_64(XMMRegister reg, Operand op); 21161cb0ef41Sopenharmony_ci 21171cb0ef41Sopenharmony_ci // Emits a REX prefix that encodes a 64-bit operand size and 21181cb0ef41Sopenharmony_ci // the top bit of the register code. 21191cb0ef41Sopenharmony_ci // The high bit of register is used for REX.B. 21201cb0ef41Sopenharmony_ci // REX.W is set and REX.R and REX.X are clear. 21211cb0ef41Sopenharmony_ci inline void emit_rex_64(Register rm_reg); 21221cb0ef41Sopenharmony_ci 21231cb0ef41Sopenharmony_ci // Emits a REX prefix that encodes a 64-bit operand size and 21241cb0ef41Sopenharmony_ci // the top bit of the index and base register codes. 21251cb0ef41Sopenharmony_ci // The high bit of op's base register is used for REX.B, and the high 21261cb0ef41Sopenharmony_ci // bit of op's index register is used for REX.X. 21271cb0ef41Sopenharmony_ci // REX.W is set and REX.R clear. 21281cb0ef41Sopenharmony_ci inline void emit_rex_64(Operand op); 21291cb0ef41Sopenharmony_ci 21301cb0ef41Sopenharmony_ci // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size. 21311cb0ef41Sopenharmony_ci void emit_rex_64() { emit(0x48); } 21321cb0ef41Sopenharmony_ci 21331cb0ef41Sopenharmony_ci // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 21341cb0ef41Sopenharmony_ci // REX.W is clear. 21351cb0ef41Sopenharmony_ci inline void emit_rex_32(Register reg, Register rm_reg); 21361cb0ef41Sopenharmony_ci 21371cb0ef41Sopenharmony_ci // The high bit of reg is used for REX.R, the high bit of op's base 21381cb0ef41Sopenharmony_ci // register is used for REX.B, and the high bit of op's index register 21391cb0ef41Sopenharmony_ci // is used for REX.X. REX.W is cleared. 21401cb0ef41Sopenharmony_ci inline void emit_rex_32(Register reg, Operand op); 21411cb0ef41Sopenharmony_ci 21421cb0ef41Sopenharmony_ci // High bit of rm_reg goes to REX.B. 21431cb0ef41Sopenharmony_ci // REX.W, REX.R and REX.X are clear. 21441cb0ef41Sopenharmony_ci inline void emit_rex_32(Register rm_reg); 21451cb0ef41Sopenharmony_ci 21461cb0ef41Sopenharmony_ci // High bit of base goes to REX.B and high bit of index to REX.X. 21471cb0ef41Sopenharmony_ci // REX.W and REX.R are clear. 21481cb0ef41Sopenharmony_ci inline void emit_rex_32(Operand op); 21491cb0ef41Sopenharmony_ci 21501cb0ef41Sopenharmony_ci // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 21511cb0ef41Sopenharmony_ci // REX.W is cleared. If no REX bits are set, no byte is emitted. 21521cb0ef41Sopenharmony_ci inline void emit_optional_rex_32(Register reg, Register rm_reg); 21531cb0ef41Sopenharmony_ci 21541cb0ef41Sopenharmony_ci // The high bit of reg is used for REX.R, the high bit of op's base 21551cb0ef41Sopenharmony_ci // register is used for REX.B, and the high bit of op's index register 21561cb0ef41Sopenharmony_ci // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing 21571cb0ef41Sopenharmony_ci // is emitted. 21581cb0ef41Sopenharmony_ci inline void emit_optional_rex_32(Register reg, Operand op); 21591cb0ef41Sopenharmony_ci 21601cb0ef41Sopenharmony_ci // As for emit_optional_rex_32(Register, Register), except that 21611cb0ef41Sopenharmony_ci // the registers are XMM registers. 21621cb0ef41Sopenharmony_ci inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base); 21631cb0ef41Sopenharmony_ci 21641cb0ef41Sopenharmony_ci // As for emit_optional_rex_32(Register, Register), except that 21651cb0ef41Sopenharmony_ci // one of the registers is an XMM registers. 21661cb0ef41Sopenharmony_ci inline void emit_optional_rex_32(XMMRegister reg, Register base); 21671cb0ef41Sopenharmony_ci 21681cb0ef41Sopenharmony_ci // As for emit_optional_rex_32(Register, Register), except that 21691cb0ef41Sopenharmony_ci // one of the registers is an XMM registers. 21701cb0ef41Sopenharmony_ci inline void emit_optional_rex_32(Register reg, XMMRegister base); 21711cb0ef41Sopenharmony_ci 21721cb0ef41Sopenharmony_ci // As for emit_optional_rex_32(Register, Operand), except that 21731cb0ef41Sopenharmony_ci // the register is an XMM register. 21741cb0ef41Sopenharmony_ci inline void emit_optional_rex_32(XMMRegister reg, Operand op); 21751cb0ef41Sopenharmony_ci 21761cb0ef41Sopenharmony_ci // Optionally do as emit_rex_32(Register) if the register number has 21771cb0ef41Sopenharmony_ci // the high bit set. 21781cb0ef41Sopenharmony_ci inline void emit_optional_rex_32(Register rm_reg); 21791cb0ef41Sopenharmony_ci inline void emit_optional_rex_32(XMMRegister rm_reg); 21801cb0ef41Sopenharmony_ci 21811cb0ef41Sopenharmony_ci // Optionally do as emit_rex_32(Operand) if the operand register 21821cb0ef41Sopenharmony_ci // numbers have a high bit set. 21831cb0ef41Sopenharmony_ci inline void emit_optional_rex_32(Operand op); 21841cb0ef41Sopenharmony_ci 21851cb0ef41Sopenharmony_ci // Calls emit_rex_32(Register) for all non-byte registers. 21861cb0ef41Sopenharmony_ci inline void emit_optional_rex_8(Register reg); 21871cb0ef41Sopenharmony_ci 21881cb0ef41Sopenharmony_ci // Calls emit_rex_32(Register, Operand) for all non-byte registers, and 21891cb0ef41Sopenharmony_ci // emit_optional_rex_32(Register, Operand) for byte registers. 21901cb0ef41Sopenharmony_ci inline void emit_optional_rex_8(Register reg, Operand op); 21911cb0ef41Sopenharmony_ci 21921cb0ef41Sopenharmony_ci void emit_rex(int size) { 21931cb0ef41Sopenharmony_ci if (size == kInt64Size) { 21941cb0ef41Sopenharmony_ci emit_rex_64(); 21951cb0ef41Sopenharmony_ci } else { 21961cb0ef41Sopenharmony_ci DCHECK_EQ(size, kInt32Size); 21971cb0ef41Sopenharmony_ci } 21981cb0ef41Sopenharmony_ci } 21991cb0ef41Sopenharmony_ci 22001cb0ef41Sopenharmony_ci template <class P1> 22011cb0ef41Sopenharmony_ci void emit_rex(P1 p1, int size) { 22021cb0ef41Sopenharmony_ci if (size == kInt64Size) { 22031cb0ef41Sopenharmony_ci emit_rex_64(p1); 22041cb0ef41Sopenharmony_ci } else { 22051cb0ef41Sopenharmony_ci DCHECK_EQ(size, kInt32Size); 22061cb0ef41Sopenharmony_ci emit_optional_rex_32(p1); 22071cb0ef41Sopenharmony_ci } 22081cb0ef41Sopenharmony_ci } 22091cb0ef41Sopenharmony_ci 22101cb0ef41Sopenharmony_ci template <class P1, class P2> 22111cb0ef41Sopenharmony_ci void emit_rex(P1 p1, P2 p2, int size) { 22121cb0ef41Sopenharmony_ci if (size == kInt64Size) { 22131cb0ef41Sopenharmony_ci emit_rex_64(p1, p2); 22141cb0ef41Sopenharmony_ci } else { 22151cb0ef41Sopenharmony_ci DCHECK_EQ(size, kInt32Size); 22161cb0ef41Sopenharmony_ci emit_optional_rex_32(p1, p2); 22171cb0ef41Sopenharmony_ci } 22181cb0ef41Sopenharmony_ci } 22191cb0ef41Sopenharmony_ci 22201cb0ef41Sopenharmony_ci // Emit vex prefix 22211cb0ef41Sopenharmony_ci void emit_vex2_byte0() { emit(0xc5); } 22221cb0ef41Sopenharmony_ci inline void emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l, 22231cb0ef41Sopenharmony_ci SIMDPrefix pp); 22241cb0ef41Sopenharmony_ci void emit_vex3_byte0() { emit(0xc4); } 22251cb0ef41Sopenharmony_ci inline void emit_vex3_byte1(XMMRegister reg, XMMRegister rm, LeadingOpcode m); 22261cb0ef41Sopenharmony_ci inline void emit_vex3_byte1(XMMRegister reg, Operand rm, LeadingOpcode m); 22271cb0ef41Sopenharmony_ci inline void emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l, 22281cb0ef41Sopenharmony_ci SIMDPrefix pp); 22291cb0ef41Sopenharmony_ci inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, XMMRegister rm, 22301cb0ef41Sopenharmony_ci VectorLength l, SIMDPrefix pp, LeadingOpcode m, 22311cb0ef41Sopenharmony_ci VexW w); 22321cb0ef41Sopenharmony_ci inline void emit_vex_prefix(Register reg, Register v, Register rm, 22331cb0ef41Sopenharmony_ci VectorLength l, SIMDPrefix pp, LeadingOpcode m, 22341cb0ef41Sopenharmony_ci VexW w); 22351cb0ef41Sopenharmony_ci inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, Operand rm, 22361cb0ef41Sopenharmony_ci VectorLength l, SIMDPrefix pp, LeadingOpcode m, 22371cb0ef41Sopenharmony_ci VexW w); 22381cb0ef41Sopenharmony_ci inline void emit_vex_prefix(Register reg, Register v, Operand rm, 22391cb0ef41Sopenharmony_ci VectorLength l, SIMDPrefix pp, LeadingOpcode m, 22401cb0ef41Sopenharmony_ci VexW w); 22411cb0ef41Sopenharmony_ci 22421cb0ef41Sopenharmony_ci // Emit the ModR/M byte, and optionally the SIB byte and 22431cb0ef41Sopenharmony_ci // 1- or 4-byte offset for a memory operand. Also encodes 22441cb0ef41Sopenharmony_ci // the second operand of the operation, a register or operation 22451cb0ef41Sopenharmony_ci // subcode, into the reg field of the ModR/M byte. 22461cb0ef41Sopenharmony_ci void emit_operand(Register reg, Operand adr) { 22471cb0ef41Sopenharmony_ci emit_operand(reg.low_bits(), adr); 22481cb0ef41Sopenharmony_ci } 22491cb0ef41Sopenharmony_ci 22501cb0ef41Sopenharmony_ci // Emit the ModR/M byte, and optionally the SIB byte and 22511cb0ef41Sopenharmony_ci // 1- or 4-byte offset for a memory operand. Also used to encode 22521cb0ef41Sopenharmony_ci // a three-bit opcode extension into the ModR/M byte. 22531cb0ef41Sopenharmony_ci void emit_operand(int rm, Operand adr); 22541cb0ef41Sopenharmony_ci 22551cb0ef41Sopenharmony_ci // Emit a ModR/M byte with registers coded in the reg and rm_reg fields. 22561cb0ef41Sopenharmony_ci void emit_modrm(Register reg, Register rm_reg) { 22571cb0ef41Sopenharmony_ci emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits()); 22581cb0ef41Sopenharmony_ci } 22591cb0ef41Sopenharmony_ci 22601cb0ef41Sopenharmony_ci // Emit a ModR/M byte with an operation subcode in the reg field and 22611cb0ef41Sopenharmony_ci // a register in the rm_reg field. 22621cb0ef41Sopenharmony_ci void emit_modrm(int code, Register rm_reg) { 22631cb0ef41Sopenharmony_ci DCHECK(is_uint3(code)); 22641cb0ef41Sopenharmony_ci emit(0xC0 | code << 3 | rm_reg.low_bits()); 22651cb0ef41Sopenharmony_ci } 22661cb0ef41Sopenharmony_ci 22671cb0ef41Sopenharmony_ci // Emit the code-object-relative offset of the label's position 22681cb0ef41Sopenharmony_ci inline void emit_code_relative_offset(Label* label); 22691cb0ef41Sopenharmony_ci 22701cb0ef41Sopenharmony_ci // The first argument is the reg field, the second argument is the r/m field. 22711cb0ef41Sopenharmony_ci void emit_sse_operand(XMMRegister dst, XMMRegister src); 22721cb0ef41Sopenharmony_ci void emit_sse_operand(XMMRegister reg, Operand adr); 22731cb0ef41Sopenharmony_ci void emit_sse_operand(Register reg, Operand adr); 22741cb0ef41Sopenharmony_ci void emit_sse_operand(XMMRegister dst, Register src); 22751cb0ef41Sopenharmony_ci void emit_sse_operand(Register dst, XMMRegister src); 22761cb0ef41Sopenharmony_ci void emit_sse_operand(XMMRegister dst); 22771cb0ef41Sopenharmony_ci 22781cb0ef41Sopenharmony_ci // Emit machine code for one of the operations ADD, ADC, SUB, SBC, 22791cb0ef41Sopenharmony_ci // AND, OR, XOR, or CMP. The encodings of these operations are all 22801cb0ef41Sopenharmony_ci // similar, differing just in the opcode or in the reg field of the 22811cb0ef41Sopenharmony_ci // ModR/M byte. 22821cb0ef41Sopenharmony_ci void arithmetic_op_8(byte opcode, Register reg, Register rm_reg); 22831cb0ef41Sopenharmony_ci void arithmetic_op_8(byte opcode, Register reg, Operand rm_reg); 22841cb0ef41Sopenharmony_ci void arithmetic_op_16(byte opcode, Register reg, Register rm_reg); 22851cb0ef41Sopenharmony_ci void arithmetic_op_16(byte opcode, Register reg, Operand rm_reg); 22861cb0ef41Sopenharmony_ci // Operate on operands/registers with pointer size, 32-bit or 64-bit size. 22871cb0ef41Sopenharmony_ci void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size); 22881cb0ef41Sopenharmony_ci void arithmetic_op(byte opcode, Register reg, Operand rm_reg, int size); 22891cb0ef41Sopenharmony_ci // Operate on a byte in memory or register. 22901cb0ef41Sopenharmony_ci void immediate_arithmetic_op_8(byte subcode, Register dst, Immediate src); 22911cb0ef41Sopenharmony_ci void immediate_arithmetic_op_8(byte subcode, Operand dst, Immediate src); 22921cb0ef41Sopenharmony_ci // Operate on a word in memory or register. 22931cb0ef41Sopenharmony_ci void immediate_arithmetic_op_16(byte subcode, Register dst, Immediate src); 22941cb0ef41Sopenharmony_ci void immediate_arithmetic_op_16(byte subcode, Operand dst, Immediate src); 22951cb0ef41Sopenharmony_ci // Operate on operands/registers with pointer size, 32-bit or 64-bit size. 22961cb0ef41Sopenharmony_ci void immediate_arithmetic_op(byte subcode, Register dst, Immediate src, 22971cb0ef41Sopenharmony_ci int size); 22981cb0ef41Sopenharmony_ci void immediate_arithmetic_op(byte subcode, Operand dst, Immediate src, 22991cb0ef41Sopenharmony_ci int size); 23001cb0ef41Sopenharmony_ci 23011cb0ef41Sopenharmony_ci // Emit machine code for a shift operation. 23021cb0ef41Sopenharmony_ci void shift(Operand dst, Immediate shift_amount, int subcode, int size); 23031cb0ef41Sopenharmony_ci void shift(Register dst, Immediate shift_amount, int subcode, int size); 23041cb0ef41Sopenharmony_ci // Shift dst by cl % 64 bits. 23051cb0ef41Sopenharmony_ci void shift(Register dst, int subcode, int size); 23061cb0ef41Sopenharmony_ci void shift(Operand dst, int subcode, int size); 23071cb0ef41Sopenharmony_ci 23081cb0ef41Sopenharmony_ci void emit_farith(int b1, int b2, int i); 23091cb0ef41Sopenharmony_ci 23101cb0ef41Sopenharmony_ci // labels 23111cb0ef41Sopenharmony_ci // void print(Label* L); 23121cb0ef41Sopenharmony_ci void bind_to(Label* L, int pos); 23131cb0ef41Sopenharmony_ci 23141cb0ef41Sopenharmony_ci // record reloc info for current pc_ 23151cb0ef41Sopenharmony_ci void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 23161cb0ef41Sopenharmony_ci 23171cb0ef41Sopenharmony_ci // Arithmetics 23181cb0ef41Sopenharmony_ci void emit_add(Register dst, Register src, int size) { 23191cb0ef41Sopenharmony_ci arithmetic_op(0x03, dst, src, size); 23201cb0ef41Sopenharmony_ci } 23211cb0ef41Sopenharmony_ci 23221cb0ef41Sopenharmony_ci void emit_add(Register dst, Immediate src, int size) { 23231cb0ef41Sopenharmony_ci immediate_arithmetic_op(0x0, dst, src, size); 23241cb0ef41Sopenharmony_ci } 23251cb0ef41Sopenharmony_ci 23261cb0ef41Sopenharmony_ci void emit_add(Register dst, Operand src, int size) { 23271cb0ef41Sopenharmony_ci arithmetic_op(0x03, dst, src, size); 23281cb0ef41Sopenharmony_ci } 23291cb0ef41Sopenharmony_ci 23301cb0ef41Sopenharmony_ci void emit_add(Operand dst, Register src, int size) { 23311cb0ef41Sopenharmony_ci arithmetic_op(0x1, src, dst, size); 23321cb0ef41Sopenharmony_ci } 23331cb0ef41Sopenharmony_ci 23341cb0ef41Sopenharmony_ci void emit_add(Operand dst, Immediate src, int size) { 23351cb0ef41Sopenharmony_ci immediate_arithmetic_op(0x0, dst, src, size); 23361cb0ef41Sopenharmony_ci } 23371cb0ef41Sopenharmony_ci 23381cb0ef41Sopenharmony_ci void emit_and(Register dst, Register src, int size) { 23391cb0ef41Sopenharmony_ci arithmetic_op(0x23, dst, src, size); 23401cb0ef41Sopenharmony_ci } 23411cb0ef41Sopenharmony_ci 23421cb0ef41Sopenharmony_ci void emit_and(Register dst, Operand src, int size) { 23431cb0ef41Sopenharmony_ci arithmetic_op(0x23, dst, src, size); 23441cb0ef41Sopenharmony_ci } 23451cb0ef41Sopenharmony_ci 23461cb0ef41Sopenharmony_ci void emit_and(Operand dst, Register src, int size) { 23471cb0ef41Sopenharmony_ci arithmetic_op(0x21, src, dst, size); 23481cb0ef41Sopenharmony_ci } 23491cb0ef41Sopenharmony_ci 23501cb0ef41Sopenharmony_ci void emit_and(Register dst, Immediate src, int size) { 23511cb0ef41Sopenharmony_ci immediate_arithmetic_op(0x4, dst, src, size); 23521cb0ef41Sopenharmony_ci } 23531cb0ef41Sopenharmony_ci 23541cb0ef41Sopenharmony_ci void emit_and(Operand dst, Immediate src, int size) { 23551cb0ef41Sopenharmony_ci immediate_arithmetic_op(0x4, dst, src, size); 23561cb0ef41Sopenharmony_ci } 23571cb0ef41Sopenharmony_ci 23581cb0ef41Sopenharmony_ci void emit_cmp(Register dst, Register src, int size) { 23591cb0ef41Sopenharmony_ci arithmetic_op(0x3B, dst, src, size); 23601cb0ef41Sopenharmony_ci } 23611cb0ef41Sopenharmony_ci 23621cb0ef41Sopenharmony_ci void emit_cmp(Register dst, Operand src, int size) { 23631cb0ef41Sopenharmony_ci arithmetic_op(0x3B, dst, src, size); 23641cb0ef41Sopenharmony_ci } 23651cb0ef41Sopenharmony_ci 23661cb0ef41Sopenharmony_ci void emit_cmp(Operand dst, Register src, int size) { 23671cb0ef41Sopenharmony_ci arithmetic_op(0x39, src, dst, size); 23681cb0ef41Sopenharmony_ci } 23691cb0ef41Sopenharmony_ci 23701cb0ef41Sopenharmony_ci void emit_cmp(Register dst, Immediate src, int size) { 23711cb0ef41Sopenharmony_ci immediate_arithmetic_op(0x7, dst, src, size); 23721cb0ef41Sopenharmony_ci } 23731cb0ef41Sopenharmony_ci 23741cb0ef41Sopenharmony_ci void emit_cmp(Operand dst, Immediate src, int size) { 23751cb0ef41Sopenharmony_ci immediate_arithmetic_op(0x7, dst, src, size); 23761cb0ef41Sopenharmony_ci } 23771cb0ef41Sopenharmony_ci 23781cb0ef41Sopenharmony_ci // Compare {al,ax,eax,rax} with src. If equal, set ZF and write dst into 23791cb0ef41Sopenharmony_ci // src. Otherwise clear ZF and write src into {al,ax,eax,rax}. This 23801cb0ef41Sopenharmony_ci // operation is only atomic if prefixed by the lock instruction. 23811cb0ef41Sopenharmony_ci void emit_cmpxchg(Operand dst, Register src, int size); 23821cb0ef41Sopenharmony_ci 23831cb0ef41Sopenharmony_ci void emit_dec(Register dst, int size); 23841cb0ef41Sopenharmony_ci void emit_dec(Operand dst, int size); 23851cb0ef41Sopenharmony_ci 23861cb0ef41Sopenharmony_ci // Divide rdx:rax by src. Quotient in rax, remainder in rdx when size is 64. 23871cb0ef41Sopenharmony_ci // Divide edx:eax by lower 32 bits of src. Quotient in eax, remainder in edx 23881cb0ef41Sopenharmony_ci // when size is 32. 23891cb0ef41Sopenharmony_ci void emit_idiv(Register src, int size); 23901cb0ef41Sopenharmony_ci void emit_div(Register src, int size); 23911cb0ef41Sopenharmony_ci 23921cb0ef41Sopenharmony_ci // Signed multiply instructions. 23931cb0ef41Sopenharmony_ci // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32. 23941cb0ef41Sopenharmony_ci void emit_imul(Register src, int size); 23951cb0ef41Sopenharmony_ci void emit_imul(Operand src, int size); 23961cb0ef41Sopenharmony_ci void emit_imul(Register dst, Register src, int size); 23971cb0ef41Sopenharmony_ci void emit_imul(Register dst, Operand src, int size); 23981cb0ef41Sopenharmony_ci void emit_imul(Register dst, Register src, Immediate imm, int size); 23991cb0ef41Sopenharmony_ci void emit_imul(Register dst, Operand src, Immediate imm, int size); 24001cb0ef41Sopenharmony_ci 24011cb0ef41Sopenharmony_ci void emit_inc(Register dst, int size); 24021cb0ef41Sopenharmony_ci void emit_inc(Operand dst, int size); 24031cb0ef41Sopenharmony_ci 24041cb0ef41Sopenharmony_ci void emit_lea(Register dst, Operand src, int size); 24051cb0ef41Sopenharmony_ci 24061cb0ef41Sopenharmony_ci void emit_mov(Register dst, Operand src, int size); 24071cb0ef41Sopenharmony_ci void emit_mov(Register dst, Register src, int size); 24081cb0ef41Sopenharmony_ci void emit_mov(Operand dst, Register src, int size); 24091cb0ef41Sopenharmony_ci void emit_mov(Register dst, Immediate value, int size); 24101cb0ef41Sopenharmony_ci void emit_mov(Operand dst, Immediate value, int size); 24111cb0ef41Sopenharmony_ci void emit_mov(Register dst, Immediate64 value, int size); 24121cb0ef41Sopenharmony_ci 24131cb0ef41Sopenharmony_ci void emit_movzxb(Register dst, Operand src, int size); 24141cb0ef41Sopenharmony_ci void emit_movzxb(Register dst, Register src, int size); 24151cb0ef41Sopenharmony_ci void emit_movzxw(Register dst, Operand src, int size); 24161cb0ef41Sopenharmony_ci void emit_movzxw(Register dst, Register src, int size); 24171cb0ef41Sopenharmony_ci 24181cb0ef41Sopenharmony_ci void emit_neg(Register dst, int size); 24191cb0ef41Sopenharmony_ci void emit_neg(Operand dst, int size); 24201cb0ef41Sopenharmony_ci 24211cb0ef41Sopenharmony_ci void emit_not(Register dst, int size); 24221cb0ef41Sopenharmony_ci void emit_not(Operand dst, int size); 24231cb0ef41Sopenharmony_ci 24241cb0ef41Sopenharmony_ci void emit_or(Register dst, Register src, int size) { 24251cb0ef41Sopenharmony_ci arithmetic_op(0x0B, dst, src, size); 24261cb0ef41Sopenharmony_ci } 24271cb0ef41Sopenharmony_ci 24281cb0ef41Sopenharmony_ci void emit_or(Register dst, Operand src, int size) { 24291cb0ef41Sopenharmony_ci arithmetic_op(0x0B, dst, src, size); 24301cb0ef41Sopenharmony_ci } 24311cb0ef41Sopenharmony_ci 24321cb0ef41Sopenharmony_ci void emit_or(Operand dst, Register src, int size) { 24331cb0ef41Sopenharmony_ci arithmetic_op(0x9, src, dst, size); 24341cb0ef41Sopenharmony_ci } 24351cb0ef41Sopenharmony_ci 24361cb0ef41Sopenharmony_ci void emit_or(Register dst, Immediate src, int size) { 24371cb0ef41Sopenharmony_ci immediate_arithmetic_op(0x1, dst, src, size); 24381cb0ef41Sopenharmony_ci } 24391cb0ef41Sopenharmony_ci 24401cb0ef41Sopenharmony_ci void emit_or(Operand dst, Immediate src, int size) { 24411cb0ef41Sopenharmony_ci immediate_arithmetic_op(0x1, dst, src, size); 24421cb0ef41Sopenharmony_ci } 24431cb0ef41Sopenharmony_ci 24441cb0ef41Sopenharmony_ci void emit_repmovs(int size); 24451cb0ef41Sopenharmony_ci 24461cb0ef41Sopenharmony_ci void emit_sbb(Register dst, Register src, int size) { 24471cb0ef41Sopenharmony_ci arithmetic_op(0x1b, dst, src, size); 24481cb0ef41Sopenharmony_ci } 24491cb0ef41Sopenharmony_ci 24501cb0ef41Sopenharmony_ci void emit_sub(Register dst, Register src, int size) { 24511cb0ef41Sopenharmony_ci arithmetic_op(0x2B, dst, src, size); 24521cb0ef41Sopenharmony_ci } 24531cb0ef41Sopenharmony_ci 24541cb0ef41Sopenharmony_ci void emit_sub(Register dst, Immediate src, int size) { 24551cb0ef41Sopenharmony_ci immediate_arithmetic_op(0x5, dst, src, size); 24561cb0ef41Sopenharmony_ci } 24571cb0ef41Sopenharmony_ci 24581cb0ef41Sopenharmony_ci void emit_sub(Register dst, Operand src, int size) { 24591cb0ef41Sopenharmony_ci arithmetic_op(0x2B, dst, src, size); 24601cb0ef41Sopenharmony_ci } 24611cb0ef41Sopenharmony_ci 24621cb0ef41Sopenharmony_ci void emit_sub(Operand dst, Register src, int size) { 24631cb0ef41Sopenharmony_ci arithmetic_op(0x29, src, dst, size); 24641cb0ef41Sopenharmony_ci } 24651cb0ef41Sopenharmony_ci 24661cb0ef41Sopenharmony_ci void emit_sub(Operand dst, Immediate src, int size) { 24671cb0ef41Sopenharmony_ci immediate_arithmetic_op(0x5, dst, src, size); 24681cb0ef41Sopenharmony_ci } 24691cb0ef41Sopenharmony_ci 24701cb0ef41Sopenharmony_ci void emit_test(Register dst, Register src, int size); 24711cb0ef41Sopenharmony_ci void emit_test(Register reg, Immediate mask, int size); 24721cb0ef41Sopenharmony_ci void emit_test(Operand op, Register reg, int size); 24731cb0ef41Sopenharmony_ci void emit_test(Operand op, Immediate mask, int size); 24741cb0ef41Sopenharmony_ci void emit_test(Register reg, Operand op, int size) { 24751cb0ef41Sopenharmony_ci return emit_test(op, reg, size); 24761cb0ef41Sopenharmony_ci } 24771cb0ef41Sopenharmony_ci 24781cb0ef41Sopenharmony_ci void emit_xchg(Register dst, Register src, int size); 24791cb0ef41Sopenharmony_ci void emit_xchg(Register dst, Operand src, int size); 24801cb0ef41Sopenharmony_ci 24811cb0ef41Sopenharmony_ci void emit_xor(Register dst, Register src, int size) { 24821cb0ef41Sopenharmony_ci if (size == kInt64Size && dst.code() == src.code()) { 24831cb0ef41Sopenharmony_ci // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore 24841cb0ef41Sopenharmony_ci // there is no need to make this a 64 bit operation. 24851cb0ef41Sopenharmony_ci arithmetic_op(0x33, dst, src, kInt32Size); 24861cb0ef41Sopenharmony_ci } else { 24871cb0ef41Sopenharmony_ci arithmetic_op(0x33, dst, src, size); 24881cb0ef41Sopenharmony_ci } 24891cb0ef41Sopenharmony_ci } 24901cb0ef41Sopenharmony_ci 24911cb0ef41Sopenharmony_ci void emit_xor(Register dst, Operand src, int size) { 24921cb0ef41Sopenharmony_ci arithmetic_op(0x33, dst, src, size); 24931cb0ef41Sopenharmony_ci } 24941cb0ef41Sopenharmony_ci 24951cb0ef41Sopenharmony_ci void emit_xor(Register dst, Immediate src, int size) { 24961cb0ef41Sopenharmony_ci immediate_arithmetic_op(0x6, dst, src, size); 24971cb0ef41Sopenharmony_ci } 24981cb0ef41Sopenharmony_ci 24991cb0ef41Sopenharmony_ci void emit_xor(Operand dst, Immediate src, int size) { 25001cb0ef41Sopenharmony_ci immediate_arithmetic_op(0x6, dst, src, size); 25011cb0ef41Sopenharmony_ci } 25021cb0ef41Sopenharmony_ci 25031cb0ef41Sopenharmony_ci void emit_xor(Operand dst, Register src, int size) { 25041cb0ef41Sopenharmony_ci arithmetic_op(0x31, src, dst, size); 25051cb0ef41Sopenharmony_ci } 25061cb0ef41Sopenharmony_ci 25071cb0ef41Sopenharmony_ci // Most BMI instructions are similar. 25081cb0ef41Sopenharmony_ci void bmi1q(byte op, Register reg, Register vreg, Register rm); 25091cb0ef41Sopenharmony_ci void bmi1q(byte op, Register reg, Register vreg, Operand rm); 25101cb0ef41Sopenharmony_ci void bmi1l(byte op, Register reg, Register vreg, Register rm); 25111cb0ef41Sopenharmony_ci void bmi1l(byte op, Register reg, Register vreg, Operand rm); 25121cb0ef41Sopenharmony_ci void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm); 25131cb0ef41Sopenharmony_ci void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg, Operand rm); 25141cb0ef41Sopenharmony_ci void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm); 25151cb0ef41Sopenharmony_ci void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg, Operand rm); 25161cb0ef41Sopenharmony_ci 25171cb0ef41Sopenharmony_ci // record the position of jmp/jcc instruction 25181cb0ef41Sopenharmony_ci void record_farjmp_position(Label* L, int pos); 25191cb0ef41Sopenharmony_ci 25201cb0ef41Sopenharmony_ci bool is_optimizable_farjmp(int idx); 25211cb0ef41Sopenharmony_ci 25221cb0ef41Sopenharmony_ci void AllocateAndInstallRequestedHeapObjects(Isolate* isolate); 25231cb0ef41Sopenharmony_ci 25241cb0ef41Sopenharmony_ci int WriteCodeComments(); 25251cb0ef41Sopenharmony_ci 25261cb0ef41Sopenharmony_ci friend class EnsureSpace; 25271cb0ef41Sopenharmony_ci friend class RegExpMacroAssemblerX64; 25281cb0ef41Sopenharmony_ci 25291cb0ef41Sopenharmony_ci // code generation 25301cb0ef41Sopenharmony_ci RelocInfoWriter reloc_info_writer; 25311cb0ef41Sopenharmony_ci 25321cb0ef41Sopenharmony_ci // Internal reference positions, required for (potential) patching in 25331cb0ef41Sopenharmony_ci // GrowBuffer(); contains only those internal references whose labels 25341cb0ef41Sopenharmony_ci // are already bound. 25351cb0ef41Sopenharmony_ci std::deque<int> internal_reference_positions_; 25361cb0ef41Sopenharmony_ci 25371cb0ef41Sopenharmony_ci // Variables for this instance of assembler 25381cb0ef41Sopenharmony_ci int farjmp_num_ = 0; 25391cb0ef41Sopenharmony_ci std::deque<int> farjmp_positions_; 25401cb0ef41Sopenharmony_ci std::map<Label*, std::vector<int>> label_farjmp_maps_; 25411cb0ef41Sopenharmony_ci 25421cb0ef41Sopenharmony_ci ConstPool constpool_; 25431cb0ef41Sopenharmony_ci 25441cb0ef41Sopenharmony_ci friend class ConstPool; 25451cb0ef41Sopenharmony_ci 25461cb0ef41Sopenharmony_ci#if defined(V8_OS_WIN_X64) 25471cb0ef41Sopenharmony_ci std::unique_ptr<win64_unwindinfo::XdataEncoder> xdata_encoder_; 25481cb0ef41Sopenharmony_ci#endif 25491cb0ef41Sopenharmony_ci}; 25501cb0ef41Sopenharmony_ci 25511cb0ef41Sopenharmony_ciextern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 25521cb0ef41Sopenharmony_civoid Assembler::vinstr(byte op, YMMRegister dst, YMMRegister src1, 25531cb0ef41Sopenharmony_ci YMMRegister src2, SIMDPrefix pp, 25541cb0ef41Sopenharmony_ci LeadingOpcode m, VexW w, CpuFeature feature); 25551cb0ef41Sopenharmony_ciextern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 25561cb0ef41Sopenharmony_civoid Assembler::vinstr(byte op, YMMRegister dst, XMMRegister src1, 25571cb0ef41Sopenharmony_ci XMMRegister src2, SIMDPrefix pp, 25581cb0ef41Sopenharmony_ci LeadingOpcode m, VexW w, CpuFeature feature); 25591cb0ef41Sopenharmony_ciextern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 25601cb0ef41Sopenharmony_civoid Assembler::vinstr(byte op, YMMRegister dst, YMMRegister src1, 25611cb0ef41Sopenharmony_ci Operand src2, SIMDPrefix pp, LeadingOpcode m, 25621cb0ef41Sopenharmony_ci VexW w, CpuFeature feature); 25631cb0ef41Sopenharmony_ciextern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 25641cb0ef41Sopenharmony_civoid Assembler::vinstr(byte op, YMMRegister dst, YMMRegister src1, 25651cb0ef41Sopenharmony_ci XMMRegister src2, SIMDPrefix pp, 25661cb0ef41Sopenharmony_ci LeadingOpcode m, VexW w, CpuFeature feature); 25671cb0ef41Sopenharmony_ciextern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 25681cb0ef41Sopenharmony_civoid Assembler::vinstr(byte op, YMMRegister dst, XMMRegister src1, 25691cb0ef41Sopenharmony_ci Operand src2, SIMDPrefix pp, LeadingOpcode m, 25701cb0ef41Sopenharmony_ci VexW w, CpuFeature feature); 25711cb0ef41Sopenharmony_ci 25721cb0ef41Sopenharmony_ci// Helper class that ensures that there is enough space for generating 25731cb0ef41Sopenharmony_ci// instructions and relocation information. The constructor makes 25741cb0ef41Sopenharmony_ci// sure that there is enough space and (in debug mode) the destructor 25751cb0ef41Sopenharmony_ci// checks that we did not generate too much. 25761cb0ef41Sopenharmony_ciclass EnsureSpace { 25771cb0ef41Sopenharmony_ci public: 25781cb0ef41Sopenharmony_ci explicit V8_INLINE EnsureSpace(Assembler* assembler) : assembler_(assembler) { 25791cb0ef41Sopenharmony_ci if (V8_UNLIKELY(assembler_->buffer_overflow())) assembler_->GrowBuffer(); 25801cb0ef41Sopenharmony_ci#ifdef DEBUG 25811cb0ef41Sopenharmony_ci space_before_ = assembler_->available_space(); 25821cb0ef41Sopenharmony_ci#endif 25831cb0ef41Sopenharmony_ci } 25841cb0ef41Sopenharmony_ci 25851cb0ef41Sopenharmony_ci#ifdef DEBUG 25861cb0ef41Sopenharmony_ci ~EnsureSpace() { 25871cb0ef41Sopenharmony_ci int bytes_generated = space_before_ - assembler_->available_space(); 25881cb0ef41Sopenharmony_ci DCHECK(bytes_generated < assembler_->kGap); 25891cb0ef41Sopenharmony_ci } 25901cb0ef41Sopenharmony_ci#endif 25911cb0ef41Sopenharmony_ci 25921cb0ef41Sopenharmony_ci private: 25931cb0ef41Sopenharmony_ci Assembler* const assembler_; 25941cb0ef41Sopenharmony_ci#ifdef DEBUG 25951cb0ef41Sopenharmony_ci int space_before_; 25961cb0ef41Sopenharmony_ci#endif 25971cb0ef41Sopenharmony_ci}; 25981cb0ef41Sopenharmony_ci 25991cb0ef41Sopenharmony_ci} // namespace internal 26001cb0ef41Sopenharmony_ci} // namespace v8 26011cb0ef41Sopenharmony_ci 26021cb0ef41Sopenharmony_ci#endif // V8_CODEGEN_X64_ASSEMBLER_X64_H_ 2603