filters/exprfilter/jitasm.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright (c) 2009-2011, Hikaru Inoue, Akihiro Yamasaki, | ||
| 2 | // All rights reserved. | ||
| 3 | // | ||
| 4 | // Redistribution and use in source and binary forms, with or without | ||
| 5 | // modification, are permitted provided that the following conditions are | ||
| 6 | // met: | ||
| 7 | // | ||
| 8 | // * Redistributions of source code must retain the above copyright | ||
| 9 | // notice, this list of conditions and the following disclaimer. | ||
| 10 | // * Redistributions in binary form must reproduce the above | ||
| 11 | // copyright notice, this list of conditions and the following | ||
| 12 | // disclaimer in the documentation and/or other materials provided | ||
| 13 | // with the distribution. | ||
| 14 | // * The names of the contributors may not be used to endorse or promote | ||
| 15 | // products derived from this software without specific prior written | ||
| 16 | // permission. | ||
| 17 | // | ||
| 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 29 | // | ||
| 30 | // Changes 2017 by pinterf | ||
| 31 | // - AVX friendly prolog/epilog with vzeroupper | ||
| 32 | // - Aligned stack slots for ymm spill variables | ||
| 33 | // - VEX encoded aligned store and load for temporary xmm/ymm registers | ||
| 34 | // - Fix: false codegen when rearranging multiple working registers in MoveGenerator by | ||
| 35 | // tracking real register usage for an xchg sequence | ||
| 36 | |||
| 37 | #include <stdint.h> | ||
| 38 | |||
| 39 | #pragma once | ||
| 40 | #ifndef JITASM_H | ||
| 41 | #define JITASM_H | ||
| 42 | |||
| 43 | #if defined(_WIN32) | ||
| 44 | #define JITASM_WIN // Windows | ||
| 45 | #endif | ||
| 46 | |||
| 47 | #if (defined(_WIN64) && (defined(_M_AMD64) || defined(_M_X64))) || defined(__x86_64__) | ||
| 48 | #define JITASM64 | ||
| 49 | #endif | ||
| 50 | |||
| 51 | #if defined(__GNUC__) | ||
| 52 | #define JITASM_GCC | ||
| 53 | #endif | ||
| 54 | |||
| 55 | #if !defined(JITASM_MMINTRIN) | ||
| 56 | #if !defined(__GNUC__) || defined(__MMX__) | ||
| 57 | #define JITASM_MMINTRIN 1 | ||
| 58 | #else | ||
| 59 | #define JITASM_MMINTRIN 0 | ||
| 60 | #endif | ||
| 61 | #endif | ||
| 62 | #if !defined(JITASM_XMMINTRIN) | ||
| 63 | #if !defined(__GNUC__) || defined(__SSE__) | ||
| 64 | #define JITASM_XMMINTRIN 1 | ||
| 65 | #else | ||
| 66 | #define JITASM_XMMINTRIN 0 | ||
| 67 | #endif | ||
| 68 | #endif | ||
| 69 | #if !defined(JITASM_EMMINTRIN) | ||
| 70 | #if !defined(__GNUC__) || defined(__SSE2__) | ||
| 71 | #define JITASM_EMMINTRIN 1 | ||
| 72 | #else | ||
| 73 | #define JITASM_EMMINTRIN 0 | ||
| 74 | #endif | ||
| 75 | #endif | ||
| 76 | |||
| 77 | |||
| 78 | #include <string> | ||
| 79 | #include <deque> | ||
| 80 | #include <vector> | ||
| 81 | #include <map> | ||
| 82 | #include <algorithm> | ||
| 83 | #include <string.h> | ||
| 84 | |||
| 85 | #if defined(JITASM_WIN) | ||
| 86 | #include <windows.h> | ||
| 87 | #else | ||
| 88 | #include <unistd.h> | ||
| 89 | #include <sys/types.h> | ||
| 90 | #include <sys/mman.h> | ||
| 91 | #endif | ||
| 92 | |||
| 93 | #if JITASM_MMINTRIN | ||
| 94 | #include <mmintrin.h> | ||
| 95 | #endif | ||
| 96 | #if JITASM_XMMINTRIN | ||
| 97 | #include <xmmintrin.h> | ||
| 98 | #endif | ||
| 99 | #if JITASM_EMMINTRIN | ||
| 100 | #include <emmintrin.h> | ||
| 101 | #endif | ||
| 102 | |||
| 103 | #if _MSC_VER >= 1400 // VC8 or later | ||
| 104 | #include <intrin.h> | ||
| 105 | #endif | ||
| 106 | |||
| 107 | #if defined(JITASM_GCC) | ||
| 108 | #define JITASM_ATTRIBUTE_WEAK | ||
| 109 | // #define JITASM_ATTRIBUTE_WEAK __attribute__((weak)) | ||
| 110 | // PF 20211013 remark, intentionally kept here: | ||
| 111 | // Do not use weak attribute! GCC Bug? | ||
| 112 | // With weak attributes mingw64 g++ 10.3 will miss a few initializations of structs during DLL load, | ||
| 113 | // for example these initializations will never be called(!): | ||
| 114 | // Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r8b = Reg8(R8B); | ||
| 115 | // YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm8 = YmmReg(YMM8); | ||
| 116 | // (list not complete). | ||
| 117 | // But most horribly: after | ||
| 118 | // Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r13d = Reg32(R13D); | ||
| 119 | // but before | ||
| 120 | // Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r14d = Reg32(R14D); | ||
| 121 | // it will overwrite some other, already initialized variable areas at a totally different | ||
| 122 | // memory space, some hundred bytes before. | ||
| 123 | // Anyway, 'weak' is probably not needed, in ExprFilter use case we do not want a different | ||
| 124 | // implementations of these functions. | ||
| 125 | #elif defined(_MSC_VER) | ||
| 126 | #define JITASM_ATTRIBUTE_WEAK __declspec(selectany) | ||
| 127 | #else | ||
| 128 | #define JITASM_ATTRIBUTE_WEAK | ||
| 129 | #endif | ||
| 130 | |||
| 131 | #if defined(_MSC_VER) | ||
| 132 | #pragma warning( push ) | ||
| 133 | #pragma warning( disable : 4127 ) // conditional expression is constant. | ||
| 134 | #pragma warning( disable : 4201 ) // nonstandard extension used : nameless struct/union | ||
| 135 | #endif | ||
| 136 | |||
| 137 | #if defined(JITASM_GCC) | ||
| 138 | #pragma GCC diagnostic ignored "-Wignored-attributes" | ||
| 139 | #endif | ||
| 140 | |||
| 141 | #ifdef ASSERT | ||
| 142 | #define JITASM_ASSERT ASSERT | ||
| 143 | #else | ||
| 144 | #include <assert.h> | ||
| 145 | #define JITASM_ASSERT assert | ||
| 146 | #endif | ||
| 147 | |||
| 148 | //#define JITASM_DEBUG_DUMP | ||
| 149 | #ifdef JITASM_DEBUG_DUMP | ||
| 150 | #include <stdio.h> | ||
| 151 | #if defined(JITASM_GCC) | ||
| 152 | #define JITASM_TRACE printf | ||
| 153 | #else | ||
| 154 | #define JITASM_TRACE jitasm::detail::Trace | ||
| 155 | #endif | ||
| 156 | #elif defined(JITASM_GCC) | ||
| 157 | #define JITASM_TRACE(...) ((void)0) | ||
| 158 | #else | ||
| 159 | #define JITASM_TRACE __noop | ||
| 160 | #endif | ||
| 161 | |||
| 162 | namespace jitasm | ||
| 163 | { | ||
| 164 | |||
| 165 | typedef signed char sint8; | ||
| 166 | typedef signed short sint16; | ||
| 167 | typedef signed int sint32; | ||
| 168 | typedef unsigned char uint8; | ||
| 169 | typedef unsigned short uint16; | ||
| 170 | typedef unsigned int uint32; | ||
| 171 | #if defined(JITASM_GCC) | ||
| 172 | typedef signed long long sint64; | ||
| 173 | typedef unsigned long long uint64; | ||
| 174 | #else | ||
| 175 | typedef signed __int64 sint64; | ||
| 176 | typedef unsigned __int64 uint64; | ||
| 177 | #endif | ||
| 178 | |||
| 179 | ✗ | template<typename T> inline void avoid_unused_warn(const T&) {} | |
| 180 | |||
| 181 | namespace detail | ||
| 182 | { | ||
| 183 | #if defined(JITASM_GCC) | ||
| 184 | ✗ | inline long interlocked_increment(long *addend) { return __sync_add_and_fetch(addend, 1); } | |
| 185 | inline long interlocked_decrement(long *addend) { return __sync_sub_and_fetch(addend, 1); } | ||
| 186 | ✗ | inline long interlocked_exchange(long *target, long value) { return __sync_lock_test_and_set(target, value); } | |
| 187 | #elif defined(JITASM_WIN) | ||
| 188 | inline long interlocked_increment(long *addend) { return _InterlockedIncrement(addend); } | ||
| 189 | inline long interlocked_decrement(long *addend) { return _InterlockedDecrement(addend); } | ||
| 190 | inline long interlocked_exchange(long *target, long value) { return _InterlockedExchange(target, value); } | ||
| 191 | #endif | ||
| 192 | } // namespace detail | ||
| 193 | |||
| 194 | /// Physical register ID | ||
| 195 | enum PhysicalRegID | ||
| 196 | { | ||
| 197 | INVALID=0x0FFFFFFF, | ||
| 198 | EAX=0, ECX, EDX, EBX, ESP, EBP, ESI, EDI, R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D, | ||
| 199 | AL=0, CL, DL, BL, AH, CH, DH, BH, R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B, | ||
| 200 | AX=0, CX, DX, BX, SP, BP, SI, DI, R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W, | ||
| 201 | RAX=0, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15, | ||
| 202 | ST0=0, ST1, ST2, ST3, ST4, ST5, ST6, ST7, | ||
| 203 | MM0=0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, | ||
| 204 | XMM0=0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, | ||
| 205 | YMM0=0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7, YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15, | ||
| 206 | }; | ||
| 207 | |||
| 208 | enum | ||
| 209 | { | ||
| 210 | /** \var NUM_OF_PHYSICAL_REG | ||
| 211 | * Number of physical register | ||
| 212 | */ | ||
| 213 | /** \var SIZE_OF_GP_REG | ||
| 214 | * Size of general-purpose register | ||
| 215 | */ | ||
| 216 | #ifdef JITASM64 | ||
| 217 | NUM_OF_PHYSICAL_REG = 16, | ||
| 218 | SIZE_OF_GP_REG = 8 | ||
| 219 | #else | ||
| 220 | NUM_OF_PHYSICAL_REG = 8, | ||
| 221 | SIZE_OF_GP_REG = 4 | ||
| 222 | #endif | ||
| 223 | }; | ||
| 224 | |||
| 225 | /// Register type | ||
| 226 | enum RegType | ||
| 227 | { | ||
| 228 | R_TYPE_GP, ///< General purpose register | ||
| 229 | R_TYPE_MMX, ///< MMX register | ||
| 230 | R_TYPE_XMM, ///< XMM register | ||
| 231 | R_TYPE_YMM, ///< YMM register | ||
| 232 | R_TYPE_FPU, ///< FPU register | ||
| 233 | R_TYPE_SYMBOLIC_GP, ///< Symbolic general purpose register | ||
| 234 | R_TYPE_SYMBOLIC_MMX, ///< Symbolic MMX register | ||
| 235 | R_TYPE_SYMBOLIC_XMM, ///< Symbolic XMM register | ||
| 236 | R_TYPE_SYMBOLIC_YMM ///< Symbolic YMM register | ||
| 237 | }; | ||
| 238 | |||
| 239 | /// Register identifier | ||
| 240 | struct RegID | ||
| 241 | { | ||
| 242 | unsigned type : 4; // RegType | ||
| 243 | unsigned id : 28; ///< PhysicalRegID or symbolic register id | ||
| 244 | |||
| 245 | ✗ | bool operator==(const RegID& rhs) const {return type == rhs.type && id == rhs.id;} | |
| 246 | bool operator!=(const RegID& rhs) const {return !(*this == rhs);} | ||
| 247 | bool operator<(const RegID& rhs) const {return type != rhs.type ? type < rhs.type : id < rhs.id;} | ||
| 248 | ✗ | bool IsInvalid() const {return type == R_TYPE_GP && id == INVALID;} | |
| 249 | ✗ | bool IsSymbolic() const {return type == R_TYPE_SYMBOLIC_GP || type == R_TYPE_SYMBOLIC_MMX || type == R_TYPE_SYMBOLIC_XMM || type == R_TYPE_SYMBOLIC_YMM;} | |
| 250 | ✗ | RegType GetType() const {return static_cast<RegType>(type);} | |
| 251 | |||
| 252 | ✗ | static RegID Invalid() { | |
| 253 | RegID reg; | ||
| 254 | ✗ | reg.type = R_TYPE_GP; | |
| 255 | ✗ | reg.id = INVALID; | |
| 256 | ✗ | return reg; | |
| 257 | } | ||
| 258 | 133800 | static RegID CreatePhysicalRegID(RegType type_, PhysicalRegID id_) { | |
| 259 | RegID reg; | ||
| 260 | 133800 | reg.type = type_; | |
| 261 | 133800 | reg.id = id_; | |
| 262 | 133800 | return reg; | |
| 263 | } | ||
| 264 | ✗ | static RegID CreateSymbolicRegID(RegType type_) { | |
| 265 | static long s_id = 0; | ||
| 266 | RegID reg; | ||
| 267 | ✗ | reg.type = type_; | |
| 268 | ✗ | reg.id = static_cast<unsigned>(detail::interlocked_increment(&s_id)); | |
| 269 | ✗ | return reg; | |
| 270 | } | ||
| 271 | }; | ||
| 272 | |||
| 273 | /// Operand type | ||
| 274 | enum OpdType | ||
| 275 | { | ||
| 276 | O_TYPE_NONE, | ||
| 277 | O_TYPE_REG, | ||
| 278 | O_TYPE_MEM, | ||
| 279 | O_TYPE_IMM, | ||
| 280 | O_TYPE_TYPE_MASK = 0x03, | ||
| 281 | |||
| 282 | O_TYPE_DUMMY = 1 << 2, ///< The operand which has this flag is not encoded. This is for register allocator. | ||
| 283 | O_TYPE_READ = 1 << 3, ///< The operand is used for reading. | ||
| 284 | O_TYPE_WRITE = 1 << 4 ///< The operand is used for writing. | ||
| 285 | }; | ||
| 286 | |||
| 287 | /// Operand size | ||
| 288 | enum OpdSize | ||
| 289 | { | ||
| 290 | O_SIZE_8, | ||
| 291 | O_SIZE_16, | ||
| 292 | O_SIZE_32, | ||
| 293 | O_SIZE_64, | ||
| 294 | O_SIZE_80, | ||
| 295 | O_SIZE_128, | ||
| 296 | O_SIZE_224, | ||
| 297 | O_SIZE_256, | ||
| 298 | O_SIZE_864, | ||
| 299 | O_SIZE_4096 | ||
| 300 | }; | ||
| 301 | |||
| 302 | namespace detail | ||
| 303 | { | ||
| 304 | #pragma pack(push, 1) | ||
| 305 | |||
| 306 | /// Operand base class | ||
| 307 | struct Opd | ||
| 308 | { | ||
| 309 | uint8 opdtype_; // OpdType | ||
| 310 | uint8 opdsize_; // OpdSize | ||
| 311 | |||
| 312 | union { | ||
| 313 | // REG | ||
| 314 | struct { | ||
| 315 | RegID reg_; | ||
| 316 | uint32 reg_assignable_; | ||
| 317 | }; | ||
| 318 | // MEM | ||
| 319 | struct { | ||
| 320 | RegID base_; | ||
| 321 | RegID index_; | ||
| 322 | sint64 scale_; | ||
| 323 | sint64 disp_; | ||
| 324 | uint8 base_size_ : 4; // OpdSize | ||
| 325 | uint8 index_size_ : 4; // OpdSize | ||
| 326 | }; | ||
| 327 | // IMM | ||
| 328 | sint64 imm_; | ||
| 329 | }; | ||
| 330 | |||
| 331 | /// NONE | ||
| 332 | ✗ | Opd() : opdtype_(O_TYPE_NONE) {} | |
| 333 | /// REG | ||
| 334 | 133800 | Opd(OpdSize opdsize, const RegID& reg, uint32 reg_assignable = 0xFFFFFFFF) : opdtype_(O_TYPE_REG), opdsize_(static_cast<uint8>(opdsize)), reg_(reg), reg_assignable_(reg_assignable) {} | |
| 335 | /// MEM | ||
| 336 | ✗ | Opd(OpdSize opdsize, OpdSize base_size, OpdSize index_size, const RegID& base, const RegID& index, sint64 scale, sint64 disp) | |
| 337 | ✗ | : opdtype_(O_TYPE_MEM), opdsize_(static_cast<uint8>(opdsize)), base_(base), index_(index), scale_(scale), disp_(disp), base_size_(static_cast<uint8>(base_size)), index_size_(static_cast<uint8>(index_size)) {} | |
| 338 | protected: | ||
| 339 | /// IMM | ||
| 340 | ✗ | explicit Opd(OpdSize opdsize, sint64 imm) : opdtype_(O_TYPE_IMM), opdsize_(static_cast<uint8>(opdsize)), imm_(imm) {} | |
| 341 | |||
| 342 | public: | ||
| 343 | ✗ | bool IsNone() const {return (opdtype_ & O_TYPE_TYPE_MASK) == O_TYPE_NONE;} | |
| 344 | ✗ | bool IsReg() const {return (opdtype_ & O_TYPE_TYPE_MASK) == O_TYPE_REG;} | |
| 345 | ✗ | bool IsGpReg() const {return IsReg() && (reg_.type == R_TYPE_GP || reg_.type == R_TYPE_SYMBOLIC_GP);} | |
| 346 | ✗ | bool IsFpuReg() const {return IsReg() && reg_.type == R_TYPE_FPU;} | |
| 347 | ✗ | bool IsMmxReg() const {return IsReg() && (reg_.type == R_TYPE_MMX || reg_.type == R_TYPE_SYMBOLIC_MMX);} | |
| 348 | ✗ | bool IsXmmReg() const {return IsReg() && (reg_.type == R_TYPE_XMM || reg_.type == R_TYPE_SYMBOLIC_XMM);} | |
| 349 | ✗ | bool IsYmmReg() const {return IsReg() && (reg_.type == R_TYPE_YMM || reg_.type == R_TYPE_SYMBOLIC_YMM);} | |
| 350 | ✗ | bool IsMem() const {return (opdtype_ & O_TYPE_TYPE_MASK) == O_TYPE_MEM;} | |
| 351 | ✗ | bool IsImm() const {return (opdtype_ & O_TYPE_TYPE_MASK) == O_TYPE_IMM;} | |
| 352 | ✗ | bool IsDummy() const {return (opdtype_ & O_TYPE_DUMMY) != 0;} | |
| 353 | bool IsRead() const {return (opdtype_ & O_TYPE_READ) != 0;} | ||
| 354 | ✗ | bool IsWrite() const {return (opdtype_ & O_TYPE_WRITE) != 0;} | |
| 355 | |||
| 356 | ✗ | OpdType GetType() const {return static_cast<OpdType>(opdtype_);} | |
| 357 | ✗ | OpdSize GetSize() const {return static_cast<OpdSize>(opdsize_);} | |
| 358 | ✗ | OpdSize GetAddressBaseSize() const {return static_cast<OpdSize>(base_size_);} | |
| 359 | ✗ | OpdSize GetAddressIndexSize() const {return static_cast<OpdSize>(index_size_);} | |
| 360 | ✗ | RegID GetReg() const {JITASM_ASSERT(IsReg()); return reg_;} | |
| 361 | ✗ | RegID GetBase() const {JITASM_ASSERT(IsMem()); return base_;} | |
| 362 | ✗ | RegID GetIndex() const {JITASM_ASSERT(IsMem()); return index_;} | |
| 363 | ✗ | sint64 GetScale() const {JITASM_ASSERT(IsMem()); return scale_;} | |
| 364 | ✗ | sint64 GetDisp() const {JITASM_ASSERT(IsMem()); return disp_;} | |
| 365 | ✗ | sint64 GetImm() const {JITASM_ASSERT(IsImm()); return imm_;} | |
| 366 | |||
| 367 | ✗ | bool operator==(const Opd& rhs) const | |
| 368 | { | ||
| 369 | ✗ | if ((opdtype_ & O_TYPE_TYPE_MASK) != (rhs.opdtype_ & O_TYPE_TYPE_MASK) || opdsize_ != rhs.opdsize_) {return false;} | |
| 370 | ✗ | if (IsReg()) {return reg_ == rhs.reg_ && reg_assignable_ == rhs.reg_assignable_;} | |
| 371 | ✗ | if (IsMem()) {return base_ == rhs.base_ && index_ == rhs.index_ && scale_ == rhs.scale_ && disp_ == rhs.disp_ && base_size_ == rhs.base_size_ && index_size_ == rhs.index_size_;} | |
| 372 | ✗ | if (IsImm()) {return imm_ == rhs.imm_;} | |
| 373 | ✗ | return true; | |
| 374 | } | ||
| 375 | ✗ | bool operator!=(const Opd& rhs) const {return !(*this == rhs);} | |
| 376 | }; | ||
| 377 | |||
| 378 | #pragma pack(pop) | ||
| 379 | |||
| 380 | /// Add O_TYPE_DUMMY to the specified operand | ||
| 381 | ✗ | inline Opd Dummy(const Opd& opd) | |
| 382 | { | ||
| 383 | ✗ | Opd o(opd); | |
| 384 | ✗ | o.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_DUMMY); | |
| 385 | ✗ | return o; | |
| 386 | } | ||
| 387 | |||
| 388 | /// Add O_TYPE_DUMMY to the specified operand and constraint of register assignment | ||
| 389 | ✗ | inline Opd Dummy(const Opd& opd, const Opd& constraint) | |
| 390 | { | ||
| 391 | ✗ | JITASM_ASSERT(opd.IsReg() && (opd.opdtype_ & O_TYPE_TYPE_MASK) == (constraint.opdtype_ & O_TYPE_TYPE_MASK) && !constraint.GetReg().IsSymbolic()); | |
| 392 | ✗ | Opd o(opd); | |
| 393 | ✗ | o.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_DUMMY); | |
| 394 | ✗ | o.reg_assignable_ = (1 << constraint.reg_.id); | |
| 395 | ✗ | return o; | |
| 396 | } | ||
| 397 | |||
| 398 | /// Add O_TYPE_READ to the specified operand | ||
| 399 | ✗ | inline Opd R(const Opd& opd) | |
| 400 | { | ||
| 401 | ✗ | Opd o(opd); | |
| 402 | ✗ | o.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_READ); | |
| 403 | ✗ | return o; | |
| 404 | } | ||
| 405 | |||
| 406 | /// Add O_TYPE_WRITE to the specified operand | ||
| 407 | ✗ | inline Opd W(const Opd& opd) | |
| 408 | { | ||
| 409 | ✗ | Opd o(opd); | |
| 410 | ✗ | o.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_WRITE); | |
| 411 | ✗ | return o; | |
| 412 | } | ||
| 413 | |||
| 414 | /// Add O_TYPE_READ | O_TYPE_WRITE to the specified operand | ||
| 415 | ✗ | inline Opd RW(const Opd& opd) | |
| 416 | { | ||
| 417 | ✗ | Opd o(opd); | |
| 418 | ✗ | o.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_READ | O_TYPE_WRITE); | |
| 419 | ✗ | return o; | |
| 420 | } | ||
| 421 | |||
| 422 | template<int Size> inline OpdSize ToOpdSize(); | ||
| 423 | 17840 | template<> inline OpdSize ToOpdSize<8>() {return O_SIZE_8;} | |
| 424 | 17840 | template<> inline OpdSize ToOpdSize<16>() {return O_SIZE_16;} | |
| 425 | 17840 | template<> inline OpdSize ToOpdSize<32>() {return O_SIZE_32;} | |
| 426 | 35680 | template<> inline OpdSize ToOpdSize<64>() {return O_SIZE_64;} | |
| 427 | 8920 | template<> inline OpdSize ToOpdSize<80>() {return O_SIZE_80;} | |
| 428 | 17840 | template<> inline OpdSize ToOpdSize<128>() {return O_SIZE_128;} | |
| 429 | template<> inline OpdSize ToOpdSize<224>() {return O_SIZE_224;} | ||
| 430 | 17840 | template<> inline OpdSize ToOpdSize<256>() {return O_SIZE_256;} | |
| 431 | template<> inline OpdSize ToOpdSize<864>() {return O_SIZE_864;} | ||
| 432 | template<> inline OpdSize ToOpdSize<4096>() {return O_SIZE_4096;} | ||
| 433 | |||
| 434 | template<int Size> | ||
| 435 | struct OpdT : Opd | ||
| 436 | { | ||
| 437 | /// NONE | ||
| 438 | OpdT() : Opd() {} | ||
| 439 | /// REG | ||
| 440 | 133800 | explicit OpdT(const RegID& reg, uint32 reg_assignable = 0xFFFFFFFF) : Opd(ToOpdSize<Size>(), reg, reg_assignable) {} | |
| 441 | /// MEM | ||
| 442 | ✗ | OpdT(OpdSize base_size, OpdSize index_size, const RegID& base, const RegID& index, sint64 scale, sint64 disp) | |
| 443 | ✗ | : Opd(ToOpdSize<Size>(), base_size, index_size, base, index, scale, disp) {} | |
| 444 | protected: | ||
| 445 | /// IMM | ||
| 446 | ✗ | OpdT(sint64 imm) : Opd(ToOpdSize<Size>(), imm) {} | |
| 447 | }; | ||
| 448 | |||
| 449 | } // namespace detail | ||
| 450 | |||
| 451 | typedef detail::OpdT<8> Opd8; | ||
| 452 | typedef detail::OpdT<16> Opd16; | ||
| 453 | typedef detail::OpdT<32> Opd32; | ||
| 454 | typedef detail::OpdT<64> Opd64; | ||
| 455 | typedef detail::OpdT<80> Opd80; | ||
| 456 | typedef detail::OpdT<128> Opd128; | ||
| 457 | typedef detail::OpdT<224> Opd224; // FPU environment | ||
| 458 | typedef detail::OpdT<256> Opd256; | ||
| 459 | typedef detail::OpdT<864> Opd864; // FPU state | ||
| 460 | typedef detail::OpdT<4096> Opd4096; // FPU, MMX, XMM, MXCSR state | ||
| 461 | |||
| 462 | /// 8bit general purpose register | ||
| 463 | struct Reg8 : Opd8 { | ||
| 464 | Reg8() : Opd8(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_GP), 0xFFFFFF0F) {} | ||
| 465 | 17840 | explicit Reg8(PhysicalRegID id) : Opd8(RegID::CreatePhysicalRegID(R_TYPE_GP, id)) {} | |
| 466 | }; | ||
| 467 | /// 16bit general purpose register | ||
| 468 | struct Reg16 : Opd16 { | ||
| 469 | Reg16() : Opd16(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_GP)) {} | ||
| 470 | 17840 | explicit Reg16(PhysicalRegID id) : Opd16(RegID::CreatePhysicalRegID(R_TYPE_GP, id)) {} | |
| 471 | }; | ||
| 472 | /// 32bit general purpose register | ||
| 473 | struct Reg32 : Opd32 { | ||
| 474 | ✗ | Reg32() : Opd32(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_GP)) {} | |
| 475 | 17840 | explicit Reg32(PhysicalRegID id) : Opd32(RegID::CreatePhysicalRegID(R_TYPE_GP, id)) {} | |
| 476 | }; | ||
| 477 | #ifdef JITASM64 | ||
| 478 | /// 64bit general purpose register | ||
| 479 | struct Reg64 : Opd64 { | ||
| 480 | ✗ | Reg64() : Opd64(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_GP)) {} | |
| 481 | 26760 | explicit Reg64(PhysicalRegID id) : Opd64(RegID::CreatePhysicalRegID(R_TYPE_GP, id)) {} | |
| 482 | explicit Reg64(RegID reg_id) : Opd64(reg_id) {} // VS2017 /permissive- | ||
| 483 | }; | ||
| 484 | typedef Reg64 Reg; | ||
| 485 | #else | ||
| 486 | typedef Reg32 Reg; | ||
| 487 | #endif | ||
| 488 | /// FPU register | ||
| 489 | struct FpuReg : Opd80 { | ||
| 490 | 8920 | explicit FpuReg(PhysicalRegID id) : Opd80(RegID::CreatePhysicalRegID(R_TYPE_FPU, id)) {} | |
| 491 | }; | ||
| 492 | /// MMX register | ||
| 493 | struct MmxReg : Opd64 { | ||
| 494 | MmxReg() : Opd64(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_MMX)) {} | ||
| 495 | 8920 | explicit MmxReg(PhysicalRegID id) : Opd64(RegID::CreatePhysicalRegID(R_TYPE_MMX, id)) {} | |
| 496 | }; | ||
| 497 | /// XMM register | ||
| 498 | struct XmmReg : Opd128 { | ||
| 499 | ✗ | XmmReg() : Opd128(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_XMM)) {} | |
| 500 | 17840 | explicit XmmReg(PhysicalRegID id) : Opd128(RegID::CreatePhysicalRegID(R_TYPE_XMM, id)) {} | |
| 501 | explicit XmmReg(RegID reg_id) : Opd128(reg_id) {} // VS2017 /permissive- | ||
| 502 | }; | ||
| 503 | /// YMM register | ||
| 504 | struct YmmReg : Opd256 { | ||
| 505 | ✗ | YmmReg() : Opd256(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_YMM)) {} | |
| 506 | 17840 | explicit YmmReg(PhysicalRegID id) : Opd256(RegID::CreatePhysicalRegID(R_TYPE_YMM, id)) {} | |
| 507 | XmmReg as128() const { | ||
| 508 | RegID id = reg_; | ||
| 509 | id.type = R_TYPE_SYMBOLIC_XMM; | ||
| 510 | return XmmReg(id); | ||
| 511 | } | ||
| 512 | }; | ||
| 513 | |||
| 514 | 1115 | struct FpuReg_st0 : FpuReg {FpuReg_st0() : FpuReg(ST0) {}}; | |
| 515 | |||
| 516 | template<class OpdN> | ||
| 517 | struct MemT : OpdN | ||
| 518 | { | ||
| 519 | ✗ | MemT(OpdSize base_size, OpdSize index_size, const RegID& base, const RegID& index, sint64 scale, sint64 disp) : OpdN(base_size, index_size, base, index, scale, disp) {} | |
| 520 | }; | ||
| 521 | typedef MemT<Opd8> Mem8; | ||
| 522 | typedef MemT<Opd16> Mem16; | ||
| 523 | typedef MemT<Opd32> Mem32; | ||
| 524 | typedef MemT<Opd64> Mem64; | ||
| 525 | typedef MemT<Opd80> Mem80; | ||
| 526 | typedef MemT<Opd128> Mem128; | ||
| 527 | typedef MemT<Opd224> Mem224; // FPU environment | ||
| 528 | typedef MemT<Opd256> Mem256; | ||
| 529 | typedef MemT<Opd864> Mem864; // FPU state | ||
| 530 | typedef MemT<Opd4096> Mem4096; // FPU, MMX, XMM, MXCSR state | ||
| 531 | |||
| 532 | template<class OpdN, OpdSize IndexSize> | ||
| 533 | struct VecMemT : OpdN | ||
| 534 | { | ||
| 535 | VecMemT(OpdSize base_size, const RegID& base, const RegID& index, sint64 scale, sint64 disp) : OpdN(base_size, IndexSize, base, index, scale, disp) {} | ||
| 536 | }; | ||
| 537 | typedef VecMemT<Opd32, O_SIZE_128> Mem32vxd; | ||
| 538 | typedef VecMemT<Opd32, O_SIZE_256> Mem32vyd; | ||
| 539 | typedef VecMemT<Opd32, O_SIZE_128> Mem64vxd; | ||
| 540 | typedef VecMemT<Opd32, O_SIZE_256> Mem64vyd; | ||
| 541 | typedef VecMemT<Opd64, O_SIZE_128> Mem32vxq; | ||
| 542 | typedef VecMemT<Opd64, O_SIZE_256> Mem32vyq; | ||
| 543 | typedef VecMemT<Opd64, O_SIZE_128> Mem64vxq; | ||
| 544 | typedef VecMemT<Opd64, O_SIZE_256> Mem64vyq; | ||
| 545 | |||
| 546 | struct MemOffset64 | ||
| 547 | { | ||
| 548 | sint64 offset_; | ||
| 549 | explicit MemOffset64(sint64 offset) : offset_(offset) {} | ||
| 550 | sint64 GetOffset() const {return offset_;} | ||
| 551 | }; | ||
| 552 | |||
| 553 | template<class OpdN, class U, class S> | ||
| 554 | struct ImmT : OpdN | ||
| 555 | { | ||
| 556 | ✗ | ImmT(U imm) : OpdN((S) imm) {} | |
| 557 | }; | ||
| 558 | typedef ImmT<Opd8, uint8, sint8> Imm8; ///< 1 byte immediate | ||
| 559 | typedef ImmT<Opd16, uint16, sint16> Imm16; ///< 2 byte immediate | ||
| 560 | typedef ImmT<Opd32, uint32, sint32> Imm32; ///< 4 byte immediate | ||
| 561 | typedef ImmT<Opd64, uint64, sint64> Imm64; ///< 8 byte immediate | ||
| 562 | |||
| 563 | namespace detail | ||
| 564 | { | ||
| 565 | ✗ | inline bool IsInt8(sint64 n) {return (sint8) n == n;} | |
| 566 | inline bool IsInt16(sint64 n) {return (sint16) n == n;} | ||
| 567 | ✗ | inline bool IsInt32(sint64 n) {return (sint32) n == n;} | |
| 568 | inline Opd ImmXor8(const Imm16& imm) {return IsInt8(imm.GetImm()) ? (Opd) Imm8((sint8) imm.GetImm()) : (Opd) imm;} | ||
| 569 | ✗ | inline Opd ImmXor8(const Imm32& imm) {return IsInt8(imm.GetImm()) ? (Opd) Imm8((sint8) imm.GetImm()) : (Opd) imm;} | |
| 570 | inline Opd ImmXor8(const Imm64& imm) {return IsInt8(imm.GetImm()) ? (Opd) Imm8((sint8) imm.GetImm()) : (Opd) imm;} | ||
| 571 | } // namespace detail | ||
| 572 | |||
| 573 | /// 32bit address (base, displacement) | ||
| 574 | struct Addr32 | ||
| 575 | { | ||
| 576 | RegID reg_; | ||
| 577 | sint64 disp_; | ||
| 578 | Addr32(const Reg32& obj) : reg_(obj.reg_), disp_(0) {} // implicit | ||
| 579 | Addr32(const RegID& reg, sint64 disp) : reg_(reg), disp_(disp) {} | ||
| 580 | }; | ||
| 581 | inline Addr32 operator+(const Reg32& lhs, sint64 rhs) {return Addr32(lhs.reg_, rhs);} | ||
| 582 | inline Addr32 operator+(sint64 lhs, const Reg32& rhs) {return rhs + lhs;} | ||
| 583 | inline Addr32 operator-(const Reg32& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 584 | inline Addr32 operator+(const Addr32& lhs, sint64 rhs) {return Addr32(lhs.reg_, lhs.disp_ + rhs);} | ||
| 585 | inline Addr32 operator+(sint64 lhs, const Addr32& rhs) {return rhs + lhs;} | ||
| 586 | inline Addr32 operator-(const Addr32& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 587 | |||
| 588 | /// 32bit address (base, index, displacement) | ||
| 589 | struct Addr32BI | ||
| 590 | { | ||
| 591 | RegID base_; | ||
| 592 | RegID index_; | ||
| 593 | sint64 disp_; | ||
| 594 | Addr32BI(const RegID& base, const RegID& index, sint64 disp) : base_(base), index_(index), disp_(disp) {} | ||
| 595 | }; | ||
| 596 | inline Addr32BI operator+(const Addr32& lhs, const Addr32& rhs) {return Addr32BI(rhs.reg_, lhs.reg_, lhs.disp_ + rhs.disp_);} | ||
| 597 | inline Addr32BI operator+(const Addr32BI& lhs, sint64 rhs) {return Addr32BI(lhs.base_, lhs.index_, lhs.disp_ + rhs);} | ||
| 598 | inline Addr32BI operator+(sint64 lhs, const Addr32BI& rhs) {return rhs + lhs;} | ||
| 599 | inline Addr32BI operator-(const Addr32BI& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 600 | |||
| 601 | /// 32bit address (index, scale, displacement) | ||
| 602 | struct Addr32SI | ||
| 603 | { | ||
| 604 | RegID index_; | ||
| 605 | sint64 scale_; | ||
| 606 | sint64 disp_; | ||
| 607 | Addr32SI(const RegID& index, sint64 scale, sint64 disp) : index_(index), scale_(scale), disp_(disp) {} | ||
| 608 | }; | ||
| 609 | inline Addr32SI operator*(const Reg32& lhs, sint64 rhs) {return Addr32SI(lhs.reg_, rhs, 0);} | ||
| 610 | inline Addr32SI operator*(sint64 lhs, const Reg32& rhs) {return rhs * lhs;} | ||
| 611 | inline Addr32SI operator*(const Addr32SI& lhs, sint64 rhs) {return Addr32SI(lhs.index_, lhs.scale_ * rhs, lhs.disp_);} | ||
| 612 | inline Addr32SI operator*(sint64 lhs, const Addr32SI& rhs) {return rhs * lhs;} | ||
| 613 | inline Addr32SI operator+(const Addr32SI& lhs, sint64 rhs) {return Addr32SI(lhs.index_, lhs.scale_, lhs.disp_ + rhs);} | ||
| 614 | inline Addr32SI operator+(sint64 lhs, const Addr32SI& rhs) {return rhs + lhs;} | ||
| 615 | inline Addr32SI operator-(const Addr32SI& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 616 | |||
| 617 | /// 32bit address (base, index, scale, displacement) | ||
| 618 | struct Addr32SIB | ||
| 619 | { | ||
| 620 | RegID base_; | ||
| 621 | RegID index_; | ||
| 622 | sint64 scale_; | ||
| 623 | sint64 disp_; | ||
| 624 | Addr32SIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {} | ||
| 625 | }; | ||
| 626 | inline Addr32SIB operator+(const Addr32& lhs, const Addr32SI& rhs) {return Addr32SIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);} | ||
| 627 | inline Addr32SIB operator+(const Addr32SI& lhs, const Addr32& rhs) {return rhs + lhs;} | ||
| 628 | inline Addr32SIB operator+(const Addr32SIB& lhs, sint64 rhs) {return Addr32SIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);} | ||
| 629 | inline Addr32SIB operator+(sint64 lhs, const Addr32SIB& rhs) {return rhs + lhs;} | ||
| 630 | inline Addr32SIB operator-(const Addr32SIB& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 631 | |||
| 632 | /// Address (xmm index, scale, displacement) | ||
| 633 | struct AddrXmmSI | ||
| 634 | { | ||
| 635 | RegID index_; | ||
| 636 | sint64 scale_; | ||
| 637 | sint64 disp_; | ||
| 638 | AddrXmmSI(const RegID& index, sint64 scale, sint64 disp) : index_(index), scale_(scale), disp_(disp) {} | ||
| 639 | }; | ||
| 640 | inline AddrXmmSI operator*(const XmmReg& lhs, sint64 rhs) {return AddrXmmSI(lhs.reg_, rhs, 0);} | ||
| 641 | inline AddrXmmSI operator*(sint64 lhs, const XmmReg& rhs) {return rhs * lhs;} | ||
| 642 | inline AddrXmmSI operator*(const AddrXmmSI& lhs, sint64 rhs) {return AddrXmmSI(lhs.index_, lhs.scale_ * rhs, lhs.disp_);} | ||
| 643 | inline AddrXmmSI operator*(sint64 lhs, const AddrXmmSI& rhs) {return rhs * lhs;} | ||
| 644 | inline AddrXmmSI operator+(const AddrXmmSI& lhs, sint64 rhs) {return AddrXmmSI(lhs.index_, lhs.scale_, lhs.disp_ + rhs);} | ||
| 645 | inline AddrXmmSI operator+(sint64 lhs, const AddrXmmSI& rhs) {return rhs + lhs;} | ||
| 646 | inline AddrXmmSI operator-(const AddrXmmSI& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 647 | |||
| 648 | /// 32bit address (base, xmm index, scale, displacement) | ||
| 649 | struct Addr32XmmSIB | ||
| 650 | { | ||
| 651 | RegID base_; | ||
| 652 | RegID index_; | ||
| 653 | sint64 scale_; | ||
| 654 | sint64 disp_; | ||
| 655 | Addr32XmmSIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {} | ||
| 656 | }; | ||
| 657 | inline Addr32XmmSIB operator+(const Addr32& lhs, const AddrXmmSI& rhs) {return Addr32XmmSIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);} | ||
| 658 | inline Addr32XmmSIB operator+(const AddrXmmSI& lhs, const Addr32& rhs) {return rhs + lhs;} | ||
| 659 | inline Addr32XmmSIB operator+(const Addr32XmmSIB& lhs, sint64 rhs) {return Addr32XmmSIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);} | ||
| 660 | inline Addr32XmmSIB operator+(sint64 lhs, const Addr32XmmSIB& rhs) {return rhs + lhs;} | ||
| 661 | inline Addr32XmmSIB operator-(const Addr32XmmSIB& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 662 | |||
| 663 | /// Address (ymm index, scale, displacement) | ||
| 664 | struct AddrYmmSI | ||
| 665 | { | ||
| 666 | RegID index_; | ||
| 667 | sint64 scale_; | ||
| 668 | sint64 disp_; | ||
| 669 | AddrYmmSI(const RegID& index, sint64 scale, sint64 disp) : index_(index), scale_(scale), disp_(disp) {} | ||
| 670 | }; | ||
| 671 | inline AddrYmmSI operator*(const YmmReg& lhs, sint64 rhs) {return AddrYmmSI(lhs.reg_, rhs, 0);} | ||
| 672 | inline AddrYmmSI operator*(sint64 lhs, const YmmReg& rhs) {return rhs * lhs;} | ||
| 673 | inline AddrYmmSI operator*(const AddrYmmSI& lhs, sint64 rhs) {return AddrYmmSI(lhs.index_, lhs.scale_ * rhs, lhs.disp_);} | ||
| 674 | inline AddrYmmSI operator*(sint64 lhs, const AddrYmmSI& rhs) {return rhs * lhs;} | ||
| 675 | inline AddrYmmSI operator+(const AddrYmmSI& lhs, sint64 rhs) {return AddrYmmSI(lhs.index_, lhs.scale_, lhs.disp_ + rhs);} | ||
| 676 | inline AddrYmmSI operator+(sint64 lhs, const AddrYmmSI& rhs) {return rhs + lhs;} | ||
| 677 | inline AddrYmmSI operator-(const AddrYmmSI& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 678 | |||
| 679 | /// 32bit address (base, ymm index, scale, displacement) | ||
| 680 | struct Addr32YmmSIB | ||
| 681 | { | ||
| 682 | RegID base_; | ||
| 683 | RegID index_; | ||
| 684 | sint64 scale_; | ||
| 685 | sint64 disp_; | ||
| 686 | Addr32YmmSIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {} | ||
| 687 | }; | ||
| 688 | inline Addr32YmmSIB operator+(const Addr32& lhs, const AddrYmmSI& rhs) {return Addr32YmmSIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);} | ||
| 689 | inline Addr32YmmSIB operator+(const AddrYmmSI& lhs, const Addr32& rhs) {return rhs + lhs;} | ||
| 690 | inline Addr32YmmSIB operator+(const Addr32YmmSIB& lhs, sint64 rhs) {return Addr32YmmSIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);} | ||
| 691 | inline Addr32YmmSIB operator+(sint64 lhs, const Addr32YmmSIB& rhs) {return rhs + lhs;} | ||
| 692 | inline Addr32YmmSIB operator-(const Addr32YmmSIB& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 693 | |||
| 694 | #ifdef JITASM64 | ||
| 695 | /// 64bit address (base, displacement) | ||
| 696 | struct Addr64 | ||
| 697 | { | ||
| 698 | RegID reg_; | ||
| 699 | sint64 disp_; | ||
| 700 | ✗ | Addr64(const Reg64& obj) : reg_(obj.reg_), disp_(0) {} // implicit | |
| 701 | ✗ | Addr64(const RegID& reg, sint64 disp) : reg_(reg), disp_(disp) {} | |
| 702 | }; | ||
| 703 | ✗ | inline Addr64 operator+(const Reg64& lhs, sint64 rhs) {return Addr64(lhs.reg_, rhs);} | |
| 704 | inline Addr64 operator+(sint64 lhs, const Reg64& rhs) {return rhs + lhs;} | ||
| 705 | ✗ | inline Addr64 operator-(const Reg64& lhs, sint64 rhs) {return lhs + -rhs;} | |
| 706 | ✗ | inline Addr64 operator+(const Addr64& lhs, sint64 rhs) {return Addr64(lhs.reg_, lhs.disp_ + rhs);} | |
| 707 | inline Addr64 operator+(sint64 lhs, const Addr64& rhs) {return rhs + lhs;} | ||
| 708 | ✗ | inline Addr64 operator-(const Addr64& lhs, sint64 rhs) {return lhs + -rhs;} | |
| 709 | |||
| 710 | /// 64bit address (base, index, displacement) | ||
| 711 | struct Addr64BI | ||
| 712 | { | ||
| 713 | RegID base_; | ||
| 714 | RegID index_; | ||
| 715 | sint64 disp_; | ||
| 716 | ✗ | Addr64BI(const RegID& base, const RegID& index, sint64 disp) : base_(base), index_(index), disp_(disp) {} | |
| 717 | }; | ||
| 718 | ✗ | inline Addr64BI operator+(const Addr64& lhs, const Addr64& rhs) {return Addr64BI(rhs.reg_, lhs.reg_, lhs.disp_ + rhs.disp_);} | |
| 719 | inline Addr64BI operator+(const Addr64BI& lhs, sint64 rhs) {return Addr64BI(lhs.base_, lhs.index_, lhs.disp_ + rhs);} | ||
| 720 | inline Addr64BI operator+(sint64 lhs, const Addr64BI& rhs) {return rhs + lhs;} | ||
| 721 | inline Addr64BI operator-(const Addr64BI& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 722 | |||
| 723 | /// 64bit address (index, scale, displacement) | ||
| 724 | struct Addr64SI | ||
| 725 | { | ||
| 726 | RegID index_; | ||
| 727 | sint64 scale_; | ||
| 728 | sint64 disp_; | ||
| 729 | Addr64SI(const RegID& index, sint64 scale, sint64 disp) : index_(index), scale_(scale), disp_(disp) {} | ||
| 730 | }; | ||
| 731 | inline Addr64SI operator*(const Reg64& lhs, sint64 rhs) {return Addr64SI(lhs.reg_, rhs, 0);} | ||
| 732 | inline Addr64SI operator*(sint64 lhs, const Reg64& rhs) {return rhs * lhs;} | ||
| 733 | inline Addr64SI operator*(const Addr64SI& lhs, sint64 rhs) {return Addr64SI(lhs.index_, lhs.scale_ * rhs, lhs.disp_);} | ||
| 734 | inline Addr64SI operator*(sint64 lhs, const Addr64SI& rhs) {return rhs * lhs;} | ||
| 735 | inline Addr64SI operator+(const Addr64SI& lhs, sint64 rhs) {return Addr64SI(lhs.index_, lhs.scale_, lhs.disp_ + rhs);} | ||
| 736 | inline Addr64SI operator+(sint64 lhs, const Addr64SI& rhs) {return rhs + lhs;} | ||
| 737 | inline Addr64SI operator-(const Addr64SI& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 738 | |||
| 739 | /// 64bit address (base, index, scale, displacement) | ||
| 740 | struct Addr64SIB | ||
| 741 | { | ||
| 742 | RegID base_; | ||
| 743 | RegID index_; | ||
| 744 | sint64 scale_; | ||
| 745 | sint64 disp_; | ||
| 746 | Addr64SIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {} | ||
| 747 | }; | ||
| 748 | inline Addr64SIB operator+(const Addr64& lhs, const Addr64SI& rhs) {return Addr64SIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);} | ||
| 749 | inline Addr64SIB operator+(const Addr64SI& lhs, const Addr64& rhs) {return rhs + lhs;} | ||
| 750 | inline Addr64SIB operator+(const Addr64SIB& lhs, sint64 rhs) {return Addr64SIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);} | ||
| 751 | inline Addr64SIB operator+(sint64 lhs, const Addr64SIB& rhs) {return rhs + lhs;} | ||
| 752 | inline Addr64SIB operator-(const Addr64SIB& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 753 | |||
| 754 | /// 64bit address (base, xmm index, scale, displacement) | ||
| 755 | struct Addr64XmmSIB | ||
| 756 | { | ||
| 757 | RegID base_; | ||
| 758 | RegID index_; | ||
| 759 | sint64 scale_; | ||
| 760 | sint64 disp_; | ||
| 761 | Addr64XmmSIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {} | ||
| 762 | }; | ||
| 763 | inline Addr64XmmSIB operator+(const Addr64& lhs, const AddrXmmSI& rhs) {return Addr64XmmSIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);} | ||
| 764 | inline Addr64XmmSIB operator+(const AddrXmmSI& lhs, const Addr64& rhs) {return rhs + lhs;} | ||
| 765 | inline Addr64XmmSIB operator+(const Addr64XmmSIB& lhs, sint64 rhs) {return Addr64XmmSIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);} | ||
| 766 | inline Addr64XmmSIB operator+(sint64 lhs, const Addr64XmmSIB& rhs) {return rhs + lhs;} | ||
| 767 | inline Addr64XmmSIB operator-(const Addr64XmmSIB& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 768 | |||
| 769 | /// 64bit address (base, ymm index, scale, displacement) | ||
| 770 | struct Addr64YmmSIB | ||
| 771 | { | ||
| 772 | RegID base_; | ||
| 773 | RegID index_; | ||
| 774 | sint64 scale_; | ||
| 775 | sint64 disp_; | ||
| 776 | Addr64YmmSIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {} | ||
| 777 | }; | ||
| 778 | inline Addr64YmmSIB operator+(const Addr64& lhs, const AddrYmmSI& rhs) {return Addr64YmmSIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);} | ||
| 779 | inline Addr64YmmSIB operator+(const AddrYmmSI& lhs, const Addr64& rhs) {return rhs + lhs;} | ||
| 780 | inline Addr64YmmSIB operator+(const Addr64YmmSIB& lhs, sint64 rhs) {return Addr64YmmSIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);} | ||
| 781 | inline Addr64YmmSIB operator+(sint64 lhs, const Addr64YmmSIB& rhs) {return rhs + lhs;} | ||
| 782 | inline Addr64YmmSIB operator-(const Addr64YmmSIB& lhs, sint64 rhs) {return lhs + -rhs;} | ||
| 783 | |||
| 784 | typedef Addr64 Addr; | ||
| 785 | typedef Addr64BI AddrBI; | ||
| 786 | typedef Addr64SI AddrSI; | ||
| 787 | typedef Addr64SIB AddrSIB; | ||
| 788 | #else | ||
| 789 | typedef Addr32 Addr; | ||
| 790 | typedef Addr32BI AddrBI; | ||
| 791 | typedef Addr32SI AddrSI; | ||
| 792 | typedef Addr32SIB AddrSIB; | ||
| 793 | #endif | ||
| 794 | |||
| 795 | template<typename OpdN> | ||
| 796 | struct AddressingPtr | ||
| 797 | { | ||
| 798 | // 32bit-Addressing | ||
| 799 | MemT<OpdN> operator[](const Addr32& obj) {return MemT<OpdN>(O_SIZE_32, O_SIZE_32, obj.reg_, RegID::Invalid(), 0, obj.disp_);} | ||
| 800 | MemT<OpdN> operator[](const Addr32BI& obj) {return MemT<OpdN>(O_SIZE_32, O_SIZE_32, obj.base_, obj.index_, 0, obj.disp_);} | ||
| 801 | MemT<OpdN> operator[](const Addr32SI& obj) {return MemT<OpdN>(O_SIZE_32, O_SIZE_32, RegID::Invalid(), obj.index_, obj.scale_, obj.disp_);} | ||
| 802 | MemT<OpdN> operator[](const Addr32SIB& obj) {return MemT<OpdN>(O_SIZE_32, O_SIZE_32, obj.base_, obj.index_, obj.scale_, obj.disp_);} | ||
| 803 | VecMemT<OpdN, O_SIZE_128> operator[](const Addr32XmmSIB& obj) {return VecMemT<OpdN, O_SIZE_128>(O_SIZE_32, obj.base_, obj.index_, obj.scale_, obj.disp_);} | ||
| 804 | VecMemT<OpdN, O_SIZE_256> operator[](const Addr32YmmSIB& obj) {return VecMemT<OpdN, O_SIZE_256>(O_SIZE_32, obj.base_, obj.index_, obj.scale_, obj.disp_);} | ||
| 805 | |||
| 806 | #ifdef JITASM64 | ||
| 807 | // 64bit-Addressing | ||
| 808 | ✗ | MemT<OpdN> operator[](const Addr64& obj) {return MemT<OpdN>(O_SIZE_64, O_SIZE_64, obj.reg_, RegID::Invalid(), 0, obj.disp_);} | |
| 809 | ✗ | MemT<OpdN> operator[](const Addr64BI& obj) {return MemT<OpdN>(O_SIZE_64, O_SIZE_64, obj.base_, obj.index_, 0, obj.disp_);} | |
| 810 | MemT<OpdN> operator[](const Addr64SI& obj) {return MemT<OpdN>(O_SIZE_64, O_SIZE_64, RegID::Invalid(), obj.index_, obj.scale_, obj.disp_);} | ||
| 811 | MemT<OpdN> operator[](const Addr64SIB& obj) {return MemT<OpdN>(O_SIZE_64, O_SIZE_64, obj.base_, obj.index_, obj.scale_, obj.disp_);} | ||
| 812 | MemOffset64 operator[](sint64 offset) {return MemOffset64(offset);} | ||
| 813 | MemOffset64 operator[](uint64 offset) {return MemOffset64((sint64) offset);} | ||
| 814 | VecMemT<OpdN, O_SIZE_128> operator[](const Addr64XmmSIB& obj) {return VecMemT<OpdN, O_SIZE_128>(O_SIZE_64, obj.base_, obj.index_, obj.scale_, obj.disp_);} | ||
| 815 | VecMemT<OpdN, O_SIZE_256> operator[](const Addr64YmmSIB& obj) {return VecMemT<OpdN, O_SIZE_256>(O_SIZE_64, obj.base_, obj.index_, obj.scale_, obj.disp_);} | ||
| 816 | #endif | ||
| 817 | |||
| 818 | #ifdef JITASM64 | ||
| 819 | MemT<OpdN> operator[](sint32 disp) {return MemT<OpdN>(O_SIZE_64, O_SIZE_64, RegID::Invalid(), RegID::Invalid(), 0, disp);} | ||
| 820 | MemT<OpdN> operator[](uint32 disp) {return MemT<OpdN>(O_SIZE_64, O_SIZE_64, RegID::Invalid(), RegID::Invalid(), 0, (sint32) disp);} | ||
| 821 | #else | ||
| 822 | MemT<OpdN> operator[](sint32 disp) {return MemT<OpdN>(O_SIZE_32, O_SIZE_32, RegID::Invalid(), RegID::Invalid(), 0, disp);} | ||
| 823 | MemT<OpdN> operator[](uint32 disp) {return MemT<OpdN>(O_SIZE_32, O_SIZE_32, RegID::Invalid(), RegID::Invalid(), 0, (sint32) disp);} | ||
| 824 | #endif | ||
| 825 | }; | ||
| 826 | |||
| 827 | /// Instruction ID | ||
| 828 | enum InstrID | ||
| 829 | { | ||
| 830 | I_ADC, I_ADD, I_AND, | ||
| 831 | I_BSF, I_BSR, I_BSWAP, I_BT, I_BTC, I_BTR, I_BTS, | ||
| 832 | I_CALL, I_CBW, I_CLC, I_CLD, I_CLI, I_CLTS, I_CMC, I_CMOVCC, I_CMP, I_CMPS_B, I_CMPS_W, I_CMPS_D, I_CMPS_Q, I_CMPXCHG, | ||
| 833 | I_CMPXCHG8B, I_CMPXCHG16B, I_CPUID, I_CWD, I_CDQ, I_CQO, | ||
| 834 | I_DEC, I_DIV, | ||
| 835 | I_ENTER, | ||
| 836 | I_HLT, | ||
| 837 | I_IDIV, I_IMUL, I_IN, I_INC, I_INS_B, I_INS_W, I_INS_D, I_INVD, I_INVLPG, I_INT3, I_INTN, I_INTO, I_IRET, I_IRETD, I_IRETQ, | ||
| 838 | I_JMP, I_JCC, | ||
| 839 | I_LAR, I_LEA, I_LEAVE, I_LLDT, I_LMSW, I_LSL, I_LTR, I_LODS_B, I_LODS_W, I_LODS_D, I_LODS_Q, I_LOOP, | ||
| 840 | I_MOV, I_MOVBE, I_MOVS_B, I_MOVS_W, I_MOVS_D, I_MOVS_Q, I_MOVZX, I_MOVSX, I_MOVSXD, I_MUL, | ||
| 841 | I_NEG, I_NOP, I_NOT, | ||
| 842 | I_OR, I_OUT, I_OUTS_B, I_OUTS_W, I_OUTS_D, | ||
| 843 | I_POP, I_POPAD, I_POPF, I_POPFD, I_POPFQ, I_PUSH, I_PUSHAD, I_PUSHF, I_PUSHFD, I_PUSHFQ, | ||
| 844 | I_RDMSR, I_RDPMC, I_RDTSC, I_RET, I_RCL, I_RCR, I_ROL, I_ROR, I_RSM, | ||
| 845 | I_SAR, I_SHL, I_SHR, I_SBB, I_SCAS_B, I_SCAS_W, I_SCAS_D, I_SCAS_Q, I_SETCC, I_SHLD, I_SHRD, I_SGDT, I_SIDT, I_SLDT, I_SMSW, I_STC, I_STD, I_STI, | ||
| 846 | I_STOS_B, I_STOS_W, I_STOS_D, I_STOS_Q, I_SUB, I_SWAPGS, I_SYSCALL, I_SYSENTER, I_SYSEXIT, I_SYSRET, | ||
| 847 | I_TEST, | ||
| 848 | I_UD2, | ||
| 849 | I_VERR, I_VERW, | ||
| 850 | I_WAIT, I_WBINVD, I_WRMSR, | ||
| 851 | I_XADD, I_XCHG, I_XGETBV, I_XLATB, I_XOR, | ||
| 852 | |||
| 853 | I_F2XM1, I_FABS, I_FADD, I_FADDP, I_FIADD, | ||
| 854 | I_FBLD, I_FBSTP, I_FCHS, I_FCLEX, I_FNCLEX, I_FCMOVCC, I_FCOM, I_FCOMP, I_FCOMPP, I_FCOMI, I_FCOMIP, I_FCOS, | ||
| 855 | I_FDECSTP, I_FDIV, I_FDIVP, I_FIDIV, I_FDIVR, I_FDIVRP, I_FIDIVR, | ||
| 856 | I_FFREE, | ||
| 857 | I_FICOM, I_FICOMP, I_FILD, I_FINCSTP, I_FINIT, I_FNINIT, I_FIST, I_FISTP, | ||
| 858 | I_FLD, I_FLD1, I_FLDCW, I_FLDENV, I_FLDL2E, I_FLDL2T, I_FLDLG2, I_FLDLN2, I_FLDPI, I_FLDZ, | ||
| 859 | I_FMUL, I_FMULP, I_FIMUL, | ||
| 860 | I_FNOP, | ||
| 861 | I_FPATAN, I_FPREM, I_FPREM1, I_FPTAN, | ||
| 862 | I_FRNDINT, I_FRSTOR, | ||
| 863 | I_FSAVE, I_FNSAVE, I_FSCALE, I_FSIN, I_FSINCOS, I_FSQRT, I_FST, I_FSTP, I_FSTCW, I_FNSTCW, I_FSTENV, I_FNSTENV, I_FSTSW, I_FNSTSW, | ||
| 864 | I_FSUB, I_FSUBP, I_FISUB, I_FSUBR, I_FSUBRP, I_FISUBR, | ||
| 865 | I_FTST, | ||
| 866 | I_FUCOM, I_FUCOMP, I_FUCOMPP, I_FUCOMI, I_FUCOMIP, | ||
| 867 | I_FXAM, I_FXCH, I_FXRSTOR, I_FXSAVE, I_FXTRACT, | ||
| 868 | I_FYL2X, I_FYL2XP1, | ||
| 869 | |||
| 870 | I_ADDPS, I_ADDSS, I_ADDPD, I_ADDSD, I_ADDSUBPS, I_ADDSUBPD, I_ANDPS, I_ANDPD, I_ANDNPS, I_ANDNPD, | ||
| 871 | I_BLENDPS, I_BLENDPD, I_BLENDVPS, I_BLENDVPD, | ||
| 872 | I_CLFLUSH, I_CMPPS, I_CMPSS, I_CMPPD, I_CMPSD, I_COMISS, I_COMISD, I_CRC32, | ||
| 873 | I_CVTDQ2PD, I_CVTDQ2PS, I_CVTPD2DQ, I_CVTPD2PI, I_CVTPD2PS, I_CVTPI2PD, I_CVTPI2PS, I_CVTPS2DQ, I_CVTPS2PD, I_CVTPS2PI, I_CVTSD2SI, | ||
| 874 | I_CVTSD2SS, I_CVTSI2SD, I_CVTSI2SS, I_CVTSS2SD, I_CVTSS2SI, I_CVTTPD2DQ, I_CVTTPD2PI, I_CVTTPS2DQ, I_CVTTPS2PI, I_CVTTSD2SI, I_CVTTSS2SI, | ||
| 875 | I_DIVPS, I_DIVSS, I_DIVPD, I_DIVSD, I_DPPS, I_DPPD, | ||
| 876 | I_EMMS, I_EXTRACTPS, | ||
| 877 | I_FISTTP, | ||
| 878 | I_HADDPS, I_HADDPD, I_HSUBPS, I_HSUBPD, | ||
| 879 | I_INSERTPS, | ||
| 880 | I_LDDQU, I_LDMXCSR, I_LFENCE, | ||
| 881 | I_MASKMOVDQU, I_MASKMOVQ, I_MAXPS, I_MAXSS, I_MAXPD, I_MAXSD, I_MFENCE, I_MINPS, I_MINSS, I_MINPD, I_MINSD, I_MONITOR, | ||
| 882 | I_MOVAPD, I_MOVAPS, I_MOVD, I_MOVDDUP, I_MOVDQA, I_MOVDQU, I_MOVDQ2Q, I_MOVHLPS, I_MOVLHPS, I_MOVHPS, I_MOVHPD, I_MOVLPS, I_MOVLPD, | ||
| 883 | I_MOVMSKPS, I_MOVMSKPD, I_MOVNTDQ, I_MOVNTDQA, I_MOVNTI, I_MOVNTPD, I_MOVNTPS, I_MOVNTQ, I_MOVQ, I_MOVQ2DQ, I_MOVSD, I_MOVSS, | ||
| 884 | I_MOVSHDUP, I_MOVSLDUP, I_MOVUPS, I_MOVUPD, I_MPSADBW, I_MULPS, I_MULSS, I_MULPD, I_MULSD, I_MWAIT, | ||
| 885 | I_ORPS, I_ORPD, | ||
| 886 | I_PABSB, I_PABSD, I_PABSW, I_PACKSSDW, I_PACKSSWB, I_PACKUSDW, I_PACKUSWB, I_PADDB, I_PADDD, I_PADDQ, I_PADDSB, I_PADDSW, I_PADDUSB, | ||
| 887 | I_PADDUSW, I_PADDW, I_PALIGNR, I_PAND, I_PANDN, I_PAUSE, I_PAVGB, I_PAVGW, | ||
| 888 | I_PBLENDVB, I_PBLENDW, | ||
| 889 | I_PCMPEQB, I_PCMPEQW, I_PCMPEQD, I_PCMPEQQ, I_PCMPESTRI, I_PCMPESTRM, I_PCMPISTRI, I_PCMPISTRM, I_PCMPGTB, I_PCMPGTW, I_PCMPGTD, I_PCMPGTQ, | ||
| 890 | I_PEXTRB, I_PEXTRW, I_PEXTRD, I_PEXTRQ, | ||
| 891 | I_PHADDW, I_PHADDD, I_PHADDSW, I_PHMINPOSUW, I_PHSUBW, I_PHSUBD, I_PHSUBSW, | ||
| 892 | I_PINSRB, I_PINSRW, I_PINSRD, I_PINSRQ, | ||
| 893 | I_PMADDUBSW, I_PMADDWD, I_PMAXSB, I_PMAXSW, I_PMAXSD, I_PMAXUB, I_PMAXUW, I_PMAXUD, I_PMINSB, I_PMINSW, I_PMINSD, I_PMINUB, I_PMINUW, | ||
| 894 | I_PMINUD, I_PMOVMSKB, I_PMOVSXBW, I_PMOVSXBD, I_PMOVSXBQ, I_PMOVSXWD, I_PMOVSXWQ, I_PMOVSXDQ, I_PMOVZXBW, I_PMOVZXBD, I_PMOVZXBQ, I_PMOVZXWD, | ||
| 895 | I_PMOVZXWQ, I_PMOVZXDQ, I_PMULDQ, I_PMULHRSW, I_PMULHUW, I_PMULHW, I_PMULLW, I_PMULLD, I_PMULUDQ, | ||
| 896 | I_POPCNT, I_POR, | ||
| 897 | I_PREFETCH, | ||
| 898 | I_PSADBW, I_PSHUFB, I_PSHUFD, I_PSHUFHW, I_PSHUFLW, I_PSHUFW, I_PSIGNB, I_PSIGNW, I_PSIGND, I_PSLLW, I_PSLLD, I_PSLLQ, I_PSLLDQ, I_PSRAW, | ||
| 899 | I_PSRAD, I_PSRLW, I_PSRLD, I_PSRLQ, I_PSRLDQ, I_PSUBB, I_PSUBW, I_PSUBD, I_PSUBQ, I_PSUBSB, I_PSUBSW, I_PSUBUSB, I_PSUBUSW, | ||
| 900 | I_PTEST, | ||
| 901 | I_PUNPCKHBW, I_PUNPCKHWD, I_PUNPCKHDQ, I_PUNPCKHQDQ, I_PUNPCKLBW, I_PUNPCKLWD, I_PUNPCKLDQ, I_PUNPCKLQDQ, | ||
| 902 | I_PXOR, | ||
| 903 | I_RCPPS, I_RCPSS, I_ROUNDPS, I_ROUNDPD, I_ROUNDSS, I_ROUNDSD, I_RSQRTPS, I_RSQRTSS, | ||
| 904 | I_SFENCE, I_SHUFPS, I_SHUFPD, I_SQRTPS, I_SQRTSS, I_SQRTPD, I_SQRTSD, I_STMXCSR, I_SUBPS, I_SUBSS, I_SUBPD, I_SUBSD, | ||
| 905 | I_UCOMISS, I_UCOMISD, I_UNPCKHPS, I_UNPCKHPD, I_UNPCKLPS, I_UNPCKLPD, | ||
| 906 | I_XORPS, I_XORPD, | ||
| 907 | |||
| 908 | I_VBROADCASTSS, I_VBROADCASTSD, I_VBROADCASTF128, | ||
| 909 | I_VEXTRACTF128, | ||
| 910 | I_VINSERTF128, | ||
| 911 | I_VMASKMOVPS, I_VMASKMOVPD, | ||
| 912 | I_VPERMILPD, I_VPERMILPS, I_VPERM2F128, | ||
| 913 | I_VTESTPS, I_VTESTPD, | ||
| 914 | I_VZEROALL, I_VZEROUPPER, | ||
| 915 | |||
| 916 | I_AESENC, I_AESENCLAST, I_AESDEC, I_AESDECLAST, I_AESIMC, I_AESKEYGENASSIST, | ||
| 917 | I_PCLMULQDQ, | ||
| 918 | |||
| 919 | // FMA | ||
| 920 | I_VFMADD132PD, I_VFMADD213PD, I_VFMADD231PD, I_VFMADD132PS, I_VFMADD213PS, I_VFMADD231PS, | ||
| 921 | I_VFMADD132SD, I_VFMADD213SD, I_VFMADD231SD, I_VFMADD132SS, I_VFMADD213SS, I_VFMADD231SS, | ||
| 922 | I_VFMADDSUB132PD, I_VFMADDSUB213PD, I_VFMADDSUB231PD, I_VFMADDSUB132PS, I_VFMADDSUB213PS, I_VFMADDSUB231PS, | ||
| 923 | I_VFMSUBADD132PD, I_VFMSUBADD213PD, I_VFMSUBADD231PD, I_VFMSUBADD132PS, I_VFMSUBADD213PS, I_VFMSUBADD231PS, | ||
| 924 | I_VFMSUB132PD, I_VFMSUB213PD, I_VFMSUB231PD, I_VFMSUB132PS, I_VFMSUB213PS, I_VFMSUB231PS, | ||
| 925 | I_VFMSUB132SD, I_VFMSUB213SD, I_VFMSUB231SD, I_VFMSUB132SS, I_VFMSUB213SS, I_VFMSUB231SS, | ||
| 926 | I_VFNMADD132PD, I_VFNMADD213PD, I_VFNMADD231PD, I_VFNMADD132PS, I_VFNMADD213PS, I_VFNMADD231PS, | ||
| 927 | I_VFNMADD132SD, I_VFNMADD213SD, I_VFNMADD231SD, I_VFNMADD132SS, I_VFNMADD213SS, I_VFNMADD231SS, | ||
| 928 | I_VFNMSUB132PD, I_VFNMSUB213PD, I_VFNMSUB231PD, I_VFNMSUB132PS, I_VFNMSUB213PS, I_VFNMSUB231PS, | ||
| 929 | I_VFNMSUB132SD, I_VFNMSUB213SD, I_VFNMSUB231SD, I_VFNMSUB132SS, I_VFNMSUB213SS, I_VFNMSUB231SS, | ||
| 930 | |||
| 931 | // F16C | ||
| 932 | I_RDFSBASE, I_RDGSBASE, I_RDRAND, I_WRFSBASE, I_WRGSBASE, I_VCVTPH2PS, I_VCVTPS2PH, | ||
| 933 | |||
| 934 | // BMI | ||
| 935 | I_ANDN, I_BEXTR, I_BLSI, I_BLSMSK, I_BLSR, I_BZHI, I_LZCNT, I_MULX, I_PDEP, I_PEXT, I_RORX, I_SARX, I_SHLX, I_SHRX, I_TZCNT, I_INVPCID, | ||
| 936 | |||
| 937 | // XOP | ||
| 938 | I_VFRCZPD, I_VFRCZPS, I_VFRCZSD, I_VFRCZSS, | ||
| 939 | I_VPCMOV, I_VPCOMB, I_VPCOMD, I_VPCOMQ, I_VPCOMUB, I_VPCOMUD, I_VPCOMUQ, I_VPCOMUW, I_VPCOMW, I_VPERMIL2PD, I_VPERMIL2PS, | ||
| 940 | I_VPHADDBD, I_VPHADDBQ, I_VPHADDBW, I_VPHADDDQ, I_VPHADDUBD, I_VPHADDUBQ, I_VPHADDUBW, I_VPHADDUDQ, I_VPHADDUWD, I_VPHADDUWQ, | ||
| 941 | I_VPHADDWD, I_VPHADDWQ, I_VPHSUBBW, I_VPHSUBDQ, I_VPHSUBWD, | ||
| 942 | I_VPMACSDD, I_VPMACSDQH, I_VPMACSDQL, I_VPMACSSDD, I_VPMACSSDQH, I_VPMACSSDQL, I_VPMACSSWD, I_VPMACSSWW, I_VPMACSWD, I_VPMACSWW, | ||
| 943 | I_VPMADCSSWD, I_VPMADCSWD, | ||
| 944 | I_VPPERM, I_VPROTB, I_VPROTD, I_VPROTQ, I_VPROTW, I_VPSHAB, I_VPSHAD, I_VPSHAQ, I_VPSHAW, I_VPSHLB, I_VPSHLD, I_VPSHLQ, I_VPSHLW, | ||
| 945 | |||
| 946 | // FMA4 | ||
| 947 | I_VFMADDPD, I_VFMADDPS, I_VFMADDSD, I_VFMADDSS, | ||
| 948 | I_VFMADDSUBPD, I_VFMADDSUBPS, | ||
| 949 | I_VFMSUBADDPD, I_VFMSUBADDPS, | ||
| 950 | I_VFMSUBPD, I_VFMSUBPS, I_VFMSUBSD, I_VFMSUBSS, | ||
| 951 | I_VFNMADDPD, I_VFNMADDPS, I_VFNMADDSD, I_VFNMADDSS, | ||
| 952 | I_VFNMSUBPD, I_VFNMSUBPS, I_VFNMSUBSD, I_VFNMSUBSS, | ||
| 953 | |||
| 954 | // AVX2 | ||
| 955 | I_VBROADCASTI128, I_VPBROADCASTB, I_VPBROADCASTW, I_VPBROADCASTD, I_VPBROADCASTQ, | ||
| 956 | I_PBLENDD, I_VPERMD, I_VPERMQ, I_VPERMPS, I_VPERMPD, I_VPERM2I128, | ||
| 957 | I_VEXTRACTI128, I_VINSERTI128, I_VMASKMOVD, I_VMASKMOVQ, I_VPSLLVD, I_VPSLLVQ, I_VPSRAVD, I_VPSRLVD, I_VPSRLVQ, | ||
| 958 | I_VGATHERDPS, I_VGATHERQPS, I_VGATHERDPD, I_VGATHERQPD, I_VPGATHERDD, I_VPGATHERQD, I_VPGATHERDQ, I_VPGATHERQQ, | ||
| 959 | |||
| 960 | // jitasm compiler instructions | ||
| 961 | I_COMPILER_DECLARE_REG_ARG, ///< Declare register argument | ||
| 962 | I_COMPILER_DECLARE_STACK_ARG, ///< Declare stack argument | ||
| 963 | I_COMPILER_DECLARE_RESULT_REG, ///< Declare result register (eax/rax/xmm0) | ||
| 964 | I_COMPILER_PROLOG, ///< Function prolog | ||
| 965 | I_COMPILER_EPILOG ///< Function epilog | ||
| 966 | }; | ||
| 967 | |||
| 968 | enum JumpCondition | ||
| 969 | { | ||
| 970 | JCC_O, JCC_NO, JCC_B, JCC_AE, JCC_E, JCC_NE, JCC_BE, JCC_A, JCC_S, JCC_NS, JCC_P, JCC_NP, JCC_L, JCC_GE, JCC_LE, JCC_G, | ||
| 971 | JCC_CXZ, JCC_ECXZ, JCC_RCXZ, | ||
| 972 | }; | ||
| 973 | |||
| 974 | enum EncodingFlags | ||
| 975 | { | ||
| 976 | E_SPECIAL = 1 << 0, | ||
| 977 | E_OPERAND_SIZE_PREFIX = 1 << 1, ///< Operand-size override prefix | ||
| 978 | E_REP_PREFIX = 1 << 2, ///< REP prefix | ||
| 979 | E_REXW_PREFIX = 1 << 3, ///< REX.W | ||
| 980 | E_MANDATORY_PREFIX_66 = 1 << 4, ///< Mandatory prefix 66 | ||
| 981 | E_MANDATORY_PREFIX_F2 = 1 << 5, ///< Mandatory prefix F2 | ||
| 982 | E_MANDATORY_PREFIX_F3 = 1 << 6, ///< Mandatory prefix F3 | ||
| 983 | E_VEX = 1 << 7, | ||
| 984 | E_XOP = 1 << 8, | ||
| 985 | E_VEX_L = 1 << 9, | ||
| 986 | E_VEX_W = 1 << 10, | ||
| 987 | E_VEX_MMMMM_SHIFT = 11, | ||
| 988 | E_VEX_MMMMM_MASK = 0x1F << E_VEX_MMMMM_SHIFT, | ||
| 989 | E_VEX_0F = 1 << E_VEX_MMMMM_SHIFT, | ||
| 990 | E_VEX_0F38 = 2 << E_VEX_MMMMM_SHIFT, | ||
| 991 | E_VEX_0F3A = 3 << E_VEX_MMMMM_SHIFT, | ||
| 992 | E_XOP_M00011 = 3 << E_VEX_MMMMM_SHIFT, | ||
| 993 | E_XOP_M01000 = 8 << E_VEX_MMMMM_SHIFT, | ||
| 994 | E_XOP_M01001 = 9 << E_VEX_MMMMM_SHIFT, | ||
| 995 | E_VEX_PP_SHIFT = 16, | ||
| 996 | E_VEX_PP_MASK = 0x3 << E_VEX_PP_SHIFT, | ||
| 997 | E_VEX_66 = 1 << E_VEX_PP_SHIFT, | ||
| 998 | E_VEX_F3 = 2 << E_VEX_PP_SHIFT, | ||
| 999 | E_VEX_F2 = 3 << E_VEX_PP_SHIFT, | ||
| 1000 | E_XOP_P00 = 0 << E_VEX_PP_SHIFT, | ||
| 1001 | E_XOP_P01 = 1 << E_VEX_PP_SHIFT, | ||
| 1002 | |||
| 1003 | E_VEX_128 = E_VEX, | ||
| 1004 | E_VEX_256 = E_VEX | E_VEX_L, | ||
| 1005 | E_VEX_LIG = E_VEX, | ||
| 1006 | E_VEX_LZ = E_VEX, | ||
| 1007 | E_VEX_66_0F = E_VEX_66 | E_VEX_0F, | ||
| 1008 | E_VEX_66_0F38 = E_VEX_66 | E_VEX_0F38, | ||
| 1009 | E_VEX_66_0F3A = E_VEX_66 | E_VEX_0F3A, | ||
| 1010 | E_VEX_F2_0F = E_VEX_F2 | E_VEX_0F, | ||
| 1011 | E_VEX_F2_0F38 = E_VEX_F2 | E_VEX_0F38, | ||
| 1012 | E_VEX_F2_0F3A = E_VEX_F2 | E_VEX_0F3A, | ||
| 1013 | E_VEX_F3_0F = E_VEX_F3 | E_VEX_0F, | ||
| 1014 | E_VEX_F3_0F38 = E_VEX_F3 | E_VEX_0F38, | ||
| 1015 | E_VEX_F3_0F3A = E_VEX_F3 | E_VEX_0F3A, | ||
| 1016 | E_VEX_W0 = 0, | ||
| 1017 | E_VEX_W1 = E_VEX_W, | ||
| 1018 | E_VEX_WIG = 0, | ||
| 1019 | E_XOP_128 = E_XOP, | ||
| 1020 | E_XOP_256 = E_XOP | E_VEX_L, | ||
| 1021 | E_XOP_W0 = 0, | ||
| 1022 | E_XOP_W1 = E_VEX_W, | ||
| 1023 | |||
| 1024 | // Aliases | ||
| 1025 | E_VEX_128_0F_WIG = E_VEX_128 | E_VEX_0F | E_VEX_WIG, | ||
| 1026 | E_VEX_256_0F_WIG = E_VEX_256 | E_VEX_0F | E_VEX_WIG, | ||
| 1027 | E_VEX_128_66_0F_WIG = E_VEX_128 | E_VEX_66_0F | E_VEX_WIG, | ||
| 1028 | E_VEX_256_66_0F_WIG = E_VEX_256 | E_VEX_66_0F | E_VEX_WIG, | ||
| 1029 | E_VEX_128_66_0F38_WIG = E_VEX_128 | E_VEX_66_0F38 | E_VEX_WIG, | ||
| 1030 | E_VEX_256_66_0F38_WIG = E_VEX_256 | E_VEX_66_0F38 | E_VEX_WIG, | ||
| 1031 | E_VEX_128_66_0F38_W0 = E_VEX_128 | E_VEX_66_0F38 | E_VEX_W0, | ||
| 1032 | E_VEX_256_66_0F38_W0 = E_VEX_256 | E_VEX_66_0F38 | E_VEX_W0, | ||
| 1033 | E_VEX_128_66_0F38_W1 = E_VEX_128 | E_VEX_66_0F38 | E_VEX_W1, | ||
| 1034 | E_VEX_256_66_0F38_W1 = E_VEX_256 | E_VEX_66_0F38 | E_VEX_W1, | ||
| 1035 | E_VEX_128_66_0F3A_W0 = E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, | ||
| 1036 | E_VEX_256_66_0F3A_W0 = E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, | ||
| 1037 | }; | ||
| 1038 | |||
| 1039 | /// Instruction | ||
| 1040 | struct Instr | ||
| 1041 | { | ||
| 1042 | static const size_t MAX_OPERAND_COUNT = 6; | ||
| 1043 | |||
| 1044 | InstrID id_; ///< Instruction ID | ||
| 1045 | uint32 opcode_; ///< Opcode | ||
| 1046 | uint32 encoding_flag_; ///< EncodingFlags | ||
| 1047 | detail::Opd opd_[MAX_OPERAND_COUNT]; ///< Operands | ||
| 1048 | |||
| 1049 | ✗ | Instr(InstrID id, uint32 opcode, uint32 encoding_flag, const detail::Opd& opd1 = detail::Opd(), const detail::Opd& opd2 = detail::Opd(), const detail::Opd& opd3 = detail::Opd(), const detail::Opd& opd4 = detail::Opd(), const detail::Opd& opd5 = detail::Opd(), const detail::Opd& opd6 = detail::Opd()) | |
| 1050 | ✗ | : id_(id), opcode_(opcode), encoding_flag_(encoding_flag) {opd_[0] = opd1, opd_[1] = opd2, opd_[2] = opd3, opd_[3] = opd4, opd_[4] = opd5, opd_[5] = opd6;} | |
| 1051 | |||
| 1052 | ✗ | InstrID GetID() const {return id_;} | |
| 1053 | ✗ | const detail::Opd& GetOpd(size_t index) const {return opd_[index];} | |
| 1054 | ✗ | detail::Opd& GetOpd(size_t index) {return opd_[index];} | |
| 1055 | }; | ||
| 1056 | |||
| 1057 | /// Assembler backend | ||
| 1058 | struct Backend | ||
| 1059 | { | ||
| 1060 | uint8* pbuff_; | ||
| 1061 | size_t buffsize_; | ||
| 1062 | size_t size_; | ||
| 1063 | |||
| 1064 | ✗ | Backend(void* pbuff = NULL, size_t buffsize = 0) : pbuff_((uint8*) pbuff), buffsize_(buffsize), size_(0) | |
| 1065 | { | ||
| 1066 | ✗ | memset(pbuff, 0xCC, buffsize); // INT3 | |
| 1067 | ✗ | } | |
| 1068 | |||
| 1069 | ✗ | size_t GetSize() const | |
| 1070 | { | ||
| 1071 | ✗ | return size_; | |
| 1072 | } | ||
| 1073 | |||
| 1074 | ✗ | void put_bytes(void* p, size_t n) | |
| 1075 | { | ||
| 1076 | ✗ | uint8* pb = (uint8*) p; | |
| 1077 | ✗ | while (n--) { | |
| 1078 | ✗ | if (pbuff_) { | |
| 1079 | ✗ | if (size_ == buffsize_) JITASM_ASSERT(0); | |
| 1080 | ✗ | pbuff_[size_] = *pb++; | |
| 1081 | } | ||
| 1082 | ✗ | size_++; | |
| 1083 | } | ||
| 1084 | ✗ | } | |
| 1085 | ✗ | void db(uint64 b) {put_bytes(&b, 1);} | |
| 1086 | ✗ | void dw(uint64 w) {put_bytes(&w, 2);} | |
| 1087 | ✗ | void dd(uint64 d) {put_bytes(&d, 4);} | |
| 1088 | ✗ | void dq(uint64 q) {put_bytes(&q, 8);} | |
| 1089 | |||
| 1090 | ✗ | uint8 GetWRXB(int w, const detail::Opd& reg, const detail::Opd& r_m) | |
| 1091 | { | ||
| 1092 | ✗ | uint8 wrxb = w ? 8 : 0; | |
| 1093 | ✗ | if (reg.IsReg()) { | |
| 1094 | ✗ | if (!reg.GetReg().IsInvalid() && reg.GetReg().id >= R8) wrxb |= 4; | |
| 1095 | } | ||
| 1096 | ✗ | if (r_m.IsReg()) { | |
| 1097 | ✗ | if (r_m.GetReg().id >= R8) wrxb |= 1; | |
| 1098 | } | ||
| 1099 | ✗ | if (r_m.IsMem()) { | |
| 1100 | ✗ | if (!r_m.GetIndex().IsInvalid() && r_m.GetIndex().id >= R8) wrxb |= 2; | |
| 1101 | ✗ | if (!r_m.GetBase().IsInvalid() && r_m.GetBase().id >= R8) wrxb |= 1; | |
| 1102 | } | ||
| 1103 | ✗ | return wrxb; | |
| 1104 | } | ||
| 1105 | |||
| 1106 | ✗ | void EncodePrefixes(uint32 flag, const detail::Opd& reg, const detail::Opd& r_m, const detail::Opd& vex) | |
| 1107 | { | ||
| 1108 | ✗ | if (flag & (E_VEX | E_XOP)) { | |
| 1109 | // Encode VEX prefix | ||
| 1110 | #ifdef JITASM64 | ||
| 1111 | ✗ | if (r_m.IsMem() && r_m.GetAddressBaseSize() != O_SIZE_64) db(0x67); | |
| 1112 | #endif | ||
| 1113 | ✗ | uint8 vvvv = vex.IsReg() ? 0xF - (uint8) vex.GetReg().id : 0xF; | |
| 1114 | ✗ | uint8 mmmmm = (flag & E_VEX_MMMMM_MASK) >> E_VEX_MMMMM_SHIFT; | |
| 1115 | ✗ | uint8 pp = static_cast<uint8>((flag & E_VEX_PP_MASK) >> E_VEX_PP_SHIFT); | |
| 1116 | ✗ | uint8 wrxb = GetWRXB(flag & E_VEX_W, reg, r_m); | |
| 1117 | ✗ | if (flag & E_XOP) { | |
| 1118 | ✗ | db(0x8F); | |
| 1119 | ✗ | db((~wrxb & 7) << 5 | mmmmm); | |
| 1120 | ✗ | db((wrxb & 8) << 4 | vvvv << 3 | (flag & E_VEX_L ? 4 : 0) | pp); | |
| 1121 | ✗ | } else if (wrxb & 0xB || (flag & E_VEX_MMMMM_MASK) == E_VEX_0F38 || (flag & E_VEX_MMMMM_MASK) == E_VEX_0F3A) { | |
| 1122 | ✗ | db(0xC4); | |
| 1123 | ✗ | db((~wrxb & 7) << 5 | mmmmm); | |
| 1124 | ✗ | db((wrxb & 8) << 4 | vvvv << 3 | (flag & E_VEX_L ? 4 : 0) | pp); | |
| 1125 | } else { | ||
| 1126 | ✗ | db(0xC5); | |
| 1127 | ✗ | db((~wrxb & 4) << 5 | vvvv << 3 | (flag & E_VEX_L ? 4 : 0) | pp); | |
| 1128 | } | ||
| 1129 | } else { | ||
| 1130 | ✗ | uint8 wrxb = GetWRXB(flag & E_REXW_PREFIX, reg, r_m); | |
| 1131 | ✗ | if (wrxb) { | |
| 1132 | // Encode REX prefix | ||
| 1133 | ✗ | JITASM_ASSERT(!reg.IsReg() || reg.GetSize() != O_SIZE_8 || reg.GetReg().id < AH || reg.GetReg().id >= R8B); // AH, BH, CH, or DH may not be used with REX. | |
| 1134 | ✗ | JITASM_ASSERT(!r_m.IsReg() || r_m.GetSize() != O_SIZE_8 || r_m.GetReg().id < AH || r_m.GetReg().id >= R8B); // AH, BH, CH, or DH may not be used with REX. | |
| 1135 | |||
| 1136 | ✗ | if (flag & E_REP_PREFIX) db(0xF3); | |
| 1137 | #ifdef JITASM64 | ||
| 1138 | ✗ | if (r_m.IsMem() && r_m.GetAddressBaseSize() != O_SIZE_64) db(0x67); | |
| 1139 | #endif | ||
| 1140 | ✗ | if (flag & E_OPERAND_SIZE_PREFIX) db(0x66); | |
| 1141 | |||
| 1142 | ✗ | if (flag & E_MANDATORY_PREFIX_66) db(0x66); | |
| 1143 | ✗ | else if (flag & E_MANDATORY_PREFIX_F2) db(0xF2); | |
| 1144 | ✗ | else if (flag & E_MANDATORY_PREFIX_F3) db(0xF3); | |
| 1145 | |||
| 1146 | ✗ | db(0x40 | wrxb); | |
| 1147 | } else { | ||
| 1148 | ✗ | if (flag & E_MANDATORY_PREFIX_66) db(0x66); | |
| 1149 | ✗ | else if (flag & E_MANDATORY_PREFIX_F2) db(0xF2); | |
| 1150 | ✗ | else if (flag & E_MANDATORY_PREFIX_F3) db(0xF3); | |
| 1151 | |||
| 1152 | ✗ | if (flag & E_REP_PREFIX) db(0xF3); | |
| 1153 | #ifdef JITASM64 | ||
| 1154 | ✗ | if (r_m.IsMem() && r_m.GetAddressBaseSize() != O_SIZE_64) db(0x67); | |
| 1155 | #endif | ||
| 1156 | ✗ | if (flag & E_OPERAND_SIZE_PREFIX) db(0x66); | |
| 1157 | } | ||
| 1158 | } | ||
| 1159 | ✗ | } | |
| 1160 | |||
| 1161 | ✗ | void EncodeModRM(uint8 reg, const detail::Opd& r_m) | |
| 1162 | { | ||
| 1163 | ✗ | reg &= 0x7; | |
| 1164 | |||
| 1165 | ✗ | if (r_m.IsReg()) { | |
| 1166 | ✗ | db(0xC0 | (reg << 3) | (r_m.GetReg().id & 0x7)); | |
| 1167 | ✗ | } else if (r_m.IsMem()) { | |
| 1168 | ✗ | JITASM_ASSERT(r_m.GetBase().type == R_TYPE_GP && (r_m.GetIndex().type == R_TYPE_GP || r_m.GetIndex().type == R_TYPE_XMM || r_m.GetIndex().type == R_TYPE_YMM)); | |
| 1169 | ✗ | int base = r_m.GetBase().id; if (base != INVALID) base &= 0x7; | |
| 1170 | ✗ | int index = r_m.GetIndex().id; if (index != INVALID) index &= 0x7; | |
| 1171 | |||
| 1172 | ✗ | if (base == INVALID && index == INVALID) { | |
| 1173 | #ifdef JITASM64 | ||
| 1174 | ✗ | db(reg << 3 | 4); | |
| 1175 | ✗ | db(0x25); | |
| 1176 | #else | ||
| 1177 | db(reg << 3 | 5); | ||
| 1178 | #endif | ||
| 1179 | ✗ | dd(r_m.GetDisp()); | |
| 1180 | } else { | ||
| 1181 | ✗ | JITASM_ASSERT(base != ESP || index != ESP); | |
| 1182 | ✗ | JITASM_ASSERT(index != ESP || r_m.GetScale() == 0); | |
| 1183 | |||
| 1184 | ✗ | if (index == ESP) { | |
| 1185 | ✗ | index = base; | |
| 1186 | ✗ | base = ESP; | |
| 1187 | } | ||
| 1188 | ✗ | bool sib = index != INVALID || r_m.GetScale() || base == ESP; | |
| 1189 | |||
| 1190 | // ModR/M | ||
| 1191 | ✗ | uint8 mod = 0; | |
| 1192 | ✗ | if (r_m.GetDisp() == 0 || (sib && base == INVALID)) mod = base != EBP ? 0 : 1; | |
| 1193 | ✗ | else if (detail::IsInt8(r_m.GetDisp())) mod = 1; | |
| 1194 | ✗ | else if (detail::IsInt32(r_m.GetDisp())) mod = 2; | |
| 1195 | ✗ | else JITASM_ASSERT(0); | |
| 1196 | ✗ | db(mod << 6 | reg << 3 | (sib ? 4 : base)); | |
| 1197 | |||
| 1198 | // SIB | ||
| 1199 | ✗ | if (sib) { | |
| 1200 | ✗ | uint8 ss = 0; | |
| 1201 | ✗ | if (r_m.GetScale() == 0) ss = 0; | |
| 1202 | ✗ | else if (r_m.GetScale() == 2) ss = 1; | |
| 1203 | ✗ | else if (r_m.GetScale() == 4) ss = 2; | |
| 1204 | ✗ | else if (r_m.GetScale() == 8) ss = 3; | |
| 1205 | ✗ | else JITASM_ASSERT(0); | |
| 1206 | ✗ | if (index != INVALID && base != INVALID) { | |
| 1207 | ✗ | db(ss << 6 | index << 3 | base); | |
| 1208 | ✗ | } else if (base != INVALID) { | |
| 1209 | ✗ | db(ss << 6 | 4 << 3 | base); | |
| 1210 | ✗ | } else if (index != INVALID) { | |
| 1211 | ✗ | db(ss << 6 | index << 3 | 5); | |
| 1212 | } else { | ||
| 1213 | ✗ | JITASM_ASSERT(0); | |
| 1214 | } | ||
| 1215 | } | ||
| 1216 | |||
| 1217 | // Displacement | ||
| 1218 | ✗ | if (mod == 0 && sib && base == INVALID) dd(r_m.GetDisp()); | |
| 1219 | ✗ | if (mod == 1) db(r_m.GetDisp()); | |
| 1220 | ✗ | if (mod == 2) dd(r_m.GetDisp()); | |
| 1221 | } | ||
| 1222 | } else { | ||
| 1223 | ✗ | JITASM_ASSERT(0); | |
| 1224 | } | ||
| 1225 | ✗ | } | |
| 1226 | |||
| 1227 | ✗ | void EncodeOpcode(uint32 opcode) | |
| 1228 | { | ||
| 1229 | ✗ | if (opcode & 0xFF000000) db((opcode >> 24) & 0xFF); | |
| 1230 | ✗ | if (opcode & 0xFFFF0000) db((opcode >> 16) & 0xFF); | |
| 1231 | ✗ | if (opcode & 0xFFFFFF00) db((opcode >> 8) & 0xFF); | |
| 1232 | ✗ | db(opcode & 0xFF); | |
| 1233 | ✗ | } | |
| 1234 | |||
| 1235 | ✗ | void EncodeImm(const detail::Opd& imm) | |
| 1236 | { | ||
| 1237 | ✗ | const OpdSize size = imm.GetSize(); | |
| 1238 | ✗ | if (size == O_SIZE_8) db(imm.GetImm()); | |
| 1239 | ✗ | else if (size == O_SIZE_16) dw(imm.GetImm()); | |
| 1240 | ✗ | else if (size == O_SIZE_32) dd(imm.GetImm()); | |
| 1241 | ✗ | else if (size == O_SIZE_64) dq(imm.GetImm()); | |
| 1242 | ✗ | else JITASM_ASSERT(0); | |
| 1243 | ✗ | } | |
| 1244 | |||
| 1245 | ✗ | void Encode(const Instr& instr) | |
| 1246 | { | ||
| 1247 | ✗ | uint32 opcode = instr.opcode_; | |
| 1248 | |||
| 1249 | ✗ | const detail::Opd& opd1 = instr.GetOpd(0).IsDummy() ? detail::Opd() : instr.GetOpd(0); JITASM_ASSERT(!(opd1.IsReg() && opd1.GetReg().IsSymbolic())); | |
| 1250 | ✗ | const detail::Opd& opd2 = instr.GetOpd(1).IsDummy() ? detail::Opd() : instr.GetOpd(1); JITASM_ASSERT(!(opd2.IsReg() && opd2.GetReg().IsSymbolic())); | |
| 1251 | ✗ | const detail::Opd& opd3 = instr.GetOpd(2).IsDummy() ? detail::Opd() : instr.GetOpd(2); JITASM_ASSERT(!(opd3.IsReg() && opd3.GetReg().IsSymbolic())); | |
| 1252 | ✗ | const detail::Opd& opd4 = instr.GetOpd(3).IsDummy() ? detail::Opd() : instr.GetOpd(3); JITASM_ASSERT(!(opd4.IsReg() && opd4.GetReg().IsSymbolic())); | |
| 1253 | |||
| 1254 | // +rb, +rw, +rd, +ro | ||
| 1255 | ✗ | if (opd1.IsReg() && (opd2.IsNone() || opd2.IsImm())) { | |
| 1256 | ✗ | opcode += opd1.GetReg().id & 0x7; | |
| 1257 | } | ||
| 1258 | |||
| 1259 | ✗ | if ((opd1.IsImm() || opd1.IsReg()) && (opd2.IsReg() || opd2.IsMem())) { // ModR/M | |
| 1260 | ✗ | const detail::Opd& reg = opd1; | |
| 1261 | ✗ | const detail::Opd& r_m = opd2; | |
| 1262 | ✗ | const detail::Opd& vex = opd3; | |
| 1263 | ✗ | EncodePrefixes(instr.encoding_flag_, reg, r_m, vex); | |
| 1264 | ✗ | EncodeOpcode(opcode); | |
| 1265 | ✗ | EncodeModRM((uint8) (reg.IsImm() ? reg.GetImm() : reg.GetReg().id), r_m); | |
| 1266 | |||
| 1267 | // /is4 | ||
| 1268 | ✗ | if (opd4.IsReg()) { | |
| 1269 | ✗ | EncodeImm(Imm8(static_cast<uint8>(opd4.GetReg().id << 4))); | |
| 1270 | } | ||
| 1271 | } else { | ||
| 1272 | ✗ | const detail::Opd& reg = detail::Opd(); | |
| 1273 | ✗ | const detail::Opd& r_m = opd1.IsReg() ? opd1 : detail::Opd(); | |
| 1274 | ✗ | const detail::Opd& vex = detail::Opd(); | |
| 1275 | ✗ | EncodePrefixes(instr.encoding_flag_, reg, r_m, vex); | |
| 1276 | ✗ | EncodeOpcode(opcode); | |
| 1277 | } | ||
| 1278 | |||
| 1279 | ✗ | if (opd1.IsImm() && !opd2.IsReg() && !opd2.IsMem()) EncodeImm(opd1); | |
| 1280 | ✗ | if (opd2.IsImm()) EncodeImm(opd2); | |
| 1281 | ✗ | if (opd3.IsImm()) EncodeImm(opd3); | |
| 1282 | ✗ | if (opd4.IsImm()) EncodeImm(opd4); | |
| 1283 | ✗ | } | |
| 1284 | |||
| 1285 | ✗ | void EncodeALU(const Instr& instr, uint32 opcode) | |
| 1286 | { | ||
| 1287 | ✗ | const detail::Opd& reg = instr.GetOpd(1); | |
| 1288 | ✗ | const detail::Opd& imm = instr.GetOpd(2); | |
| 1289 | ✗ | JITASM_ASSERT(instr.GetOpd(0).IsImm() && reg.IsReg() && imm.IsImm()); | |
| 1290 | |||
| 1291 | ✗ | if (reg.GetReg().id == EAX && (reg.GetSize() == O_SIZE_8 || !detail::IsInt8(imm.GetImm()))) { | |
| 1292 | ✗ | opcode |= (reg.GetSize() == O_SIZE_8 ? 0 : 1); | |
| 1293 | ✗ | Encode(Instr(instr.GetID(), opcode, instr.encoding_flag_, reg, imm)); | |
| 1294 | } else { | ||
| 1295 | ✗ | Encode(instr); | |
| 1296 | } | ||
| 1297 | ✗ | } | |
| 1298 | |||
| 1299 | ✗ | void EncodeJMP(const Instr& instr) | |
| 1300 | { | ||
| 1301 | ✗ | const detail::Opd& imm = instr.GetOpd(0); | |
| 1302 | ✗ | if (instr.GetID() == I_JMP) { | |
| 1303 | ✗ | Encode(Instr(instr.GetID(), imm.GetSize() == O_SIZE_8 ? 0xEB : 0xE9, instr.encoding_flag_, imm)); | |
| 1304 | ✗ | } else if (instr.GetID() == I_JCC) { | |
| 1305 | #ifndef JITASM64 | ||
| 1306 | uint32 tttn = instr.opcode_; | ||
| 1307 | if (tttn == JCC_CXZ) Encode(Instr(instr.GetID(), 0x67E3, instr.encoding_flag_, imm)); | ||
| 1308 | else if (tttn == JCC_ECXZ) Encode(Instr(instr.GetID(), 0xE3, instr.encoding_flag_, imm)); | ||
| 1309 | else Encode(Instr(instr.GetID(), (imm.GetSize() == O_SIZE_8 ? 0x70 : 0x0F80) | tttn, instr.encoding_flag_, imm)); | ||
| 1310 | #else | ||
| 1311 | ✗ | uint32 tttn = instr.opcode_; | |
| 1312 | ✗ | if (tttn == JCC_ECXZ) Encode(Instr(instr.GetID(), 0x67E3, instr.encoding_flag_, imm)); | |
| 1313 | ✗ | else if (tttn == JCC_RCXZ) Encode(Instr(instr.GetID(), 0xE3, instr.encoding_flag_, imm)); | |
| 1314 | ✗ | else Encode(Instr(instr.GetID(), (imm.GetSize() == O_SIZE_8 ? 0x70 : 0x0F80) | tttn, instr.encoding_flag_, imm)); | |
| 1315 | #endif | ||
| 1316 | ✗ | } else if (instr.GetID() == I_LOOP) { | |
| 1317 | ✗ | Encode(Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, imm)); | |
| 1318 | } else { | ||
| 1319 | ✗ | JITASM_ASSERT(0); | |
| 1320 | } | ||
| 1321 | ✗ | } | |
| 1322 | |||
| 1323 | ✗ | void EncodeMOV(const Instr& instr) | |
| 1324 | { | ||
| 1325 | #ifndef JITASM64 | ||
| 1326 | const detail::Opd& reg = instr.GetOpd(0); | ||
| 1327 | const detail::Opd& mem = instr.GetOpd(1); | ||
| 1328 | JITASM_ASSERT(reg.IsReg() && mem.IsMem()); | ||
| 1329 | |||
| 1330 | if (reg.GetReg().id == EAX && mem.GetBase().IsInvalid() && mem.GetIndex().IsInvalid()) { | ||
| 1331 | uint32 opcode = 0xA0 | (~instr.opcode_ & 0x2) | (instr.opcode_ & 1); | ||
| 1332 | Encode(Instr(instr.GetID(), opcode, instr.encoding_flag_, Imm32((sint32) mem.GetDisp()))); | ||
| 1333 | } else { | ||
| 1334 | Encode(instr); | ||
| 1335 | } | ||
| 1336 | #else | ||
| 1337 | ✗ | Encode(instr); | |
| 1338 | #endif | ||
| 1339 | ✗ | } | |
| 1340 | |||
| 1341 | ✗ | void EncodeTEST(const Instr& instr) | |
| 1342 | { | ||
| 1343 | ✗ | const detail::Opd& reg = instr.GetOpd(1); | |
| 1344 | ✗ | const detail::Opd& imm = instr.GetOpd(2); | |
| 1345 | ✗ | JITASM_ASSERT(instr.GetOpd(0).IsImm() && reg.IsReg() && imm.IsImm()); | |
| 1346 | |||
| 1347 | ✗ | if (reg.GetReg().id == EAX) { | |
| 1348 | ✗ | uint32 opcode = 0xA8 | (reg.GetSize() == O_SIZE_8 ? 0 : 1); | |
| 1349 | ✗ | Encode(Instr(instr.GetID(), opcode, instr.encoding_flag_, reg, imm)); | |
| 1350 | } else { | ||
| 1351 | ✗ | Encode(instr); | |
| 1352 | } | ||
| 1353 | ✗ | } | |
| 1354 | |||
| 1355 | ✗ | void EncodeXCHG(const Instr& instr) | |
| 1356 | { | ||
| 1357 | ✗ | const detail::Opd& dst = instr.GetOpd(0); | |
| 1358 | ✗ | const detail::Opd& src = instr.GetOpd(1); | |
| 1359 | ✗ | JITASM_ASSERT(dst.IsReg() && src.IsReg()); | |
| 1360 | |||
| 1361 | ✗ | if (dst.GetReg().id == EAX) { | |
| 1362 | ✗ | Encode(Instr(instr.GetID(), 0x90, instr.encoding_flag_, src)); | |
| 1363 | ✗ | } else if (src.GetReg().id == EAX) { | |
| 1364 | ✗ | Encode(Instr(instr.GetID(), 0x90, instr.encoding_flag_, dst)); | |
| 1365 | } else { | ||
| 1366 | ✗ | Encode(instr); | |
| 1367 | } | ||
| 1368 | ✗ | } | |
| 1369 | |||
| 1370 | ✗ | void Assemble(const Instr& instr) | |
| 1371 | { | ||
| 1372 | ✗ | if (instr.encoding_flag_ & E_SPECIAL) { | |
| 1373 | ✗ | switch (instr.GetID()) { | |
| 1374 | ✗ | case I_ADD: EncodeALU(instr, 0x04); break; | |
| 1375 | ✗ | case I_OR: EncodeALU(instr, 0x0C); break; | |
| 1376 | ✗ | case I_ADC: EncodeALU(instr, 0x14); break; | |
| 1377 | ✗ | case I_SBB: EncodeALU(instr, 0x1C); break; | |
| 1378 | ✗ | case I_AND: EncodeALU(instr, 0x24); break; | |
| 1379 | ✗ | case I_SUB: EncodeALU(instr, 0x2C); break; | |
| 1380 | ✗ | case I_XOR: EncodeALU(instr, 0x34); break; | |
| 1381 | ✗ | case I_CMP: EncodeALU(instr, 0x3C); break; | |
| 1382 | ✗ | case I_JMP: EncodeJMP(instr); break; | |
| 1383 | ✗ | case I_JCC: EncodeJMP(instr); break; | |
| 1384 | ✗ | case I_LOOP: EncodeJMP(instr); break; | |
| 1385 | ✗ | case I_MOV: EncodeMOV(instr); break; | |
| 1386 | ✗ | case I_TEST: EncodeTEST(instr); break; | |
| 1387 | ✗ | case I_XCHG: EncodeXCHG(instr); break; | |
| 1388 | ✗ | default: JITASM_ASSERT(0); break; | |
| 1389 | } | ||
| 1390 | } else { | ||
| 1391 | ✗ | Encode(instr); | |
| 1392 | } | ||
| 1393 | ✗ | } | |
| 1394 | |||
| 1395 | static size_t GetInstrCodeSize(const Instr& instr) | ||
| 1396 | { | ||
| 1397 | Backend backend; | ||
| 1398 | backend.Assemble(instr); | ||
| 1399 | return backend.GetSize(); | ||
| 1400 | } | ||
| 1401 | }; | ||
| 1402 | |||
| 1403 | namespace detail | ||
| 1404 | { | ||
| 1405 | /// Counting 1-Bits | ||
| 1406 | ✗ | inline uint32 Count1Bits(uint32 x) | |
| 1407 | { | ||
| 1408 | ✗ | x = x - ((x >> 1) & 0x55555555); | |
| 1409 | ✗ | x = (x & 0x33333333) + ((x >> 2) & 0x33333333); | |
| 1410 | ✗ | x = (x + (x >> 4)) & 0x0F0F0F0F; | |
| 1411 | ✗ | x = x + (x >> 8); | |
| 1412 | ✗ | x = x + (x >> 16); | |
| 1413 | ✗ | return x & 0x0000003F; | |
| 1414 | } | ||
| 1415 | |||
| 1416 | /// The bit position of the first bit 1. | ||
| 1417 | ✗ | inline uint32 bit_scan_forward(uint32 x) | |
| 1418 | { | ||
| 1419 | ✗ | JITASM_ASSERT(x != 0); | |
| 1420 | #if defined(JITASM_GCC) | ||
| 1421 | ✗ | return __builtin_ctz(x); | |
| 1422 | #else | ||
| 1423 | unsigned long index; | ||
| 1424 | _BitScanForward(&index, x); | ||
| 1425 | return index; | ||
| 1426 | #endif | ||
| 1427 | } | ||
| 1428 | |||
| 1429 | /// The bit position of the last bit 1. | ||
| 1430 | ✗ | inline uint32 bit_scan_reverse(uint32 x) | |
| 1431 | { | ||
| 1432 | ✗ | JITASM_ASSERT(x != 0); | |
| 1433 | #if defined(JITASM_GCC) | ||
| 1434 | ✗ | return 31 - __builtin_clz(x); | |
| 1435 | #else | ||
| 1436 | unsigned long index; | ||
| 1437 | _BitScanReverse(&index, x); | ||
| 1438 | return index; | ||
| 1439 | #endif | ||
| 1440 | } | ||
| 1441 | |||
| 1442 | /// Prior iterator | ||
| 1443 | ✗ | template<class It> It prior(const It &it) { | |
| 1444 | ✗ | It i = it; | |
| 1445 | ✗ | return --i; | |
| 1446 | } | ||
| 1447 | |||
| 1448 | /// Next iterator | ||
| 1449 | ✗ | template<class It> It next(const It &it) { | |
| 1450 | ✗ | It i = it; | |
| 1451 | ✗ | return ++i; | |
| 1452 | } | ||
| 1453 | |||
| 1454 | /// Iterator range | ||
| 1455 | template<class T, class It = typename T::iterator> struct Range : std::pair<It, It> { | ||
| 1456 | typedef It Iterator; | ||
| 1457 | ✗ | Range() : std::pair<It, It>() {} | |
| 1458 | Range(const It& f, const It& s) : std::pair<It, It>(f, s) {} | ||
| 1459 | ✗ | Range(T& container) : std::pair<It, It>(container.begin(), container.end()) {} | |
| 1460 | ✗ | bool empty() const {return this->first == this->second;} | |
| 1461 | ✗ | size_t size() const {return std::distance(this->first, this->second);} | |
| 1462 | }; | ||
| 1463 | |||
| 1464 | /// Const iterator range | ||
| 1465 | template<class T> struct ConstRange : Range<T, typename T::const_iterator> { | ||
| 1466 | ✗ | ConstRange() : Range<T, typename T::const_iterator>() {} | |
| 1467 | ConstRange(const typename T::const_iterator& f, const typename T::const_iterator& s) : Range<T, typename T::const_iterator>(f, s) {} | ||
| 1468 | ConstRange(const T& container) : Range<T, typename T::const_iterator>(container.begin(), container.end()) {} | ||
| 1469 | }; | ||
| 1470 | |||
| 1471 | inline void append_num(std::string& str, size_t num) | ||
| 1472 | { | ||
| 1473 | if (num >= 10) | ||
| 1474 | append_num(str, num / 10); | ||
| 1475 | str.append(1, static_cast<char>('0' + num % 10)); | ||
| 1476 | } | ||
| 1477 | |||
| 1478 | #if defined(JITASM_DEBUG_DUMP) && defined(JITASM_WIN) | ||
| 1479 | /// Debug trace | ||
| 1480 | inline void Trace(const char *format, ...) | ||
| 1481 | { | ||
| 1482 | char szBuf[256]; | ||
| 1483 | va_list args; | ||
| 1484 | va_start(args, format); | ||
| 1485 | #if _MSC_VER >= 1400 // VC8 or later | ||
| 1486 | _vsnprintf_s(szBuf, sizeof(szBuf) / sizeof(char), format, args); | ||
| 1487 | #else | ||
| 1488 | vsnprintf(szBuf, sizeof(szBuf) / sizeof(char), format, args); | ||
| 1489 | #endif | ||
| 1490 | va_end(args); | ||
| 1491 | ::OutputDebugStringA(szBuf); | ||
| 1492 | } | ||
| 1493 | #endif | ||
| 1494 | |||
| 1495 | /// Executable code buffer | ||
| 1496 | class CodeBuffer | ||
| 1497 | { | ||
| 1498 | void* pbuff_; | ||
| 1499 | size_t codesize_; | ||
| 1500 | size_t buffsize_; | ||
| 1501 | |||
| 1502 | public: | ||
| 1503 | ✗ | CodeBuffer() : pbuff_(NULL), codesize_(0), buffsize_(0) {} | |
| 1504 | ✗ | ~CodeBuffer() {Reset(0);} | |
| 1505 | |||
| 1506 | ✗ | void* GetPointer() const {return pbuff_;} | |
| 1507 | ✗ | size_t GetCodeSize() const {return codesize_;} | |
| 1508 | ✗ | size_t GetBufferSize() const {return buffsize_;} | |
| 1509 | |||
| 1510 | ✗ | bool Reset(size_t codesize) | |
| 1511 | { | ||
| 1512 | ✗ | if (pbuff_) { | |
| 1513 | #if defined(JITASM_WIN) | ||
| 1514 | ::VirtualFree(pbuff_, 0, MEM_RELEASE); | ||
| 1515 | #else | ||
| 1516 | ✗ | munmap(pbuff_, buffsize_); | |
| 1517 | #endif | ||
| 1518 | ✗ | pbuff_ = NULL; | |
| 1519 | ✗ | codesize_ = 0; | |
| 1520 | ✗ | buffsize_ = 0; | |
| 1521 | } | ||
| 1522 | ✗ | if (codesize) { | |
| 1523 | #if defined(JITASM_WIN) | ||
| 1524 | void* pbuff = ::VirtualAlloc(NULL, codesize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); | ||
| 1525 | if (!pbuff) { | ||
| 1526 | JITASM_ASSERT(0); | ||
| 1527 | return false; | ||
| 1528 | } | ||
| 1529 | MEMORY_BASIC_INFORMATION info; | ||
| 1530 | ::VirtualQuery(pbuff, &info, sizeof(info)); | ||
| 1531 | buffsize_ = info.RegionSize; | ||
| 1532 | #else | ||
| 1533 | ✗ | int pagesize = getpagesize(); | |
| 1534 | ✗ | size_t buffsize = (codesize + pagesize - 1) / pagesize * pagesize; | |
| 1535 | ✗ | void* pbuff = mmap(NULL, buffsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); | |
| 1536 | ✗ | if (!pbuff) { | |
| 1537 | ✗ | JITASM_ASSERT(0); | |
| 1538 | return false; | ||
| 1539 | } | ||
| 1540 | ✗ | buffsize_ = buffsize; | |
| 1541 | #endif | ||
| 1542 | |||
| 1543 | ✗ | pbuff_ = pbuff; | |
| 1544 | ✗ | codesize_ = codesize; | |
| 1545 | } | ||
| 1546 | ✗ | return true; | |
| 1547 | } | ||
| 1548 | }; | ||
| 1549 | |||
| 1550 | /// Stack manager | ||
| 1551 | /** | ||
| 1552 | * <b>Stack layout</b> | ||
| 1553 | * \verbatim | ||
| 1554 | * +-----------------------+ | ||
| 1555 | * | Caller return address | | ||
| 1556 | * +=======================+======== | ||
| 1557 | * | ebp (rbp) | | ||
| 1558 | * +-----------------------+ <-- ebp (rbp) | ||
| 1559 | * | Saved gp registers | | ||
| 1560 | * +-----------------------+ | ||
| 1561 | * | Padding for alignment | | ||
| 1562 | * +-----------------------+ <-- Stack base | ||
| 1563 | * | Spill slots and | | ||
| 1564 | * | local variable | | ||
| 1565 | * +-----------------------+ <-- esp (rsp) | ||
| 1566 | * \endverbatim | ||
| 1567 | */ | ||
| 1568 | class StackManager | ||
| 1569 | { | ||
| 1570 | private: | ||
| 1571 | Addr stack_base_; | ||
| 1572 | uint32 stack_size_; | ||
| 1573 | |||
| 1574 | public: | ||
| 1575 | ✗ | StackManager() : stack_base_(RegID::CreatePhysicalRegID(R_TYPE_GP, EBX), 0), stack_size_(0) {} | |
| 1576 | |||
| 1577 | /// Get allocated stack size | ||
| 1578 | ✗ | uint32 GetSize() const {return (stack_size_ + 15) / 16 * 16; /* 16 bytes aligned*/} | |
| 1579 | |||
| 1580 | /// Get stack base | ||
| 1581 | Addr GetStackBase() const {return stack_base_;} | ||
| 1582 | |||
| 1583 | /// Set stack base | ||
| 1584 | void SetStackBase(const Addr& stack_base) {stack_base_ = stack_base;} | ||
| 1585 | |||
| 1586 | /// Allocate stack | ||
| 1587 | ✗ | Addr Alloc(uint32 size, uint32 alignment) | |
| 1588 | { | ||
| 1589 | ✗ | stack_size_ = (stack_size_ + alignment - 1) / alignment * alignment; | |
| 1590 | ✗ | stack_size_ += size; | |
| 1591 | ✗ | return stack_base_ - stack_size_; | |
| 1592 | } | ||
| 1593 | }; | ||
| 1594 | |||
| 1595 | /// Spin lock | ||
| 1596 | class SpinLock | ||
| 1597 | { | ||
| 1598 | long lock_; | ||
| 1599 | public: | ||
| 1600 | ✗ | SpinLock() : lock_(0) {} | |
| 1601 | ✗ | void Lock() {while (interlocked_exchange(&lock_, 1));} | |
| 1602 | ✗ | void Unlock() {interlocked_exchange(&lock_, 0);} | |
| 1603 | }; | ||
| 1604 | |||
| 1605 | template<class Ty> | ||
| 1606 | class ScopedLock | ||
| 1607 | { | ||
| 1608 | Ty& lock_; | ||
| 1609 | ScopedLock<Ty>& operator=(const ScopedLock<Ty>&); | ||
| 1610 | public: | ||
| 1611 | ✗ | ScopedLock(Ty& lock) : lock_(lock) {lock.Lock();} | |
| 1612 | ✗ | ~ScopedLock() {lock_.Unlock();} | |
| 1613 | }; | ||
| 1614 | } // namespace detail | ||
| 1615 | |||
| 1616 | // compiler prototype declaration | ||
| 1617 | struct Frontend; | ||
| 1618 | namespace compiler { | ||
| 1619 | void Compile(Frontend& f); | ||
| 1620 | } | ||
| 1621 | |||
| 1622 | /// jitasm frontend | ||
| 1623 | struct Frontend | ||
| 1624 | { | ||
| 1625 | typedef jitasm::Addr Addr; | ||
| 1626 | typedef jitasm::Reg Reg; | ||
| 1627 | typedef jitasm::Reg8 Reg8; | ||
| 1628 | typedef jitasm::Reg16 Reg16; | ||
| 1629 | typedef jitasm::Reg32 Reg32; | ||
| 1630 | #ifdef JITASM64 | ||
| 1631 | typedef jitasm::Reg64 Reg64; | ||
| 1632 | #endif | ||
| 1633 | typedef jitasm::MmxReg MmxReg; | ||
| 1634 | typedef jitasm::XmmReg XmmReg; | ||
| 1635 | typedef jitasm::YmmReg YmmReg; | ||
| 1636 | |||
| 1637 | static Reg8 al, cl, dl, bl, ah, ch, dh, bh; | ||
| 1638 | static Reg16 ax, cx, dx, bx, sp, bp, si, di; | ||
| 1639 | static Reg32 eax, ecx, edx, ebx, esp, ebp, esi, edi; | ||
| 1640 | static FpuReg_st0 st0; | ||
| 1641 | static FpuReg st1, st2, st3, st4, st5, st6, st7; | ||
| 1642 | static MmxReg mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7; | ||
| 1643 | static XmmReg xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; | ||
| 1644 | static YmmReg ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7; | ||
| 1645 | #ifdef JITASM64 | ||
| 1646 | static Reg8 r8b, r9b, r10b, r11b, r12b, r13b, r14b, r15b; | ||
| 1647 | static Reg16 r8w, r9w, r10w, r11w, r12w, r13w, r14w, r15w; | ||
| 1648 | static Reg32 r8d, r9d, r10d, r11d, r12d, r13d, r14d, r15d; | ||
| 1649 | static Reg64 rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15; | ||
| 1650 | static XmmReg xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15; | ||
| 1651 | static YmmReg ymm8, ymm9, ymm10, ymm11, ymm12, ymm13, ymm14, ymm15; | ||
| 1652 | #endif | ||
| 1653 | |||
| 1654 | AddressingPtr<Opd8> byte_ptr; | ||
| 1655 | AddressingPtr<Opd16> word_ptr; | ||
| 1656 | AddressingPtr<Opd32> dword_ptr; | ||
| 1657 | AddressingPtr<Opd64> qword_ptr; | ||
| 1658 | AddressingPtr<Opd64> mmword_ptr; | ||
| 1659 | AddressingPtr<Opd128> xmmword_ptr; | ||
| 1660 | AddressingPtr<Opd256> ymmword_ptr; | ||
| 1661 | AddressingPtr<Opd32> real4_ptr; | ||
| 1662 | AddressingPtr<Opd64> real8_ptr; | ||
| 1663 | AddressingPtr<Opd80> real10_ptr; | ||
| 1664 | AddressingPtr<Opd16> m2byte_ptr; | ||
| 1665 | AddressingPtr<Opd224> m28byte_ptr; | ||
| 1666 | AddressingPtr<Opd864> m108byte_ptr; | ||
| 1667 | AddressingPtr<Opd4096> m512byte_ptr; | ||
| 1668 | |||
| 1669 | static Reg zax, zcx, zdx, zbx, zsp, zbp, zsi, zdi; | ||
| 1670 | #ifdef JITASM64 | ||
| 1671 | AddressingPtr<Opd64> ptr; | ||
| 1672 | #else | ||
| 1673 | AddressingPtr<Opd32> ptr; | ||
| 1674 | #endif | ||
| 1675 | |||
| 1676 | typedef std::vector<Instr> InstrList; | ||
| 1677 | InstrList instrs_; | ||
| 1678 | bool assembled_; | ||
| 1679 | bool avx_epilog_; // PF AVS+: avoid AVX transition penalties | ||
| 1680 | detail::CodeBuffer codebuff_; | ||
| 1681 | detail::SpinLock codelock_; | ||
| 1682 | detail::StackManager stack_manager_; | ||
| 1683 | |||
| 1684 | struct Label | ||
| 1685 | { | ||
| 1686 | std::string name; | ||
| 1687 | size_t instr_number; | ||
| 1688 | ✗ | explicit Label(const std::string& name_) : name(name_), instr_number(0) {} | |
| 1689 | }; | ||
| 1690 | typedef std::deque<Label> LabelList; | ||
| 1691 | LabelList labels_; | ||
| 1692 | |||
| 1693 | |||
| 1694 | ✗ | Frontend() : assembled_(false) {} | |
| 1695 | ✗ | virtual ~Frontend() {} | |
| 1696 | |||
| 1697 | virtual void InternalMain() = 0; | ||
| 1698 | |||
| 1699 | /// Declare variable of the function argument on register | ||
| 1700 | ✗ | void DeclareRegArg(const detail::Opd& var, const detail::Opd& arg, const detail::Opd& spill_slot = detail::Opd()) | |
| 1701 | { | ||
| 1702 | ✗ | JITASM_ASSERT(var.IsReg() && arg.IsReg()); | |
| 1703 | // Insert special instruction after Prolog | ||
| 1704 | ✗ | InstrList::iterator it = instrs_.begin(); | |
| 1705 | ✗ | if (!instrs_.empty() && instrs_[0].GetID() == I_COMPILER_PROLOG) ++it; | |
| 1706 | // The arg is passed as register constraint of the var. | ||
| 1707 | ✗ | instrs_.insert(it, Instr(I_COMPILER_DECLARE_REG_ARG, 0, E_SPECIAL, Dummy(W(var), arg), spill_slot)); | |
| 1708 | ✗ | } | |
| 1709 | |||
| 1710 | /// Declare variable of the function argument on stack | ||
| 1711 | ✗ | void DeclareStackArg(const detail::Opd& var, const detail::Opd& arg) | |
| 1712 | { | ||
| 1713 | ✗ | JITASM_ASSERT(var.IsReg() && arg.IsMem()); | |
| 1714 | // Insert special instruction after Prolog | ||
| 1715 | ✗ | InstrList::iterator it = instrs_.begin(); | |
| 1716 | ✗ | if (!instrs_.empty() && instrs_[0].GetID() == I_COMPILER_PROLOG) ++it; | |
| 1717 | ✗ | instrs_.insert(it, Instr(I_COMPILER_DECLARE_STACK_ARG, 0, E_SPECIAL, W(var), R(arg))); | |
| 1718 | ✗ | } | |
| 1719 | |||
| 1720 | /// Declare variable of the function result on register | ||
| 1721 | void DeclareResultReg(const detail::Opd& var) | ||
| 1722 | { | ||
| 1723 | JITASM_ASSERT(var.IsReg()); | ||
| 1724 | // The result register is passed as register constraint of the var. | ||
| 1725 | if (var.IsGpReg()) { | ||
| 1726 | AppendInstr(I_COMPILER_DECLARE_RESULT_REG, 0, E_SPECIAL, Dummy(R(var), zax)); | ||
| 1727 | } else if (var.IsMmxReg()) { | ||
| 1728 | AppendInstr(I_COMPILER_DECLARE_RESULT_REG, 0, E_SPECIAL, Dummy(R(var), mm0)); | ||
| 1729 | } else if (var.IsXmmReg()) { | ||
| 1730 | AppendInstr(I_COMPILER_DECLARE_RESULT_REG, 0, E_SPECIAL, Dummy(R(var), xmm0)); | ||
| 1731 | } | ||
| 1732 | } | ||
| 1733 | |||
| 1734 | /// Function prolog | ||
| 1735 | ✗ | void Prolog() | |
| 1736 | { | ||
| 1737 | ✗ | AppendInstr(I_COMPILER_PROLOG, 0, E_SPECIAL); | |
| 1738 | ✗ | } | |
| 1739 | |||
| 1740 | /// Function epilog | ||
| 1741 | ✗ | void Epilog() | |
| 1742 | { | ||
| 1743 | ✗ | AppendInstr(I_COMPILER_EPILOG, 0, E_SPECIAL); | |
| 1744 | ✗ | } | |
| 1745 | |||
| 1746 | ✗ | static bool IsJump(InstrID id) | |
| 1747 | { | ||
| 1748 | ✗ | return id == I_JMP || id == I_JCC || id == I_LOOP; | |
| 1749 | } | ||
| 1750 | |||
| 1751 | ✗ | size_t GetJumpTo(const Instr& instr) const | |
| 1752 | { | ||
| 1753 | ✗ | size_t label_id = (size_t) instr.GetOpd(0).GetImm(); | |
| 1754 | ✗ | JITASM_ASSERT(labels_[label_id].instr_number != (size_t)-1); // invalid label | |
| 1755 | ✗ | return labels_[label_id].instr_number; | |
| 1756 | } | ||
| 1757 | |||
| 1758 | // TODO: Return an error when there is no destination. | ||
| 1759 | ✗ | void ResolveJump() | |
| 1760 | { | ||
| 1761 | // Replace label indexes with instruncion numbers. | ||
| 1762 | ✗ | for (InstrList::iterator it = instrs_.begin(); it != instrs_.end(); ++it) { | |
| 1763 | ✗ | Instr& instr = *it; | |
| 1764 | ✗ | if (IsJump(instr.GetID())) { | |
| 1765 | ✗ | instr = Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, Imm8(0x7F), Imm64(GetJumpTo(instr))); // Opd(0) = max value in sint8, Opd(1) = instruction number | |
| 1766 | } | ||
| 1767 | } | ||
| 1768 | |||
| 1769 | // Resolve operand sizes. | ||
| 1770 | ✗ | std::vector<int> offsets; | |
| 1771 | ✗ | offsets.reserve(instrs_.size() + 1); | |
| 1772 | bool retry; | ||
| 1773 | ✗ | do { | |
| 1774 | ✗ | offsets.clear(); | |
| 1775 | ✗ | offsets.push_back(0); | |
| 1776 | ✗ | Backend pre; | |
| 1777 | ✗ | for (InstrList::const_iterator it = instrs_.begin(); it != instrs_.end(); ++it) { | |
| 1778 | ✗ | pre.Assemble(*it); | |
| 1779 | ✗ | offsets.push_back((int) pre.GetSize()); | |
| 1780 | } | ||
| 1781 | |||
| 1782 | ✗ | retry = false; | |
| 1783 | ✗ | for (size_t i = 0; i < instrs_.size(); i++) { | |
| 1784 | ✗ | Instr& instr = instrs_[i]; | |
| 1785 | ✗ | if (IsJump(instr.GetID())) { | |
| 1786 | ✗ | size_t d = (size_t) instr.GetOpd(1).GetImm(); | |
| 1787 | ✗ | int rel = (int) offsets[d] - offsets[i + 1]; | |
| 1788 | ✗ | OpdSize size = instr.GetOpd(0).GetSize(); | |
| 1789 | ✗ | if (size == O_SIZE_8) { | |
| 1790 | ✗ | if (!detail::IsInt8(rel)) { | |
| 1791 | // jrcxz, jcxz, jecxz, loop, loope, loopne are only for short jump | ||
| 1792 | ✗ | uint32 tttn = instr.opcode_; | |
| 1793 | ✗ | if (instr.GetID() == I_JCC && (tttn == JCC_CXZ || tttn == JCC_ECXZ || tttn == JCC_RCXZ)) JITASM_ASSERT(0); | |
| 1794 | ✗ | if (instr.GetID() == I_LOOP) JITASM_ASSERT(0); | |
| 1795 | |||
| 1796 | // Retry with immediate 32 | ||
| 1797 | ✗ | instr = Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, Imm32(0x7FFFFFFF), Imm64(instr.GetOpd(1).GetImm())); | |
| 1798 | ✗ | retry = true; | |
| 1799 | } | ||
| 1800 | ✗ | } else if (size == O_SIZE_32) { | |
| 1801 | ✗ | JITASM_ASSERT(detail::IsInt32(rel)); // There is no jump instruction larger than immediate 32. | |
| 1802 | } | ||
| 1803 | } | ||
| 1804 | } | ||
| 1805 | } while (retry); | ||
| 1806 | |||
| 1807 | // Resolve immediates | ||
| 1808 | ✗ | for (size_t i = 0; i < instrs_.size(); i++) { | |
| 1809 | ✗ | Instr& instr = instrs_[i]; | |
| 1810 | ✗ | if (IsJump(instr.GetID())) { | |
| 1811 | ✗ | size_t d = (size_t) instr.GetOpd(1).GetImm(); | |
| 1812 | ✗ | int rel = (int) offsets[d] - offsets[i + 1]; | |
| 1813 | ✗ | OpdSize size = instr.GetOpd(0).GetSize(); | |
| 1814 | ✗ | if (size == O_SIZE_8) { | |
| 1815 | ✗ | JITASM_ASSERT(detail::IsInt8(rel)); | |
| 1816 | ✗ | instr = Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, Imm8((uint8) rel)); | |
| 1817 | ✗ | } else if (size == O_SIZE_32) { | |
| 1818 | ✗ | JITASM_ASSERT(detail::IsInt32(rel)); | |
| 1819 | ✗ | instr = Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, Imm32((uint32) rel)); | |
| 1820 | } | ||
| 1821 | } | ||
| 1822 | } | ||
| 1823 | ✗ | } | |
| 1824 | |||
| 1825 | /// Assemble | ||
| 1826 | ✗ | void Assemble() | |
| 1827 | { | ||
| 1828 | ✗ | detail::ScopedLock<detail::SpinLock> lock(codelock_); | |
| 1829 | ✗ | if (assembled_) return; | |
| 1830 | |||
| 1831 | ✗ | instrs_.clear(); | |
| 1832 | ✗ | labels_.clear(); | |
| 1833 | ✗ | instrs_.reserve(128); | |
| 1834 | |||
| 1835 | ✗ | InternalMain(); | |
| 1836 | ✗ | compiler::Compile(*this); | |
| 1837 | |||
| 1838 | // Resolve jump instructions | ||
| 1839 | ✗ | if (!labels_.empty()) { | |
| 1840 | ✗ | ResolveJump(); | |
| 1841 | } | ||
| 1842 | |||
| 1843 | // Count total size of machine code | ||
| 1844 | ✗ | Backend pre; | |
| 1845 | ✗ | for (InstrList::const_iterator it = instrs_.begin(); it != instrs_.end(); ++it) { | |
| 1846 | ✗ | pre.Assemble(*it); | |
| 1847 | } | ||
| 1848 | ✗ | size_t codesize = pre.GetSize(); | |
| 1849 | |||
| 1850 | // Write machine code to the buffer | ||
| 1851 | ✗ | codebuff_.Reset(codesize); | |
| 1852 | ✗ | Backend backend(codebuff_.GetPointer(), codebuff_.GetBufferSize()); | |
| 1853 | ✗ | for (InstrList::const_iterator it = instrs_.begin(); it != instrs_.end(); ++it) { | |
| 1854 | ✗ | backend.Assemble(*it); | |
| 1855 | } | ||
| 1856 | |||
| 1857 | ✗ | InstrList().swap(instrs_); | |
| 1858 | ✗ | LabelList().swap(labels_); | |
| 1859 | ✗ | assembled_ = true; | |
| 1860 | ✗ | } | |
| 1861 | |||
| 1862 | /// Get assembled code | ||
| 1863 | ✗ | void *GetCode(bool force_avx_epilog = false) | |
| 1864 | { | ||
| 1865 | ✗ | avx_epilog_ = force_avx_epilog; // PF AVS+: anti penalty | |
| 1866 | ✗ | if (!assembled_) { | |
| 1867 | ✗ | Assemble(); | |
| 1868 | } | ||
| 1869 | ✗ | return codebuff_.GetPointer(); | |
| 1870 | } | ||
| 1871 | |||
| 1872 | /// Get total size of machine code | ||
| 1873 | ✗ | size_t GetCodeSize() const | |
| 1874 | { | ||
| 1875 | ✗ | return codebuff_.GetCodeSize(); | |
| 1876 | } | ||
| 1877 | |||
| 1878 | ✗ | void AppendInstr(InstrID id, uint32 opcode, uint32 encoding_flag, const detail::Opd& opd1 = detail::Opd(), const detail::Opd& opd2 = detail::Opd(), const detail::Opd& opd3 = detail::Opd(), const detail::Opd& opd4 = detail::Opd(), const detail::Opd& opd5 = detail::Opd(), const detail::Opd& opd6 = detail::Opd()) | |
| 1879 | { | ||
| 1880 | ✗ | instrs_.push_back(Instr(id, opcode, encoding_flag, opd1, opd2, opd3, opd4, opd5, opd6)); | |
| 1881 | ✗ | } | |
| 1882 | |||
| 1883 | ✗ | void AppendJmp(size_t label_id) | |
| 1884 | { | ||
| 1885 | ✗ | AppendInstr(I_JMP, 0, E_SPECIAL, Imm64(label_id)); | |
| 1886 | ✗ | } | |
| 1887 | |||
| 1888 | ✗ | void AppendJcc(JumpCondition jcc, size_t label_id) | |
| 1889 | { | ||
| 1890 | ✗ | AppendInstr(I_JCC, jcc, E_SPECIAL, Imm64(label_id)); | |
| 1891 | ✗ | } | |
| 1892 | |||
| 1893 | /// Change label id of jump instruction | ||
| 1894 | ✗ | static void ChangeLabelID(Instr& instr, size_t label_id) | |
| 1895 | { | ||
| 1896 | ✗ | JITASM_ASSERT(IsJump(instr.id_) && instr.GetOpd(0).IsImm()); | |
| 1897 | ✗ | instr.GetOpd(0).imm_ = label_id; | |
| 1898 | ✗ | } | |
| 1899 | |||
| 1900 | ✗ | size_t NewLabelID(const std::string& label_name) | |
| 1901 | { | ||
| 1902 | ✗ | labels_.push_back(Label(label_name)); | |
| 1903 | ✗ | return labels_.size() - 1; | |
| 1904 | } | ||
| 1905 | |||
| 1906 | ✗ | size_t GetLabelID(const std::string& label_name) | |
| 1907 | { | ||
| 1908 | ✗ | for (size_t i = 0; i < labels_.size(); i++) { | |
| 1909 | ✗ | if (labels_[i].name == label_name) { | |
| 1910 | ✗ | return i; | |
| 1911 | } | ||
| 1912 | } | ||
| 1913 | ✗ | return NewLabelID(label_name); | |
| 1914 | } | ||
| 1915 | |||
| 1916 | ✗ | void L(size_t label_id) | |
| 1917 | { | ||
| 1918 | ✗ | labels_[label_id].instr_number = instrs_.size(); // Label current instruction | |
| 1919 | ✗ | } | |
| 1920 | |||
| 1921 | /// Label | ||
| 1922 | ✗ | void L(const std::string& label_name) | |
| 1923 | { | ||
| 1924 | ✗ | JITASM_ASSERT(!label_name.empty()); | |
| 1925 | ✗ | L(GetLabelID(label_name)); | |
| 1926 | ✗ | } | |
| 1927 | |||
| 1928 | // General-Purpose Instructions | ||
| 1929 | void adc(const Reg8& dst, const Imm8& imm) {AppendInstr(I_ADC, 0x80, E_SPECIAL, Imm8(2), RW(dst), imm);} | ||
| 1930 | void adc(const Mem8& dst, const Imm8& imm) {AppendInstr(I_ADC, 0x80, 0, Imm8(2), RW(dst), imm);} | ||
| 1931 | void adc(const Reg16& dst, const Imm16& imm) {AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(2), RW(dst), detail::ImmXor8(imm));} | ||
| 1932 | void adc(const Mem16& dst, const Imm16& imm) {AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), detail::ImmXor8(imm));} | ||
| 1933 | void adc(const Reg32& dst, const Imm32& imm) {AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(2), RW(dst), detail::ImmXor8(imm));} | ||
| 1934 | void adc(const Mem32& dst, const Imm32& imm) {AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(2), RW(dst), detail::ImmXor8(imm));} | ||
| 1935 | void adc(const Reg8& dst, const Reg8& src) {AppendInstr(I_ADC, 0x12, 0, RW(dst), R(src));} | ||
| 1936 | void adc(const Mem8& dst, const Reg8& src) {AppendInstr(I_ADC, 0x10, 0, R(src), RW(dst));} | ||
| 1937 | void adc(const Reg8& dst, const Mem8& src) {AppendInstr(I_ADC, 0x12, 0, RW(dst), R(src));} | ||
| 1938 | void adc(const Reg16& dst, const Reg16& src) {AppendInstr(I_ADC, 0x13, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 1939 | void adc(const Mem16& dst, const Reg16& src) {AppendInstr(I_ADC, 0x11, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));} | ||
| 1940 | void adc(const Reg16& dst, const Mem16& src) {AppendInstr(I_ADC, 0x13, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 1941 | void adc(const Reg32& dst, const Reg32& src) {AppendInstr(I_ADC, 0x13, 0, RW(dst), R(src));} | ||
| 1942 | void adc(const Mem32& dst, const Reg32& src) {AppendInstr(I_ADC, 0x11, 0, R(src), RW(dst));} | ||
| 1943 | void adc(const Reg32& dst, const Mem32& src) {AppendInstr(I_ADC, 0x13, 0, RW(dst), R(src));} | ||
| 1944 | #ifdef JITASM64 | ||
| 1945 | void adc(const Reg64& dst, const Imm32& imm) {AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(2), RW(dst), detail::ImmXor8(imm));} | ||
| 1946 | void adc(const Mem64& dst, const Imm32& imm) {AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(2), RW(dst), detail::ImmXor8(imm));} | ||
| 1947 | void adc(const Reg64& dst, const Reg64& src) {AppendInstr(I_ADC, 0x13, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 1948 | void adc(const Mem64& dst, const Reg64& src) {AppendInstr(I_ADC, 0x11, E_REXW_PREFIX, R(src), RW(dst));} | ||
| 1949 | void adc(const Reg64& dst, const Mem64& src) {AppendInstr(I_ADC, 0x13, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 1950 | #endif | ||
| 1951 | void add(const Reg8& dst, const Imm8& imm) {AppendInstr(I_ADD, 0x80, E_SPECIAL, Imm8(0), RW(dst), imm);} | ||
| 1952 | void add(const Mem8& dst, const Imm8& imm) {AppendInstr(I_ADD, 0x80, 0, Imm8(0), RW(dst), imm);} | ||
| 1953 | void add(const Reg16& dst, const Imm16& imm) {AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(0), RW(dst), detail::ImmXor8(imm));} | ||
| 1954 | void add(const Mem16& dst, const Imm16& imm) {AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), detail::ImmXor8(imm));} | ||
| 1955 | void add(const Reg32& dst, const Imm32& imm) {AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(0), RW(dst), detail::ImmXor8(imm));} | ||
| 1956 | void add(const Mem32& dst, const Imm32& imm) {AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(0), RW(dst), detail::ImmXor8(imm));} | ||
| 1957 | void add(const Reg8& dst, const Reg8& src) {AppendInstr(I_ADD, 0x02, 0, RW(dst), R(src));} | ||
| 1958 | void add(const Mem8& dst, const Reg8& src) {AppendInstr(I_ADD, 0x00, 0, R(src), RW(dst));} | ||
| 1959 | void add(const Reg8& dst, const Mem8& src) {AppendInstr(I_ADD, 0x02, 0, RW(dst), R(src));} | ||
| 1960 | void add(const Reg16& dst, const Reg16& src) {AppendInstr(I_ADD, 0x03, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 1961 | void add(const Mem16& dst, const Reg16& src) {AppendInstr(I_ADD, 0x01, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));} | ||
| 1962 | void add(const Reg16& dst, const Mem16& src) {AppendInstr(I_ADD, 0x03, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 1963 | void add(const Reg32& dst, const Reg32& src) {AppendInstr(I_ADD, 0x03, 0, RW(dst), R(src));} | ||
| 1964 | void add(const Mem32& dst, const Reg32& src) {AppendInstr(I_ADD, 0x01, 0, R(src), RW(dst));} | ||
| 1965 | void add(const Reg32& dst, const Mem32& src) {AppendInstr(I_ADD, 0x03, 0, RW(dst), R(src));} | ||
| 1966 | #ifdef JITASM64 | ||
| 1967 | ✗ | void add(const Reg64& dst, const Imm32& imm) {AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(0), RW(dst), detail::ImmXor8(imm));} | |
| 1968 | void add(const Mem64& dst, const Imm32& imm) {AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(0), RW(dst), detail::ImmXor8(imm));} | ||
| 1969 | ✗ | void add(const Reg64& dst, const Reg64& src) {AppendInstr(I_ADD, 0x03, E_REXW_PREFIX, RW(dst), R(src));} | |
| 1970 | void add(const Mem64& dst, const Reg64& src) {AppendInstr(I_ADD, 0x01, E_REXW_PREFIX, R(src), RW(dst));} | ||
| 1971 | void add(const Reg64& dst, const Mem64& src) {AppendInstr(I_ADD, 0x03, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 1972 | #endif | ||
| 1973 | void and_(const Reg8& dst, const Imm8& imm) {AppendInstr(I_AND, 0x80, E_SPECIAL, Imm8(4), RW(dst), imm);} | ||
| 1974 | void and_(const Mem8& dst, const Imm8& imm) {AppendInstr(I_AND, 0x80, 0, Imm8(4), RW(dst), imm);} | ||
| 1975 | void and_(const Reg16& dst, const Imm16& imm) {AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(4), RW(dst), detail::ImmXor8(imm));} | ||
| 1976 | void and_(const Mem16& dst, const Imm16& imm) {AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), detail::ImmXor8(imm));} | ||
| 1977 | void and_(const Reg32& dst, const Imm32& imm) {AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(4), RW(dst), detail::ImmXor8(imm));} | ||
| 1978 | void and_(const Mem32& dst, const Imm32& imm) {AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(4), RW(dst), detail::ImmXor8(imm));} | ||
| 1979 | void and_(const Reg8& dst, const Reg8& src) {AppendInstr(I_AND, 0x22, 0, RW(dst), R(src));} | ||
| 1980 | void and_(const Mem8& dst, const Reg8& src) {AppendInstr(I_AND, 0x20, 0, R(src), RW(dst));} | ||
| 1981 | void and_(const Reg8& dst, const Mem8& src) {AppendInstr(I_AND, 0x22, 0, RW(dst), R(src));} | ||
| 1982 | void and_(const Reg16& dst, const Reg16& src) {AppendInstr(I_AND, 0x23, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 1983 | void and_(const Mem16& dst, const Reg16& src) {AppendInstr(I_AND, 0x21, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));} | ||
| 1984 | void and_(const Reg16& dst, const Mem16& src) {AppendInstr(I_AND, 0x23, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 1985 | void and_(const Reg32& dst, const Reg32& src) {AppendInstr(I_AND, 0x23, 0, RW(dst), R(src));} | ||
| 1986 | void and_(const Mem32& dst, const Reg32& src) {AppendInstr(I_AND, 0x21, 0, R(src), RW(dst));} | ||
| 1987 | void and_(const Reg32& dst, const Mem32& src) {AppendInstr(I_AND, 0x23, 0, RW(dst), R(src));} | ||
| 1988 | #ifdef JITASM64 | ||
| 1989 | // and with Imm32 is sign extended | ||
| 1990 | ✗ | void and_(const Reg64& dst, const Imm32& imm) {AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(4), RW(dst), detail::ImmXor8(imm));} | |
| 1991 | void and_(const Mem64& dst, const Imm32& imm) {AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(4), RW(dst), detail::ImmXor8(imm));} | ||
| 1992 | void and_(const Reg64& dst, const Reg64& src) {AppendInstr(I_AND, 0x23, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 1993 | void and_(const Mem64& dst, const Reg64& src) {AppendInstr(I_AND, 0x21, E_REXW_PREFIX, R(src), RW(dst));} | ||
| 1994 | void and_(const Reg64& dst, const Mem64& src) {AppendInstr(I_AND, 0x23, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 1995 | #endif | ||
| 1996 | void bsf(const Reg16& dst, const Reg16& src) {AppendInstr(I_BSF, 0x0FBC, E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 1997 | void bsf(const Reg16& dst, const Mem16& src) {AppendInstr(I_BSF, 0x0FBC, E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 1998 | void bsf(const Reg32& dst, const Reg32& src) {AppendInstr(I_BSF, 0x0FBC, 0, W(dst), R(src));} | ||
| 1999 | void bsf(const Reg32& dst, const Mem32& src) {AppendInstr(I_BSF, 0x0FBC, 0, W(dst), R(src));} | ||
| 2000 | #ifdef JITASM64 | ||
| 2001 | void bsf(const Reg64& dst, const Reg64& src) {AppendInstr(I_BSF, 0x0FBC, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2002 | void bsf(const Reg64& dst, const Mem64& src) {AppendInstr(I_BSF, 0x0FBC, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2003 | #endif | ||
| 2004 | void bsr(const Reg16& dst, const Reg16& src) {AppendInstr(I_BSR, 0x0FBD, E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 2005 | void bsr(const Reg16& dst, const Mem16& src) {AppendInstr(I_BSR, 0x0FBD, E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 2006 | void bsr(const Reg32& dst, const Reg32& src) {AppendInstr(I_BSR, 0x0FBD, 0, W(dst), R(src));} | ||
| 2007 | void bsr(const Reg32& dst, const Mem32& src) {AppendInstr(I_BSR, 0x0FBD, 0, W(dst), R(src));} | ||
| 2008 | #ifdef JITASM64 | ||
| 2009 | void bsr(const Reg64& dst, const Reg64& src) {AppendInstr(I_BSR, 0x0FBD, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2010 | void bsr(const Reg64& dst, const Mem64& src) {AppendInstr(I_BSR, 0x0FBD, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2011 | #endif | ||
| 2012 | void bswap(const Reg32& dst) {AppendInstr(I_BSWAP, 0x0FC8, 0, RW(dst));} | ||
| 2013 | #ifdef JITASM64 | ||
| 2014 | void bswap(const Reg64& dst) {AppendInstr(I_BSWAP, 0x0FC8, E_REXW_PREFIX, RW(dst));} | ||
| 2015 | #endif | ||
| 2016 | void bt(const Reg16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BT, 0x0FA3, E_OPERAND_SIZE_PREFIX, R(bitoffset), R(bitbase));} | ||
| 2017 | void bt(const Mem16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BT, 0x0FA3, E_OPERAND_SIZE_PREFIX, R(bitoffset), R(bitbase));} | ||
| 2018 | void bt(const Reg32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BT, 0x0FA3, 0, R(bitoffset), R(bitbase));} | ||
| 2019 | void bt(const Mem32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BT, 0x0FA3, 0, R(bitoffset), R(bitbase));} | ||
| 2020 | void bt(const Reg16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BT, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(4), R(bitbase), bitoffset);} | ||
| 2021 | void bt(const Mem16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BT, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(4), R(bitbase), bitoffset);} | ||
| 2022 | void bt(const Reg32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BT, 0x0FBA, 0, Imm8(4), R(bitbase), bitoffset);} | ||
| 2023 | void bt(const Mem32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BT, 0x0FBA, 0, Imm8(4), R(bitbase), bitoffset);} | ||
| 2024 | #ifdef JITASM64 | ||
| 2025 | void bt(const Reg64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BT, 0x0FA3, E_REXW_PREFIX, R(bitoffset), R(bitbase));} | ||
| 2026 | void bt(const Mem64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BT, 0x0FA3, E_REXW_PREFIX, R(bitoffset), R(bitbase));} | ||
| 2027 | void bt(const Reg64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BT, 0x0FBA, E_REXW_PREFIX, Imm8(4), R(bitbase), bitoffset);} | ||
| 2028 | void bt(const Mem64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BT, 0x0FBA, E_REXW_PREFIX, Imm8(4), R(bitbase), bitoffset);} | ||
| 2029 | #endif | ||
| 2030 | void btc(const Reg16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BTC, 0x0FBB, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));} | ||
| 2031 | void btc(const Mem16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BTC, 0x0FBB, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));} | ||
| 2032 | void btc(const Reg32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BTC, 0x0FBB, 0, R(bitoffset), RW(bitbase));} | ||
| 2033 | void btc(const Mem32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BTC, 0x0FBB, 0, R(bitoffset), RW(bitbase));} | ||
| 2034 | void btc(const Reg16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTC, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(bitbase), bitoffset);} | ||
| 2035 | void btc(const Mem16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTC, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(bitbase), bitoffset);} | ||
| 2036 | void btc(const Reg32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTC, 0x0FBA, 0, Imm8(7), RW(bitbase), bitoffset);} | ||
| 2037 | void btc(const Mem32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTC, 0x0FBA, 0, Imm8(7), RW(bitbase), bitoffset);} | ||
| 2038 | #ifdef JITASM64 | ||
| 2039 | void btc(const Reg64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BTC, 0x0FBB, E_REXW_PREFIX, R(bitoffset), RW(bitbase));} | ||
| 2040 | void btc(const Mem64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BTC, 0x0FBB, E_REXW_PREFIX, R(bitoffset), RW(bitbase));} | ||
| 2041 | void btc(const Reg64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTC, 0x0FBA, E_REXW_PREFIX, Imm8(7), RW(bitbase), bitoffset);} | ||
| 2042 | void btc(const Mem64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTC, 0x0FBA, E_REXW_PREFIX, Imm8(7), RW(bitbase), bitoffset);} | ||
| 2043 | #endif | ||
| 2044 | void btr(const Reg16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BTR, 0x0FB3, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));} | ||
| 2045 | void btr(const Mem16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BTR, 0x0FB3, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));} | ||
| 2046 | void btr(const Reg32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BTR, 0x0FB3, 0, R(bitoffset), RW(bitbase));} | ||
| 2047 | void btr(const Mem32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BTR, 0x0FB3, 0, R(bitoffset), RW(bitbase));} | ||
| 2048 | void btr(const Reg16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTR, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(6), RW(bitbase), bitoffset);} | ||
| 2049 | void btr(const Mem16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTR, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(6), RW(bitbase), bitoffset);} | ||
| 2050 | void btr(const Reg32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTR, 0x0FBA, 0, Imm8(6), RW(bitbase), bitoffset);} | ||
| 2051 | void btr(const Mem32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTR, 0x0FBA, 0, Imm8(6), RW(bitbase), bitoffset);} | ||
| 2052 | #ifdef JITASM64 | ||
| 2053 | void btr(const Reg64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BTR, 0x0FB3, E_REXW_PREFIX, R(bitoffset), RW(bitbase));} | ||
| 2054 | void btr(const Mem64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BTR, 0x0FB3, E_REXW_PREFIX, R(bitoffset), RW(bitbase));} | ||
| 2055 | void btr(const Reg64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTR, 0x0FBA, E_REXW_PREFIX, Imm8(6), RW(bitbase), bitoffset);} | ||
| 2056 | void btr(const Mem64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTR, 0x0FBA, E_REXW_PREFIX, Imm8(6), RW(bitbase), bitoffset);} | ||
| 2057 | #endif | ||
| 2058 | void bts(const Reg16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BTS, 0x0FAB, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));} | ||
| 2059 | void bts(const Mem16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BTS, 0x0FAB, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));} | ||
| 2060 | void bts(const Reg32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BTS, 0x0FAB, 0, R(bitoffset), RW(bitbase));} | ||
| 2061 | void bts(const Mem32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BTS, 0x0FAB, 0, R(bitoffset), RW(bitbase));} | ||
| 2062 | void bts(const Reg16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTS, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(bitbase), bitoffset);} | ||
| 2063 | void bts(const Mem16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTS, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(bitbase), bitoffset);} | ||
| 2064 | void bts(const Reg32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTS, 0x0FBA, 0, Imm8(5), RW(bitbase), bitoffset);} | ||
| 2065 | void bts(const Mem32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTS, 0x0FBA, 0, Imm8(5), RW(bitbase), bitoffset);} | ||
| 2066 | #ifdef JITASM64 | ||
| 2067 | void bts(const Reg64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BTS, 0x0FAB, E_REXW_PREFIX, R(bitoffset), RW(bitbase));} | ||
| 2068 | void bts(const Mem64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BTS, 0x0FAB, E_REXW_PREFIX, R(bitoffset), RW(bitbase));} | ||
| 2069 | void bts(const Reg64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTS, 0x0FBA, E_REXW_PREFIX, Imm8(5), RW(bitbase), bitoffset);} | ||
| 2070 | void bts(const Mem64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTS, 0x0FBA, E_REXW_PREFIX, Imm8(5), RW(bitbase), bitoffset);} | ||
| 2071 | #endif | ||
| 2072 | #ifndef JITASM64 | ||
| 2073 | void call(const Reg16& dst) {AppendInstr(I_CALL, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(2), R(dst));} | ||
| 2074 | void call(const Reg32& dst) {AppendInstr(I_CALL, 0xFF, 0, Imm8(2), R(dst));} | ||
| 2075 | #else | ||
| 2076 | void call(const Reg64& dst) {AppendInstr(I_CALL, 0xFF, 0, Imm8(2), R(dst));} | ||
| 2077 | #endif | ||
| 2078 | void cbw() {AppendInstr(I_CBW, 0x98, E_OPERAND_SIZE_PREFIX, Dummy(RW(eax)));} | ||
| 2079 | void cwde() {AppendInstr(I_CBW, 0x98, 0, Dummy(RW(eax)));} | ||
| 2080 | #ifdef JITASM64 | ||
| 2081 | void cdqe() {AppendInstr(I_CBW, 0x98, E_REXW_PREFIX, Dummy(RW(eax)));} | ||
| 2082 | #endif | ||
| 2083 | void clc() {AppendInstr(I_CLC, 0xF8, 0);} | ||
| 2084 | void cld() {AppendInstr(I_CLD, 0xFC, 0);} | ||
| 2085 | void cli() {AppendInstr(I_CLI, 0xFA, 0);} | ||
| 2086 | #ifdef JITASM64 | ||
| 2087 | void clts() {AppendInstr(I_CLTS, 0x0F06, 0);} | ||
| 2088 | #endif | ||
| 2089 | void cmc() {AppendInstr(I_CMC, 0xF5, 0);} | ||
| 2090 | void cmova(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F47, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2091 | void cmova(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F47, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2092 | void cmovae(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F43, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2093 | void cmovae(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F43, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2094 | void cmovb(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F42, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2095 | void cmovb(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F42, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2096 | void cmovbe(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F46, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2097 | void cmovbe(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F46, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2098 | void cmovc(const Reg16& dst, const Reg16& src) {cmovb(dst, src);} | ||
| 2099 | void cmovc(const Reg16& dst, const Mem16& src) {cmovb(dst, src);} | ||
| 2100 | void cmove(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F44, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2101 | void cmove(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F44, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2102 | void cmovg(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F4F, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2103 | void cmovg(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F4F, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2104 | void cmovge(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F4D, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2105 | void cmovge(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F4D, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2106 | void cmovl(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F4C, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2107 | void cmovl(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F4C, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2108 | void cmovle(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F4E, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2109 | void cmovle(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F4E, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2110 | void cmovna(const Reg16& dst, const Reg16& src) {cmovbe(dst, src);} | ||
| 2111 | void cmovna(const Reg16& dst, const Mem16& src) {cmovbe(dst, src);} | ||
| 2112 | void cmovnae(const Reg16& dst, const Reg16& src) {cmovb(dst, src);} | ||
| 2113 | void cmovnae(const Reg16& dst, const Mem16& src) {cmovb(dst, src);} | ||
| 2114 | void cmovnb(const Reg16& dst, const Reg16& src) {cmovae(dst, src);} | ||
| 2115 | void cmovnb(const Reg16& dst, const Mem16& src) {cmovae(dst, src);} | ||
| 2116 | void cmovnbe(const Reg16& dst, const Reg16& src) {cmova(dst, src);} | ||
| 2117 | void cmovnbe(const Reg16& dst, const Mem16& src) {cmova(dst, src);} | ||
| 2118 | void cmovnc(const Reg16& dst, const Reg16& src) {cmovae(dst, src);} | ||
| 2119 | void cmovnc(const Reg16& dst, const Mem16& src) {cmovae(dst, src);} | ||
| 2120 | void cmovne(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F45, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2121 | void cmovne(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F45, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2122 | void cmovng(const Reg16& dst, const Reg16& src) {cmovle(dst, src);} | ||
| 2123 | void cmovng(const Reg16& dst, const Mem16& src) {cmovle(dst, src);} | ||
| 2124 | void cmovnge(const Reg16& dst, const Reg16& src) {cmovl(dst, src);} | ||
| 2125 | void cmovnge(const Reg16& dst, const Mem16& src) {cmovl(dst, src);} | ||
| 2126 | void cmovnl(const Reg16& dst, const Reg16& src) {cmovge(dst, src);} | ||
| 2127 | void cmovnl(const Reg16& dst, const Mem16& src) {cmovge(dst, src);} | ||
| 2128 | void cmovnle(const Reg16& dst, const Reg16& src) {cmovg(dst, src);} | ||
| 2129 | void cmovnle(const Reg16& dst, const Mem16& src) {cmovg(dst, src);} | ||
| 2130 | void cmovno(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F41, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2131 | void cmovno(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F41, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2132 | void cmovnp(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F4B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2133 | void cmovnp(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F4B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2134 | void cmovns(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F49, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2135 | void cmovns(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F49, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2136 | void cmovnz(const Reg16& dst, const Reg16& src) {cmovne(dst, src);} | ||
| 2137 | void cmovnz(const Reg16& dst, const Mem16& src) {cmovne(dst, src);} | ||
| 2138 | void cmovo(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F40, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2139 | void cmovo(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F40, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2140 | void cmovp(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F4A, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2141 | void cmovp(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F4A, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2142 | void cmovpe(const Reg16& dst, const Reg16& src) {cmovp(dst, src);} | ||
| 2143 | void cmovpe(const Reg16& dst, const Mem16& src) {cmovp(dst, src);} | ||
| 2144 | void cmovpo(const Reg16& dst, const Reg16& src) {cmovnp(dst, src);} | ||
| 2145 | void cmovpo(const Reg16& dst, const Mem16& src) {cmovnp(dst, src);} | ||
| 2146 | void cmovs(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F48, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2147 | void cmovs(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F48, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2148 | void cmovz(const Reg16& dst, const Reg16& src) {cmove(dst, src);} | ||
| 2149 | void cmovz(const Reg16& dst, const Mem16& src) {cmove(dst, src);} | ||
| 2150 | void cmova(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F47, 0, RW(dst), R(src));} | ||
| 2151 | void cmova(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F47, 0, RW(dst), R(src));} | ||
| 2152 | void cmovae(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F43, 0, RW(dst), R(src));} | ||
| 2153 | void cmovae(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F43, 0, RW(dst), R(src));} | ||
| 2154 | void cmovb(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F42, 0, RW(dst), R(src));} | ||
| 2155 | void cmovb(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F42, 0, RW(dst), R(src));} | ||
| 2156 | void cmovbe(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F46, 0, RW(dst), R(src));} | ||
| 2157 | void cmovbe(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F46, 0, RW(dst), R(src));} | ||
| 2158 | void cmovc(const Reg32& dst, const Reg32& src) {cmovb(dst, src);} | ||
| 2159 | void cmovc(const Reg32& dst, const Mem32& src) {cmovb(dst, src);} | ||
| 2160 | void cmove(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F44, 0, RW(dst), R(src));} | ||
| 2161 | void cmove(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F44, 0, RW(dst), R(src));} | ||
| 2162 | void cmovg(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F4F, 0, RW(dst), R(src));} | ||
| 2163 | void cmovg(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F4F, 0, RW(dst), R(src));} | ||
| 2164 | void cmovge(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F4D, 0, RW(dst), R(src));} | ||
| 2165 | void cmovge(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F4D, 0, RW(dst), R(src));} | ||
| 2166 | void cmovl(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F4C, 0, RW(dst), R(src));} | ||
| 2167 | void cmovl(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F4C, 0, RW(dst), R(src));} | ||
| 2168 | void cmovle(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F4E, 0, RW(dst), R(src));} | ||
| 2169 | void cmovle(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F4E, 0, RW(dst), R(src));} | ||
| 2170 | void cmovna(const Reg32& dst, const Reg32& src) {cmovbe(dst, src);} | ||
| 2171 | void cmovna(const Reg32& dst, const Mem32& src) {cmovbe(dst, src);} | ||
| 2172 | void cmovnae(const Reg32& dst, const Reg32& src) {cmovb(dst, src);} | ||
| 2173 | void cmovnae(const Reg32& dst, const Mem32& src) {cmovb(dst, src);} | ||
| 2174 | void cmovnb(const Reg32& dst, const Reg32& src) {cmovae(dst, src);} | ||
| 2175 | void cmovnb(const Reg32& dst, const Mem32& src) {cmovae(dst, src);} | ||
| 2176 | void cmovnbe(const Reg32& dst, const Reg32& src) {cmova(dst, src);} | ||
| 2177 | void cmovnbe(const Reg32& dst, const Mem32& src) {cmova(dst, src);} | ||
| 2178 | void cmovnc(const Reg32& dst, const Reg32& src) {cmovae(dst, src);} | ||
| 2179 | void cmovnc(const Reg32& dst, const Mem32& src) {cmovae(dst, src);} | ||
| 2180 | void cmovne(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F45, 0, RW(dst), R(src));} | ||
| 2181 | void cmovne(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F45, 0, RW(dst), R(src));} | ||
| 2182 | void cmovng(const Reg32& dst, const Reg32& src) {cmovle(dst, src);} | ||
| 2183 | void cmovng(const Reg32& dst, const Mem32& src) {cmovle(dst, src);} | ||
| 2184 | void cmovnge(const Reg32& dst, const Reg32& src) {cmovl(dst, src);} | ||
| 2185 | void cmovnge(const Reg32& dst, const Mem32& src) {cmovl(dst, src);} | ||
| 2186 | void cmovnl(const Reg32& dst, const Reg32& src) {cmovge(dst, src);} | ||
| 2187 | void cmovnl(const Reg32& dst, const Mem32& src) {cmovge(dst, src);} | ||
| 2188 | void cmovnle(const Reg32& dst, const Reg32& src) {cmovg(dst, src);} | ||
| 2189 | void cmovnle(const Reg32& dst, const Mem32& src) {cmovg(dst, src);} | ||
| 2190 | void cmovno(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F41, 0, RW(dst), R(src));} | ||
| 2191 | void cmovno(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F41, 0, RW(dst), R(src));} | ||
| 2192 | void cmovnp(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F4B, 0, RW(dst), R(src));} | ||
| 2193 | void cmovnp(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F4B, 0, RW(dst), R(src));} | ||
| 2194 | void cmovns(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F49, 0, RW(dst), R(src));} | ||
| 2195 | void cmovns(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F49, 0, RW(dst), R(src));} | ||
| 2196 | void cmovnz(const Reg32& dst, const Reg32& src) {cmovne(dst, src);} | ||
| 2197 | void cmovnz(const Reg32& dst, const Mem32& src) {cmovne(dst, src);} | ||
| 2198 | void cmovo(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F40, 0, RW(dst), R(src));} | ||
| 2199 | void cmovo(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F40, 0, RW(dst), R(src));} | ||
| 2200 | void cmovp(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F4A, 0, RW(dst), R(src));} | ||
| 2201 | void cmovp(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F4A, 0, RW(dst), R(src));} | ||
| 2202 | void cmovpe(const Reg32& dst, const Reg32& src) {cmovp(dst, src);} | ||
| 2203 | void cmovpe(const Reg32& dst, const Mem32& src) {cmovp(dst, src);} | ||
| 2204 | void cmovpo(const Reg32& dst, const Reg32& src) {cmovnp(dst, src);} | ||
| 2205 | void cmovpo(const Reg32& dst, const Mem32& src) {cmovnp(dst, src);} | ||
| 2206 | void cmovs(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F48, 0, RW(dst), R(src));} | ||
| 2207 | void cmovs(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F48, 0, RW(dst), R(src));} | ||
| 2208 | void cmovz(const Reg32& dst, const Reg32& src) {cmove(dst, src);} | ||
| 2209 | void cmovz(const Reg32& dst, const Mem32& src) {cmove(dst, src);} | ||
| 2210 | #ifdef JITASM64 | ||
| 2211 | void cmova(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F47, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2212 | void cmova(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F47, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2213 | void cmovae(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F43, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2214 | void cmovae(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F43, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2215 | void cmovb(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F42, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2216 | void cmovb(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F42, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2217 | void cmovbe(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F46, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2218 | void cmovbe(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F46, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2219 | void cmovc(const Reg64& dst, const Reg64& src) {cmovb(dst, src);} | ||
| 2220 | void cmovc(const Reg64& dst, const Mem64& src) {cmovb(dst, src);} | ||
| 2221 | void cmove(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F44, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2222 | void cmove(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F44, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2223 | ✗ | void cmovg(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F4F, E_REXW_PREFIX, RW(dst), R(src));} | |
| 2224 | void cmovg(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F4F, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2225 | void cmovge(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F4D, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2226 | void cmovge(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F4D, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2227 | void cmovl(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F4C, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2228 | void cmovl(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F4C, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2229 | void cmovle(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F4E, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2230 | void cmovle(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F4E, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2231 | void cmovna(const Reg64& dst, const Reg64& src) {cmovbe(dst, src);} | ||
| 2232 | void cmovna(const Reg64& dst, const Mem64& src) {cmovbe(dst, src);} | ||
| 2233 | void cmovnae(const Reg64& dst, const Reg64& src) {cmovb(dst, src);} | ||
| 2234 | void cmovnae(const Reg64& dst, const Mem64& src) {cmovb(dst, src);} | ||
| 2235 | void cmovnb(const Reg64& dst, const Reg64& src) {cmovae(dst, src);} | ||
| 2236 | void cmovnb(const Reg64& dst, const Mem64& src) {cmovae(dst, src);} | ||
| 2237 | void cmovnbe(const Reg64& dst, const Reg64& src) {cmova(dst, src);} | ||
| 2238 | void cmovnbe(const Reg64& dst, const Mem64& src) {cmova(dst, src);} | ||
| 2239 | void cmovnc(const Reg64& dst, const Reg64& src) {cmovae(dst, src);} | ||
| 2240 | void cmovnc(const Reg64& dst, const Mem64& src) {cmovae(dst, src);} | ||
| 2241 | void cmovne(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F45, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2242 | void cmovne(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F45, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2243 | void cmovng(const Reg64& dst, const Reg64& src) {cmovle(dst, src);} | ||
| 2244 | void cmovng(const Reg64& dst, const Mem64& src) {cmovle(dst, src);} | ||
| 2245 | void cmovnge(const Reg64& dst, const Reg64& src) {cmovl(dst, src);} | ||
| 2246 | void cmovnge(const Reg64& dst, const Mem64& src) {cmovl(dst, src);} | ||
| 2247 | void cmovnl(const Reg64& dst, const Reg64& src) {cmovge(dst, src);} | ||
| 2248 | void cmovnl(const Reg64& dst, const Mem64& src) {cmovge(dst, src);} | ||
| 2249 | void cmovnle(const Reg64& dst, const Reg64& src) {cmovg(dst, src);} | ||
| 2250 | void cmovnle(const Reg64& dst, const Mem64& src) {cmovg(dst, src);} | ||
| 2251 | void cmovno(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F41, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2252 | void cmovno(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F41, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2253 | void cmovnp(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F4B, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2254 | void cmovnp(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F4B, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2255 | void cmovns(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F49, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2256 | void cmovns(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F49, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2257 | void cmovnz(const Reg64& dst, const Reg64& src) {cmovne(dst, src);} | ||
| 2258 | void cmovnz(const Reg64& dst, const Mem64& src) {cmovne(dst, src);} | ||
| 2259 | void cmovo(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F40, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2260 | void cmovo(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F40, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2261 | void cmovp(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F4A, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2262 | void cmovp(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F4A, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2263 | void cmovpe(const Reg64& dst, const Reg64& src) {cmovp(dst, src);} | ||
| 2264 | void cmovpe(const Reg64& dst, const Mem64& src) {cmovp(dst, src);} | ||
| 2265 | void cmovpo(const Reg64& dst, const Reg64& src) {cmovnp(dst, src);} | ||
| 2266 | void cmovpo(const Reg64& dst, const Mem64& src) {cmovnp(dst, src);} | ||
| 2267 | void cmovs(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F48, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2268 | void cmovs(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F48, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2269 | void cmovz(const Reg64& dst, const Reg64& src) {cmove(dst, src);} | ||
| 2270 | void cmovz(const Reg64& dst, const Mem64& src) {cmove(dst, src);} | ||
| 2271 | #endif | ||
| 2272 | void cmp(const Reg8& lhs, const Imm8& imm) {AppendInstr(I_CMP, 0x80, E_SPECIAL, Imm8(7), R(lhs), imm);} | ||
| 2273 | void cmp(const Mem8& lhs, const Imm8& imm) {AppendInstr(I_CMP, 0x80, 0, Imm8(7), R(lhs), imm);} | ||
| 2274 | void cmp(const Reg16& lhs, const Imm16& imm) {AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(7), R(lhs), detail::ImmXor8(imm));} | ||
| 2275 | void cmp(const Mem16& lhs, const Imm16& imm) {AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(7), R(lhs), detail::ImmXor8(imm));} | ||
| 2276 | void cmp(const Reg32& lhs, const Imm32& imm) {AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(7), R(lhs), detail::ImmXor8(imm));} | ||
| 2277 | void cmp(const Mem32& lhs, const Imm32& imm) {AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(7), R(lhs), detail::ImmXor8(imm));} | ||
| 2278 | void cmp(const Reg8& lhs, const Reg8& rhs) {AppendInstr(I_CMP, 0x3A, 0, R(lhs), R(rhs));} | ||
| 2279 | void cmp(const Mem8& lhs, const Reg8& rhs) {AppendInstr(I_CMP, 0x38, 0, R(rhs), R(lhs));} | ||
| 2280 | void cmp(const Reg8& lhs, const Mem8& rhs) {AppendInstr(I_CMP, 0x3A, 0, R(lhs), R(rhs));} | ||
| 2281 | void cmp(const Reg16& lhs, const Reg16& rhs) {AppendInstr(I_CMP, 0x3B, E_OPERAND_SIZE_PREFIX, R(lhs), R(rhs));} | ||
| 2282 | void cmp(const Mem16& lhs, const Reg16& rhs) {AppendInstr(I_CMP, 0x39, E_OPERAND_SIZE_PREFIX, R(rhs), R(lhs));} | ||
| 2283 | void cmp(const Reg16& lhs, const Mem16& rhs) {AppendInstr(I_CMP, 0x3B, E_OPERAND_SIZE_PREFIX, R(lhs), R(rhs));} | ||
| 2284 | void cmp(const Reg32& lhs, const Reg32& rhs) {AppendInstr(I_CMP, 0x3B, 0, R(lhs), R(rhs));} | ||
| 2285 | void cmp(const Mem32& lhs, const Reg32& rhs) {AppendInstr(I_CMP, 0x39, 0, R(rhs), R(lhs));} | ||
| 2286 | void cmp(const Reg32& lhs, const Mem32& rhs) {AppendInstr(I_CMP, 0x3B, 0, R(lhs), R(rhs));} | ||
| 2287 | #ifdef JITASM64 | ||
| 2288 | ✗ | void cmp(const Reg64& lhs, const Imm32& imm) {AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(7), R(lhs), detail::ImmXor8(imm));} | |
| 2289 | void cmp(const Mem64& lhs, const Imm32& imm) {AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(7), R(lhs), detail::ImmXor8(imm));} | ||
| 2290 | ✗ | void cmp(const Reg64& lhs, const Reg64& rhs) {AppendInstr(I_CMP, 0x3B, E_REXW_PREFIX, R(lhs), R(rhs));} | |
| 2291 | void cmp(const Mem64& lhs, const Reg64& rhs) {AppendInstr(I_CMP, 0x39, E_REXW_PREFIX, R(rhs), R(lhs));} | ||
| 2292 | void cmp(const Reg64& lhs, const Mem64& rhs) {AppendInstr(I_CMP, 0x3B, E_REXW_PREFIX, R(lhs), R(rhs));} | ||
| 2293 | #endif | ||
| 2294 | void cmpsb() {AppendInstr(I_CMPS_B, 0xA6, 0, Dummy(RW(edi)), Dummy(RW(esi)));} | ||
| 2295 | void cmpsw() {AppendInstr(I_CMPS_W, 0xA7, E_OPERAND_SIZE_PREFIX, Dummy(RW(edi)), Dummy(RW(esi)));} | ||
| 2296 | void cmpsd() {AppendInstr(I_CMPS_D, 0xA7, 0, Dummy(RW(edi)), Dummy(RW(esi)));} | ||
| 2297 | #ifdef JITASM64 | ||
| 2298 | void cmpsq() {AppendInstr(I_CMPS_Q, 0xA7, E_REXW_PREFIX, Dummy(RW(rdi)), Dummy(RW(rsi)));} | ||
| 2299 | #endif | ||
| 2300 | void cmpxchg(const Reg8& dst, const Reg8& src, const Reg8& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB0, 0, R(src), RW(dst), Dummy(RW(cmpx),al));} | ||
| 2301 | void cmpxchg(const Mem8& dst, const Reg8& src, const Reg8& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB0, 0, R(src), RW(dst), Dummy(RW(cmpx),al));} | ||
| 2302 | void cmpxchg(const Reg16& dst, const Reg16& src, const Reg16& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB1, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(RW(cmpx),ax));} | ||
| 2303 | void cmpxchg(const Mem16& dst, const Reg16& src, const Reg16& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB1, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(RW(cmpx),ax));} | ||
| 2304 | void cmpxchg(const Reg32& dst, const Reg32& src, const Reg32& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB1, 0, R(src), RW(dst), Dummy(RW(cmpx),eax));} | ||
| 2305 | void cmpxchg(const Mem32& dst, const Reg32& src, const Reg32& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB1, 0, R(src), RW(dst), Dummy(RW(cmpx),eax));} | ||
| 2306 | #ifdef JITASM64 | ||
| 2307 | void cmpxchg(const Reg64& dst, const Reg64& src, const Reg64& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB1, E_REXW_PREFIX, R(src), RW(dst), Dummy(RW(cmpx),rax));} | ||
| 2308 | void cmpxchg(const Mem64& dst, const Reg64& src, const Reg64& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB1, E_REXW_PREFIX, R(src), RW(dst), Dummy(RW(cmpx),rax));} | ||
| 2309 | #endif | ||
| 2310 | void cmpxchg8b(const Mem64& dst) {AppendInstr(I_CMPXCHG8B, 0x0FC7, 0, Imm8(1), RW(dst), Dummy(RW(edx)), Dummy(RW(eax)), Dummy(R(ecx)), Dummy(R(ebx)));} | ||
| 2311 | #ifdef JITASM64 | ||
| 2312 | void cmpxchg16b(const Mem128& dst) {AppendInstr(I_CMPXCHG16B, 0x0FC7, E_REXW_PREFIX, Imm8(1), RW(dst), Dummy(RW(rdx)), Dummy(RW(rax)), Dummy(R(rcx)), Dummy(R(rbx)));} | ||
| 2313 | #endif | ||
| 2314 | void cpuid() {AppendInstr(I_CPUID, 0x0FA2, 0, Dummy(RW(eax)), Dummy(RW(ecx)), Dummy(W(ebx)), Dummy(W(edx)));} | ||
| 2315 | void cwd() {AppendInstr(I_CWD, 0x99, E_OPERAND_SIZE_PREFIX, Dummy(W(dx)), Dummy(R(ax)));} | ||
| 2316 | void cdq() {AppendInstr(I_CDQ, 0x99, 0, Dummy(W(edx)), Dummy(R(eax)));} | ||
| 2317 | #ifdef JITASM64 | ||
| 2318 | void cqo() {AppendInstr(I_CQO, 0x99, E_REXW_PREFIX, Dummy(W(rdx)), Dummy(R(rax)));} | ||
| 2319 | #endif | ||
| 2320 | void dec(const Reg8& dst) {AppendInstr(I_DEC, 0xFE, 0, Imm8(1), RW(dst));} | ||
| 2321 | void dec(const Mem8& dst) {AppendInstr(I_DEC, 0xFE, 0, Imm8(1), RW(dst));} | ||
| 2322 | void dec(const Mem16& dst) {AppendInstr(I_DEC, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst));} | ||
| 2323 | void dec(const Mem32& dst) {AppendInstr(I_DEC, 0xFF, 0, Imm8(1), RW(dst));} | ||
| 2324 | #ifndef JITASM64 | ||
| 2325 | void dec(const Reg16& dst) {AppendInstr(I_DEC, 0x48, E_OPERAND_SIZE_PREFIX, RW(dst));} | ||
| 2326 | void dec(const Reg32& dst) {AppendInstr(I_DEC, 0x48, 0, RW(dst));} | ||
| 2327 | #else | ||
| 2328 | void dec(const Reg16& dst) {AppendInstr(I_DEC, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst));} | ||
| 2329 | void dec(const Reg32& dst) {AppendInstr(I_DEC, 0xFF, 0, Imm8(1), RW(dst));} | ||
| 2330 | ✗ | void dec(const Reg64& dst) {AppendInstr(I_DEC, 0xFF, E_REXW_PREFIX, Imm8(1), RW(dst));} | |
| 2331 | void dec(const Mem64& dst) {AppendInstr(I_DEC, 0xFF, E_REXW_PREFIX, Imm8(1), RW(dst));} | ||
| 2332 | #endif | ||
| 2333 | void div(const Reg8& src) {AppendInstr(I_DIV, 0xF6, 0, Imm8(6), R(src), Dummy(RW(ax)));} | ||
| 2334 | void div(const Mem8& src) {AppendInstr(I_DIV, 0xF6, 0, Imm8(6), R(src), Dummy(RW(ax)));} | ||
| 2335 | void div(const Reg16& src) {AppendInstr(I_DIV, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(6), R(src), Dummy(RW(ax)), Dummy(RW(dx)));} | ||
| 2336 | void div(const Mem16& src) {AppendInstr(I_DIV, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(6), R(src), Dummy(RW(ax)), Dummy(RW(dx)));} | ||
| 2337 | void div(const Reg32& src) {AppendInstr(I_DIV, 0xF7, 0, Imm8(6), R(src), Dummy(RW(eax)), Dummy(RW(edx)));} | ||
| 2338 | void div(const Mem32& src) {AppendInstr(I_DIV, 0xF7, 0, Imm8(6), R(src), Dummy(RW(eax)), Dummy(RW(edx)));} | ||
| 2339 | #ifdef JITASM64 | ||
| 2340 | void div(const Reg64& src) {AppendInstr(I_DIV, 0xF7, E_REXW_PREFIX, Imm8(6), R(src), Dummy(RW(rax)), Dummy(RW(rdx)));} | ||
| 2341 | void div(const Mem64& src) {AppendInstr(I_DIV, 0xF7, E_REXW_PREFIX, Imm8(6), R(src), Dummy(RW(rax)), Dummy(RW(rdx)));} | ||
| 2342 | #endif | ||
| 2343 | void enter(const Imm16& imm16, const Imm8& imm8) {AppendInstr(I_ENTER, 0xC8, 0, imm16, imm8, Dummy(RW(esp)), Dummy(RW(ebp)));} | ||
| 2344 | void hlt() {AppendInstr(I_HLT, 0xF4, 0);} | ||
| 2345 | void idiv(const Reg8& src) {AppendInstr(I_IDIV, 0xF6, 0, Imm8(7), R(src), Dummy(RW(ax)));} | ||
| 2346 | void idiv(const Mem8& src) {AppendInstr(I_IDIV, 0xF6, 0, Imm8(7), R(src), Dummy(RW(ax)));} | ||
| 2347 | void idiv(const Reg16& src) {AppendInstr(I_IDIV, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(7), R(src), Dummy(RW(ax)), Dummy(RW(dx)));} | ||
| 2348 | void idiv(const Mem16& src) {AppendInstr(I_IDIV, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(7), R(src), Dummy(RW(ax)), Dummy(RW(dx)));} | ||
| 2349 | void idiv(const Reg32& src) {AppendInstr(I_IDIV, 0xF7, 0, Imm8(7), R(src), Dummy(RW(eax)), Dummy(RW(edx)));} | ||
| 2350 | void idiv(const Mem32& src) {AppendInstr(I_IDIV, 0xF7, 0, Imm8(7), R(src), Dummy(RW(eax)), Dummy(RW(edx)));} | ||
| 2351 | #ifdef JITASM64 | ||
| 2352 | void idiv(const Reg64& src) {AppendInstr(I_IDIV, 0xF7, E_REXW_PREFIX, Imm8(7), R(src), Dummy(RW(rax)), Dummy(RW(rdx)));} | ||
| 2353 | void idiv(const Mem64& src) {AppendInstr(I_IDIV, 0xF7, E_REXW_PREFIX, Imm8(7), R(src), Dummy(RW(rax)), Dummy(RW(rdx)));} | ||
| 2354 | #endif | ||
| 2355 | void imul(const Reg8& src) {AppendInstr(I_IMUL, 0xF6, 0, Imm8(5), R(src), Dummy(RW(ax)));} | ||
| 2356 | void imul(const Mem8& src) {AppendInstr(I_IMUL, 0xF6, 0, Imm8(5), R(src), Dummy(RW(ax)));} | ||
| 2357 | void imul(const Reg16& src) {AppendInstr(I_IMUL, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(5), R(src), Dummy(RW(ax)), Dummy(W(dx)));} | ||
| 2358 | void imul(const Mem16& src) {AppendInstr(I_IMUL, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(5), R(src), Dummy(RW(ax)), Dummy(W(dx)));} | ||
| 2359 | void imul(const Reg32& src) {AppendInstr(I_IMUL, 0xF7, 0, Imm8(5), R(src), Dummy(RW(eax)), Dummy(W(edx)));} | ||
| 2360 | void imul(const Mem32& src) {AppendInstr(I_IMUL, 0xF7, 0, Imm8(5), R(src), Dummy(RW(eax)), Dummy(W(edx)));} | ||
| 2361 | void imul(const Reg16& dst, const Reg16& src) {AppendInstr(I_IMUL, 0x0FAF, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2362 | void imul(const Reg16& dst, const Mem16& src) {AppendInstr(I_IMUL, 0x0FAF, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2363 | void imul(const Reg32& dst, const Reg32& src) {AppendInstr(I_IMUL, 0x0FAF, 0, RW(dst), R(src));} | ||
| 2364 | void imul(const Reg32& dst, const Mem32& src) {AppendInstr(I_IMUL, 0x0FAF, 0, RW(dst), R(src));} | ||
| 2365 | void imul(const Reg16& dst, const Reg16& src, const Imm16& imm) {AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, E_OPERAND_SIZE_PREFIX, W(dst), R(src), detail::ImmXor8(imm));} | ||
| 2366 | void imul(const Reg16& dst, const Mem16& src, const Imm16& imm) {AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, E_OPERAND_SIZE_PREFIX, W(dst), R(src), detail::ImmXor8(imm));} | ||
| 2367 | void imul(const Reg32& dst, const Reg32& src, const Imm32& imm) {AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, 0, W(dst), R(src), detail::ImmXor8(imm));} | ||
| 2368 | void imul(const Reg32& dst, const Mem32& src, const Imm32& imm) {AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, 0, W(dst), R(src), detail::ImmXor8(imm));} | ||
| 2369 | void imul(const Reg16& dst, const Imm16& imm) {imul(dst, dst, imm);} | ||
| 2370 | void imul(const Reg32& dst, const Imm32& imm) {imul(dst, dst, imm);} | ||
| 2371 | #ifdef JITASM64 | ||
| 2372 | void imul(const Reg64& src) {AppendInstr(I_IMUL, 0xF7, E_REXW_PREFIX, Imm8(5), R(src), Dummy(RW(rax)), Dummy(W(rdx)));} | ||
| 2373 | void imul(const Mem64& src) {AppendInstr(I_IMUL, 0xF7, E_REXW_PREFIX, Imm8(5), R(src), Dummy(RW(rax)), Dummy(W(rdx)));} | ||
| 2374 | void imul(const Reg64& dst, const Reg64& src) {AppendInstr(I_IMUL, 0x0FAF, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2375 | ✗ | void imul(const Reg64& dst, const Mem64& src) {AppendInstr(I_IMUL, 0x0FAF, E_REXW_PREFIX, RW(dst), R(src));} | |
| 2376 | void imul(const Reg64& dst, const Reg64& src, const Imm32& imm) {AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, E_REXW_PREFIX, W(dst), R(src), detail::ImmXor8(imm));} | ||
| 2377 | void imul(const Reg64& dst, const Mem64& src, const Imm32& imm) {AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, E_REXW_PREFIX, W(dst), R(src), detail::ImmXor8(imm));} | ||
| 2378 | void imul(const Reg64& dst, const Imm32& imm) {imul(dst, dst, imm);} | ||
| 2379 | #endif | ||
| 2380 | void in(const Reg8& dst, const Imm8& src) {AppendInstr(I_IN, 0xE4, 0, src, Dummy(W(dst),al));} | ||
| 2381 | void in(const Reg16& dst, const Imm8& src) {AppendInstr(I_IN, 0xE5, E_OPERAND_SIZE_PREFIX, src, Dummy(W(dst),ax));} | ||
| 2382 | void in(const Reg32& dst, const Imm8& src) {AppendInstr(I_IN, 0xE5, 0, src, Dummy(W(dst),eax));} | ||
| 2383 | void in(const Reg8& dst, const Reg16& src) {AppendInstr(I_IN, 0xEC, 0, Dummy(R(src),dx), Dummy(W(dst),al));} | ||
| 2384 | void in(const Reg16& dst, const Reg16& src) {AppendInstr(I_IN, 0xED, E_OPERAND_SIZE_PREFIX, Dummy(R(src),dx), Dummy(W(dst),ax));} | ||
| 2385 | void in(const Reg32& dst, const Reg16& src) {AppendInstr(I_IN, 0xED, 0, Dummy(R(src),dx), Dummy(W(dst),eax));} | ||
| 2386 | void inc(const Reg8& dst) {AppendInstr(I_INC, 0xFE, 0, Imm8(0), RW(dst));} | ||
| 2387 | void inc(const Mem8& dst) {AppendInstr(I_INC, 0xFE, 0, Imm8(0), RW(dst));} | ||
| 2388 | void inc(const Mem16& dst) {AppendInstr(I_INC, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst));} | ||
| 2389 | void inc(const Mem32& dst) {AppendInstr(I_INC, 0xFF, 0, Imm8(0), RW(dst));} | ||
| 2390 | #ifndef JITASM64 | ||
| 2391 | void inc(const Reg16& dst) {AppendInstr(I_INC, 0x40, E_OPERAND_SIZE_PREFIX, RW(dst));} | ||
| 2392 | void inc(const Reg32& dst) {AppendInstr(I_INC, 0x40, 0, RW(dst));} | ||
| 2393 | #else | ||
| 2394 | void inc(const Reg16& dst) {AppendInstr(I_INC, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst));} | ||
| 2395 | void inc(const Reg32& dst) {AppendInstr(I_INC, 0xFF, 0, Imm8(0), RW(dst));} | ||
| 2396 | void inc(const Reg64& dst) {AppendInstr(I_INC, 0xFF, E_REXW_PREFIX, Imm8(0), RW(dst));} | ||
| 2397 | void inc(const Mem64& dst) {AppendInstr(I_INC, 0xFF, E_REXW_PREFIX, Imm8(0), RW(dst));} | ||
| 2398 | #endif | ||
| 2399 | void insb(const Reg& dst, const Reg16& src) {AppendInstr(I_INS_B, 0x6C, 0, Dummy(R(src),dx), Dummy(RW(dst),edi));} | ||
| 2400 | void insw(const Reg& dst, const Reg16& src) {AppendInstr(I_INS_W, 0x6D, E_OPERAND_SIZE_PREFIX, Dummy(R(src),dx), Dummy(RW(dst),edi));} | ||
| 2401 | void insd(const Reg& dst, const Reg16& src) {AppendInstr(I_INS_D, 0x6D, 0, Dummy(R(src),dx), Dummy(RW(dst),edi));} | ||
| 2402 | void rep_insb(const Reg& dst, const Reg16& src, const Reg& count) {AppendInstr(I_INS_B, 0x6C, E_REP_PREFIX, Dummy(R(src),dx), Dummy(RW(dst),edi), Dummy(RW(count),ecx));} | ||
| 2403 | void rep_insw(const Reg& dst, const Reg16& src, const Reg& count) {AppendInstr(I_INS_W, 0x6D, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(R(src),dx), Dummy(RW(dst),edi), Dummy(RW(count),ecx));} | ||
| 2404 | void rep_insd(const Reg& dst, const Reg16& src, const Reg& count) {AppendInstr(I_INS_D, 0x6D, E_REP_PREFIX, Dummy(R(src),dx), Dummy(RW(dst),edi), Dummy(RW(count),ecx));} | ||
| 2405 | void int3() {AppendInstr(I_INT3, 0xCC, 0);} | ||
| 2406 | void intn(const Imm8& n) {AppendInstr(I_INTN, 0xCD, 0, n);} | ||
| 2407 | #ifndef JITASM64 | ||
| 2408 | void into() {AppendInstr(I_INTO, 0xCE, 0);} | ||
| 2409 | #endif | ||
| 2410 | void invd() {AppendInstr(I_INVD, 0x0F08, 0);} | ||
| 2411 | template<class Ty> void invlpg(const MemT<Ty>& dst) {AppendInstr(I_INVLPG, 0x0F01, 0, Imm8(7), R(dst));} | ||
| 2412 | void iret() {AppendInstr(I_IRET, 0xCF, E_OPERAND_SIZE_PREFIX);} | ||
| 2413 | void iretd() {AppendInstr(I_IRETD, 0xCF, 0);} | ||
| 2414 | #ifdef JITASM64 | ||
| 2415 | void iretq() {AppendInstr(I_IRETQ, 0xCF, E_REXW_PREFIX);} | ||
| 2416 | #endif | ||
| 2417 | ✗ | void jmp(const std::string& label_name) {AppendJmp(GetLabelID(label_name));} | |
| 2418 | void ja(const std::string& label_name) {AppendJcc(JCC_A, GetLabelID(label_name));} | ||
| 2419 | void jae(const std::string& label_name) {AppendJcc(JCC_AE, GetLabelID(label_name));} | ||
| 2420 | void jb(const std::string& label_name) {AppendJcc(JCC_B, GetLabelID(label_name));} | ||
| 2421 | void jbe(const std::string& label_name) {AppendJcc(JCC_BE, GetLabelID(label_name));} | ||
| 2422 | void jc(const std::string& label_name) {jb(label_name);} | ||
| 2423 | #ifdef JITASM64 | ||
| 2424 | void jecxz(const std::string& label_name) {AppendJcc(JCC_ECXZ, GetLabelID(label_name));} // short jump only | ||
| 2425 | void jrcxz (const std::string& label_name) {AppendJcc(JCC_RCXZ, GetLabelID(label_name));} // short jump only | ||
| 2426 | #else | ||
| 2427 | void jcxz(const std::string& label_name) {AppendJcc(JCC_CXZ, GetLabelID(label_name));} // short jump only | ||
| 2428 | void jecxz(const std::string& label_name) {AppendJcc(JCC_ECXZ, GetLabelID(label_name));} // short jump only | ||
| 2429 | #endif | ||
| 2430 | ✗ | void je(const std::string& label_name) {AppendJcc(JCC_E, GetLabelID(label_name));} | |
| 2431 | ✗ | void jg(const std::string& label_name) {AppendJcc(JCC_G, GetLabelID(label_name));} | |
| 2432 | ✗ | void jge(const std::string& label_name) {AppendJcc(JCC_GE, GetLabelID(label_name));} | |
| 2433 | ✗ | void jl(const std::string& label_name) {AppendJcc(JCC_L, GetLabelID(label_name));} | |
| 2434 | ✗ | void jle(const std::string& label_name) {AppendJcc(JCC_LE, GetLabelID(label_name));} | |
| 2435 | void jna(const std::string& label_name) {jbe(label_name);} | ||
| 2436 | void jnae(const std::string& label_name) {jb(label_name);} | ||
| 2437 | void jnb(const std::string& label_name) {jae(label_name);} | ||
| 2438 | void jnbe(const std::string& label_name) {ja(label_name);} | ||
| 2439 | void jnc(const std::string& label_name) {jae(label_name);} | ||
| 2440 | void jne(const std::string& label_name) {AppendJcc(JCC_NE, GetLabelID(label_name));} | ||
| 2441 | void jng(const std::string& label_name) {jle(label_name);} | ||
| 2442 | void jnge(const std::string& label_name) {jl(label_name);} | ||
| 2443 | void jnl(const std::string& label_name) {jge(label_name);} | ||
| 2444 | void jnle(const std::string& label_name) {jg(label_name);} | ||
| 2445 | void jno(const std::string& label_name) {AppendJcc(JCC_NO, GetLabelID(label_name));} | ||
| 2446 | void jnp(const std::string& label_name) {AppendJcc(JCC_NP, GetLabelID(label_name));} | ||
| 2447 | void jns(const std::string& label_name) {AppendJcc(JCC_NS, GetLabelID(label_name));} | ||
| 2448 | void jnz(const std::string& label_name) {jne(label_name);} | ||
| 2449 | void jo(const std::string& label_name) {AppendJcc(JCC_O, GetLabelID(label_name));} | ||
| 2450 | void jp(const std::string& label_name) {AppendJcc(JCC_P, GetLabelID(label_name));} | ||
| 2451 | void jpe(const std::string& label_name) {jp(label_name);} | ||
| 2452 | void jpo(const std::string& label_name) {jnp(label_name);} | ||
| 2453 | void js(const std::string& label_name) {AppendJcc(JCC_S, GetLabelID(label_name));} | ||
| 2454 | void jz(const std::string& label_name) {je(label_name);} | ||
| 2455 | void lar(const Reg16& dst, const Reg16& src) {AppendInstr(I_LAR, 0x0F02, E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 2456 | void lar(const Reg16& dst, const Mem16& src) {AppendInstr(I_LAR, 0x0F02, E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 2457 | void lar(const Reg32& dst, const Reg32& src) {AppendInstr(I_LAR, 0x0F02, 0, W(dst), R(src));} | ||
| 2458 | void lar(const Reg32& dst, const Mem16& src) {AppendInstr(I_LAR, 0x0F02, 0, W(dst), R(src));} | ||
| 2459 | #ifdef JITASM64 | ||
| 2460 | void lar(const Reg64& dst, const Reg64& src) {AppendInstr(I_LAR, 0x0F02, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2461 | void lar(const Reg64& dst, const Mem16& src) {AppendInstr(I_LAR, 0x0F02, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2462 | #endif | ||
| 2463 | template<class Ty> void lea(const Reg16& dst, const MemT<Ty>& src) {AppendInstr(I_LEA, 0x8D, E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 2464 | template<class Ty> void lea(const Reg32& dst, const MemT<Ty>& src) {AppendInstr(I_LEA, 0x8D, 0, W(dst), R(src));} | ||
| 2465 | #ifdef JITASM64 | ||
| 2466 | ✗ | template<class Ty> void lea(const Reg64& dst, const MemT<Ty>& src) {AppendInstr(I_LEA, 0x8D, E_REXW_PREFIX, W(dst), R(src));} | |
| 2467 | #endif | ||
| 2468 | void leave() {AppendInstr(I_LEAVE, 0xC9, 0, Dummy(W(esp)), Dummy(RW(ebp)));} | ||
| 2469 | //lgdt | ||
| 2470 | //lidt | ||
| 2471 | void lldt(const Reg16& src) {AppendInstr(I_LLDT, 0x0F00, 0, Imm8(2), R(src));} | ||
| 2472 | void lldt(const Mem16& src) {AppendInstr(I_LLDT, 0x0F00, 0, Imm8(2), R(src));} | ||
| 2473 | void lmsw(const Reg16& src) {AppendInstr(I_LMSW, 0x0F01, 0, Imm8(6), R(src));} | ||
| 2474 | void lmsw(const Mem16& src) {AppendInstr(I_LMSW, 0x0F01, 0, Imm8(6), R(src));} | ||
| 2475 | void lodsb(const Reg8& dst, const Reg& src) {AppendInstr(I_LODS_B, 0xAC, 0, Dummy(W(dst),al), Dummy(RW(src),zsi));} | ||
| 2476 | void lodsw(const Reg16& dst, const Reg& src) {AppendInstr(I_LODS_W, 0xAD, E_OPERAND_SIZE_PREFIX, Dummy(W(dst),ax), Dummy(RW(src),zsi));} | ||
| 2477 | void lodsd(const Reg32& dst, const Reg& src) {AppendInstr(I_LODS_D, 0xAD, 0, Dummy(W(dst),eax), Dummy(RW(src),zsi));} | ||
| 2478 | #ifdef JITASM64 | ||
| 2479 | void lodsq(const Reg64& dst, const Reg& src) {AppendInstr(I_LODS_Q, 0xAD, E_REXW_PREFIX, Dummy(W(dst),rax), Dummy(RW(src),rsi));} | ||
| 2480 | #endif | ||
| 2481 | void rep_lodsb(const Reg8& dst, const Reg& src, const Reg& count) {AppendInstr(I_LODS_B, 0xAC, E_REP_PREFIX, Dummy(RW(dst),al), Dummy(RW(src),zsi), Dummy(RW(count),zcx));} // dst is RW because of ecx == 0 | ||
| 2482 | void rep_lodsw(const Reg16& dst, const Reg& src, const Reg& count) {AppendInstr(I_LODS_W, 0xAD, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(RW(dst),ax), Dummy(RW(src),zsi), Dummy(RW(count),zcx));} // dst is RW because of ecx == 0 | ||
| 2483 | void rep_lodsd(const Reg32& dst, const Reg& src, const Reg& count) {AppendInstr(I_LODS_D, 0xAD, E_REP_PREFIX, Dummy(RW(dst),eax), Dummy(RW(src),zsi), Dummy(RW(count),zcx));} // dst is RW because of ecx == 0 | ||
| 2484 | #ifdef JITASM64 | ||
| 2485 | void rep_lodsq(const Reg64& dst, const Reg& src, const Reg& count) {AppendInstr(I_LODS_Q, 0xAD, E_REP_PREFIX | E_REXW_PREFIX, Dummy(RW(dst),rax), Dummy(RW(src),rsi), Dummy(RW(count),rcx));} // dst is RW because of ecx == 0 | ||
| 2486 | #endif | ||
| 2487 | void loop(const std::string& label_name) {AppendInstr(I_LOOP, 0xE2, E_SPECIAL, Imm64(GetLabelID(label_name)), Dummy(RW(zcx)));} // short jump only | ||
| 2488 | void loope(const std::string& label_name) {AppendInstr(I_LOOP, 0xE1, E_SPECIAL, Imm64(GetLabelID(label_name)), Dummy(RW(zcx)));} // short jump only | ||
| 2489 | void loopne(const std::string& label_name) {AppendInstr(I_LOOP, 0xE0, E_SPECIAL, Imm64(GetLabelID(label_name)), Dummy(RW(zcx)));} // short jump only | ||
| 2490 | void lsl(const Reg16& dst, const Reg16& src) {AppendInstr(I_LSL, 0x0F03, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2491 | void lsl(const Reg16& dst, const Mem16& src) {AppendInstr(I_LSL, 0x0F03, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2492 | void lsl(const Reg32& dst, const Reg32& src) {AppendInstr(I_LSL, 0x0F03, 0, RW(dst), R(src));} | ||
| 2493 | void lsl(const Reg32& dst, const Mem16& src) {AppendInstr(I_LSL, 0x0F03, 0, RW(dst), R(src));} | ||
| 2494 | #ifdef JITASM64 | ||
| 2495 | void lsl(const Reg64& dst, const Reg32& src) {AppendInstr(I_LSL, 0x0F03, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2496 | void lsl(const Reg64& dst, const Mem16& src) {AppendInstr(I_LSL, 0x0F03, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2497 | #endif | ||
| 2498 | void ltr(const Reg16& src) {AppendInstr(I_LTR, 0x0F00, 0, Imm8(3), R(src));} | ||
| 2499 | void ltr(const Mem16& src) {AppendInstr(I_LTR, 0x0F00, 0, Imm8(3), R(src));} | ||
| 2500 | void mov(const Reg8& dst, const Reg8& src) {AppendInstr(I_MOV, 0x8A, 0, W(dst), R(src));} | ||
| 2501 | void mov(const Mem8& dst, const Reg8& src) {AppendInstr(I_MOV, 0x88, E_SPECIAL, R(src), W(dst));} | ||
| 2502 | void mov(const Reg16& dst, const Reg16& src) {AppendInstr(I_MOV, 0x8B, E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 2503 | void mov(const Mem16& dst, const Reg16& src) {AppendInstr(I_MOV, 0x89, E_OPERAND_SIZE_PREFIX | E_SPECIAL, R(src), W(dst));} | ||
| 2504 | void mov(const Reg32& dst, const Reg32& src) {AppendInstr(I_MOV, 0x8B, 0, W(dst), R(src));} | ||
| 2505 | void mov(const Mem32& dst, const Reg32& src) {AppendInstr(I_MOV, 0x89, E_SPECIAL, R(src), W(dst));} | ||
| 2506 | void mov(const Reg8& dst, const Mem8& src) {AppendInstr(I_MOV, 0x8A, E_SPECIAL, W(dst), R(src));} | ||
| 2507 | void mov(const Reg16& dst, const Mem16& src) {AppendInstr(I_MOV, 0x8B, E_OPERAND_SIZE_PREFIX | E_SPECIAL, W(dst), R(src));} | ||
| 2508 | void mov(const Reg32& dst, const Mem32& src) {AppendInstr(I_MOV, 0x8B, E_SPECIAL, W(dst), R(src));} | ||
| 2509 | void mov(const Reg8& dst, const Imm8& imm) {AppendInstr(I_MOV, 0xB0, 0, W(dst), imm);} | ||
| 2510 | void mov(const Reg16& dst, const Imm16& imm) {AppendInstr(I_MOV, 0xB8, E_OPERAND_SIZE_PREFIX, W(dst), imm);} | ||
| 2511 | ✗ | void mov(const Reg32& dst, const Imm32& imm) {AppendInstr(I_MOV, 0xB8, 0, W(dst), imm);} | |
| 2512 | void mov(const Mem8& dst, const Imm8& imm) {AppendInstr(I_MOV, 0xC6, 0, Imm8(0), W(dst), imm);} | ||
| 2513 | void mov(const Mem16& dst, const Imm16& imm) {AppendInstr(I_MOV, 0xC7, E_OPERAND_SIZE_PREFIX, Imm8(0), W(dst), imm);} | ||
| 2514 | void mov(const Mem32& dst, const Imm32& imm) {AppendInstr(I_MOV, 0xC7, 0, Imm8(0), W(dst), imm);} | ||
| 2515 | #ifdef JITASM64 | ||
| 2516 | ✗ | void mov(const Reg64& dst, const Reg64& src) {AppendInstr(I_MOV, 0x8B, E_REXW_PREFIX, W(dst), R(src));} | |
| 2517 | ✗ | void mov(const Mem64& dst, const Reg64& src) {AppendInstr(I_MOV, 0x89, E_REXW_PREFIX, R(src), W(dst));} | |
| 2518 | ✗ | void mov(const Reg64& dst, const Mem64& src) {AppendInstr(I_MOV, 0x8B, E_REXW_PREFIX, W(dst), R(src));} | |
| 2519 | ✗ | void mov(const Reg64& dst, const Imm64& imm) {detail::IsInt32(imm.GetImm()) ? AppendInstr(I_MOV, 0xC7, E_REXW_PREFIX, Imm8(0), W(dst), Imm32((sint32) imm.GetImm())) : AppendInstr(I_MOV, 0xB8, E_REXW_PREFIX, W(dst), imm);} | |
| 2520 | void mov(const Mem64& dst, const Imm32& imm) {AppendInstr(I_MOV, 0xC7, E_REXW_PREFIX, Imm8(0), W(dst), imm);} | ||
| 2521 | void mov(const Reg64& dst, const MemOffset64& src) {AppendInstr(I_MOV, 0xA1, E_REXW_PREFIX, Imm64(src.GetOffset()), Dummy(W(dst), rax));} | ||
| 2522 | void mov(const MemOffset64& dst, const Reg64& src) {AppendInstr(I_MOV, 0xA3, E_REXW_PREFIX, Imm64(dst.GetOffset()), Dummy(R(src), rax));} | ||
| 2523 | #endif | ||
| 2524 | void movbe(const Reg16& dst, const Mem16& src) {AppendInstr(I_MOVBE, 0x0F38F0, E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 2525 | void movbe(const Reg32& dst, const Mem32& src) {AppendInstr(I_MOVBE, 0x0F38F0, 0, W(dst), R(src));} | ||
| 2526 | void movbe(const Mem16& dst, const Reg16& src) {AppendInstr(I_MOVBE, 0x0F38F1, E_OPERAND_SIZE_PREFIX, R(src), W(dst));} | ||
| 2527 | void movbe(const Mem32& dst, const Reg32& src) {AppendInstr(I_MOVBE, 0x0F38F1, 0, R(src), W(dst));} | ||
| 2528 | #ifdef JITASM64 | ||
| 2529 | void movbe(const Reg64& dst, const Mem64& src) {AppendInstr(I_MOVBE, 0x0F38F0, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2530 | void movbe(const Mem64& dst, const Reg64& src) {AppendInstr(I_MOVBE, 0x0F38F1, E_REXW_PREFIX, R(src), W(dst));} | ||
| 2531 | #endif | ||
| 2532 | void movsb(const Reg& dst, const Reg& src) {AppendInstr(I_MOVS_B, 0xA4, 0, Dummy(RW(dst), zdi), Dummy(RW(src), zsi));} | ||
| 2533 | void movsw(const Reg& dst, const Reg& src) {AppendInstr(I_MOVS_W, 0xA5, E_OPERAND_SIZE_PREFIX, Dummy(RW(dst), zdi), Dummy(RW(src), zsi));} | ||
| 2534 | void movsd(const Reg& dst, const Reg& src) {AppendInstr(I_MOVS_D, 0xA5, 0, Dummy(RW(dst), zdi), Dummy(RW(src), zsi));} | ||
| 2535 | #ifdef JITASM64 | ||
| 2536 | void movsq(const Reg& dst, const Reg& src) {AppendInstr(I_MOVS_Q, 0xA5, E_REXW_PREFIX, Dummy(RW(dst), rdi), Dummy(RW(src), rsi));} | ||
| 2537 | #endif | ||
| 2538 | void rep_movsb() {rep_movsb(zdi, zsi, zcx);} | ||
| 2539 | void rep_movsw() {rep_movsw(zdi, zsi, zcx);} | ||
| 2540 | void rep_movsd() {rep_movsd(zdi, zsi, zcx);} | ||
| 2541 | void rep_movsb(const Reg& dst, const Reg& src, const Reg& count) {AppendInstr(I_MOVS_B, 0xA4, E_REP_PREFIX, Dummy(RW(dst), zdi), Dummy(RW(src), zsi), Dummy(RW(count), ecx));} | ||
| 2542 | void rep_movsw(const Reg& dst, const Reg& src, const Reg& count) {AppendInstr(I_MOVS_W, 0xA5, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(RW(dst), zdi), Dummy(RW(src), zsi), Dummy(RW(count), ecx));} | ||
| 2543 | void rep_movsd(const Reg& dst, const Reg& src, const Reg& count) {AppendInstr(I_MOVS_D, 0xA5, E_REP_PREFIX, Dummy(RW(dst), zdi), Dummy(RW(src), zsi), Dummy(RW(count), ecx));} | ||
| 2544 | #ifdef JITASM64 | ||
| 2545 | void rep_movsq() {rep_movsq(rdi, rsi, rcx);} | ||
| 2546 | void rep_movsq(const Reg64& dst, const Reg64& src, const Reg64& count) {AppendInstr(I_MOVS_Q, 0xA5, E_REP_PREFIX | E_REXW_PREFIX, Dummy(RW(dst), rdi), Dummy(RW(src), rsi), Dummy(RW(count), rcx));} | ||
| 2547 | #endif | ||
| 2548 | void movsx(const Reg16& dst, const Reg8& src) {AppendInstr(I_MOVSX, 0x0FBE, E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 2549 | void movsx(const Reg16& dst, const Mem8& src) {AppendInstr(I_MOVSX, 0x0FBE, E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 2550 | void movsx(const Reg32& dst, const Reg8& src) {AppendInstr(I_MOVSX, 0x0FBE, 0, W(dst), R(src));} | ||
| 2551 | void movsx(const Reg32& dst, const Mem8& src) {AppendInstr(I_MOVSX, 0x0FBE, 0, W(dst), R(src));} | ||
| 2552 | void movsx(const Reg32& dst, const Reg16& src) {AppendInstr(I_MOVSX, 0x0FBF, 0, W(dst), R(src));} | ||
| 2553 | void movsx(const Reg32& dst, const Mem16& src) {AppendInstr(I_MOVSX, 0x0FBF, 0, W(dst), R(src));} | ||
| 2554 | #ifdef JITASM64 | ||
| 2555 | void movsx(const Reg64& dst, const Reg8& src) {AppendInstr(I_MOVSX, 0x0FBE, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2556 | void movsx(const Reg64& dst, const Mem8& src) {AppendInstr(I_MOVSX, 0x0FBE, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2557 | void movsx(const Reg64& dst, const Reg16& src) {AppendInstr(I_MOVSX, 0x0FBF, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2558 | void movsx(const Reg64& dst, const Mem16& src) {AppendInstr(I_MOVSX, 0x0FBF, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2559 | void movsxd(const Reg64& dst, const Reg32& src) {AppendInstr(I_MOVSXD, 0x63, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2560 | void movsxd(const Reg64& dst, const Mem32& src) {AppendInstr(I_MOVSXD, 0x63, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2561 | #endif | ||
| 2562 | void movzx(const Reg16& dst, const Reg8& src) {AppendInstr(I_MOVZX, 0x0FB6, E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 2563 | void movzx(const Reg16& dst, const Mem8& src) {AppendInstr(I_MOVZX, 0x0FB6, E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 2564 | void movzx(const Reg32& dst, const Reg8& src) {AppendInstr(I_MOVZX, 0x0FB6, 0, W(dst), R(src));} | ||
| 2565 | void movzx(const Reg32& dst, const Mem8& src) {AppendInstr(I_MOVZX, 0x0FB6, 0, W(dst), R(src));} | ||
| 2566 | void movzx(const Reg32& dst, const Reg16& src) {AppendInstr(I_MOVZX, 0x0FB7, 0, W(dst), R(src));} | ||
| 2567 | void movzx(const Reg32& dst, const Mem16& src) {AppendInstr(I_MOVZX, 0x0FB7, 0, W(dst), R(src));} | ||
| 2568 | #ifdef JITASM64 | ||
| 2569 | void movzx(const Reg64& dst, const Reg8& src) {AppendInstr(I_MOVZX, 0x0FB6, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2570 | ✗ | void movzx(const Reg64& dst, const Mem8& src) {AppendInstr(I_MOVZX, 0x0FB6, E_REXW_PREFIX, W(dst), R(src));} | |
| 2571 | void movzx(const Reg64& dst, const Reg16& src) {AppendInstr(I_MOVZX, 0x0FB7, E_REXW_PREFIX, W(dst), R(src));} | ||
| 2572 | ✗ | void movzx(const Reg64& dst, const Mem16& src) {AppendInstr(I_MOVZX, 0x0FB7, E_REXW_PREFIX, W(dst), R(src));} | |
| 2573 | #endif | ||
| 2574 | void mul(const Reg8& src) {AppendInstr(I_MUL, 0xF6, 0, Imm8(4), R(src), Dummy(RW(ax)));} | ||
| 2575 | void mul(const Mem8& src) {AppendInstr(I_MUL, 0xF6, 0, Imm8(4), R(src), Dummy(RW(ax)));} | ||
| 2576 | void mul(const Reg16& src) {AppendInstr(I_MUL, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(4), R(src), Dummy(RW(ax)), Dummy(W(dx)));} | ||
| 2577 | void mul(const Mem16& src) {AppendInstr(I_MUL, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(4), R(src), Dummy(RW(ax)), Dummy(W(dx)));} | ||
| 2578 | void mul(const Reg32& src) {AppendInstr(I_MUL, 0xF7, 0, Imm8(4), R(src), Dummy(RW(eax)), Dummy(W(edx)));} | ||
| 2579 | void mul(const Mem32& src) {AppendInstr(I_MUL, 0xF7, 0, Imm8(4), R(src), Dummy(RW(eax)), Dummy(W(edx)));} | ||
| 2580 | #ifdef JITASM64 | ||
| 2581 | void mul(const Reg64& src) {AppendInstr(I_MUL, 0xF7, E_REXW_PREFIX, Imm8(4), R(src), Dummy(RW(rax)), Dummy(W(rdx)));} | ||
| 2582 | void mul(const Mem64& src) {AppendInstr(I_MUL, 0xF7, E_REXW_PREFIX, Imm8(4), R(src), Dummy(RW(rax)), Dummy(W(rdx)));} | ||
| 2583 | #endif | ||
| 2584 | void neg(const Reg8& dst) {AppendInstr(I_NEG, 0xF6, 0, Imm8(3), RW(dst));} | ||
| 2585 | void neg(const Mem8& dst) {AppendInstr(I_NEG, 0xF6, 0, Imm8(3), RW(dst));} | ||
| 2586 | void neg(const Reg16& dst) {AppendInstr(I_NEG, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst));} | ||
| 2587 | void neg(const Mem16& dst) {AppendInstr(I_NEG, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst));} | ||
| 2588 | void neg(const Reg32& dst) {AppendInstr(I_NEG, 0xF7, 0, Imm8(3), RW(dst));} | ||
| 2589 | void neg(const Mem32& dst) {AppendInstr(I_NEG, 0xF7, 0, Imm8(3), RW(dst));} | ||
| 2590 | #ifdef JITASM64 | ||
| 2591 | void neg(const Reg64& dst) {AppendInstr(I_NEG, 0xF7, E_REXW_PREFIX, Imm8(3), RW(dst));} | ||
| 2592 | void neg(const Mem64& dst) {AppendInstr(I_NEG, 0xF7, E_REXW_PREFIX, Imm8(3), RW(dst));} | ||
| 2593 | #endif | ||
| 2594 | void nop() {AppendInstr(I_NOP, 0x90, 0);} | ||
| 2595 | void not_(const Reg8& dst) {AppendInstr(I_NOT, 0xF6, 0, Imm8(2), RW(dst));} | ||
| 2596 | void not_(const Mem8& dst) {AppendInstr(I_NOT, 0xF6, 0, Imm8(2), RW(dst));} | ||
| 2597 | void not_(const Reg16& dst) {AppendInstr(I_NOT, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst));} | ||
| 2598 | void not_(const Mem16& dst) {AppendInstr(I_NOT, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst));} | ||
| 2599 | void not_(const Reg32& dst) {AppendInstr(I_NOT, 0xF7, 0, Imm8(2), RW(dst));} | ||
| 2600 | void not_(const Mem32& dst) {AppendInstr(I_NOT, 0xF7, 0, Imm8(2), RW(dst));} | ||
| 2601 | #ifdef JITASM64 | ||
| 2602 | void not_(const Reg64& dst) {AppendInstr(I_NOT, 0xF7, E_REXW_PREFIX, Imm8(2), RW(dst));} | ||
| 2603 | void not_(const Mem64& dst) {AppendInstr(I_NOT, 0xF7, E_REXW_PREFIX, Imm8(2), RW(dst));} | ||
| 2604 | #endif | ||
| 2605 | void or_(const Reg8& dst, const Imm8& imm) {AppendInstr(I_OR, 0x80, E_SPECIAL, Imm8(1), RW(dst), imm);} | ||
| 2606 | void or_(const Mem8& dst, const Imm8& imm) {AppendInstr(I_OR, 0x80, 0, Imm8(1), RW(dst), imm);} | ||
| 2607 | void or_(const Reg16& dst, const Imm16& imm) {AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(1), RW(dst), detail::ImmXor8(imm));} | ||
| 2608 | void or_(const Mem16& dst, const Imm16& imm) {AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), detail::ImmXor8(imm));} | ||
| 2609 | void or_(const Reg32& dst, const Imm32& imm) {AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(1), RW(dst), detail::ImmXor8(imm));} | ||
| 2610 | void or_(const Mem32& dst, const Imm32& imm) {AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(1), RW(dst), detail::ImmXor8(imm));} | ||
| 2611 | void or_(const Reg8& dst, const Reg8& src) {AppendInstr(I_OR, 0x0A, 0, RW(dst), R(src));} | ||
| 2612 | void or_(const Mem8& dst, const Reg8& src) {AppendInstr(I_OR, 0x08, 0, R(src), RW(dst));} | ||
| 2613 | void or_(const Reg8& dst, const Mem8& src) {AppendInstr(I_OR, 0x0A, 0, RW(dst), R(src));} | ||
| 2614 | void or_(const Reg16& dst, const Reg16& src) {AppendInstr(I_OR, 0x0B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2615 | void or_(const Mem16& dst, const Reg16& src) {AppendInstr(I_OR, 0x09, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));} | ||
| 2616 | void or_(const Reg16& dst, const Mem16& src) {AppendInstr(I_OR, 0x0B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2617 | void or_(const Reg32& dst, const Reg32& src) {AppendInstr(I_OR, 0x0B, 0, RW(dst), R(src));} | ||
| 2618 | void or_(const Mem32& dst, const Reg32& src) {AppendInstr(I_OR, 0x09, 0, R(src), RW(dst));} | ||
| 2619 | void or_(const Reg32& dst, const Mem32& src) {AppendInstr(I_OR, 0x0B, 0, RW(dst), R(src));} | ||
| 2620 | #ifdef JITASM64 | ||
| 2621 | void or_(const Reg64& dst, const Imm32& imm) {AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(1), RW(dst), detail::ImmXor8(imm));} | ||
| 2622 | void or_(const Mem64& dst, const Imm32& imm) {AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(1), RW(dst), detail::ImmXor8(imm));} | ||
| 2623 | void or_(const Reg64& dst, const Reg64& src) {AppendInstr(I_OR, 0x0B, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2624 | void or_(const Mem64& dst, const Reg64& src) {AppendInstr(I_OR, 0x09, E_REXW_PREFIX, R(src), RW(dst));} | ||
| 2625 | void or_(const Reg64& dst, const Mem64& src) {AppendInstr(I_OR, 0x0B, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2626 | #endif | ||
| 2627 | void out(const Imm8& dst, const Reg8& src) {AppendInstr(I_OUT, 0xE6, 0, dst, Dummy(R(src),al));} | ||
| 2628 | void out(const Imm8& dst, const Reg16& src) {AppendInstr(I_OUT, 0xE7, E_OPERAND_SIZE_PREFIX, dst, Dummy(R(src),ax));} | ||
| 2629 | void out(const Imm8& dst, const Reg32& src) {AppendInstr(I_OUT, 0xE7, 0, dst, Dummy(R(src),eax));} | ||
| 2630 | void out(const Reg16& dst, const Reg8& src) {AppendInstr(I_OUT, 0xEE, 0, Dummy(R(dst),dx), Dummy(R(src),al));} | ||
| 2631 | void out(const Reg16& dst, const Reg16& src) {AppendInstr(I_OUT, 0xEF, E_OPERAND_SIZE_PREFIX, Dummy(R(dst),dx), Dummy(R(src),ax));} | ||
| 2632 | void out(const Reg16& dst, const Reg32& src) {AppendInstr(I_OUT, 0xEF, 0, Dummy(R(dst),dx), Dummy(R(src),eax));} | ||
| 2633 | void outsb(const Reg16& dst, const Reg& src) {AppendInstr(I_OUTS_B, 0x6E, 0, Dummy(RW(src),esi), Dummy(R(dst),dx));} | ||
| 2634 | void outsw(const Reg16& dst, const Reg& src) {AppendInstr(I_OUTS_W, 0x6F, E_OPERAND_SIZE_PREFIX, Dummy(RW(src),esi), Dummy(R(dst),dx));} | ||
| 2635 | void outsd(const Reg16& dst, const Reg& src) {AppendInstr(I_OUTS_D, 0x6F, 0, Dummy(RW(src),esi), Dummy(R(dst),dx));} | ||
| 2636 | void rep_outsb(const Reg16& dst, const Reg& src, const Reg& count) {AppendInstr(I_OUTS_B, 0x6E, E_REP_PREFIX, Dummy(RW(src),esi), Dummy(R(dst),dx), Dummy(RW(count),ecx));} | ||
| 2637 | void rep_outsw(const Reg16& dst, const Reg& src, const Reg& count) {AppendInstr(I_OUTS_W, 0x6F, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(RW(src),esi), Dummy(R(dst),dx), Dummy(RW(count),ecx));} | ||
| 2638 | void rep_outsd(const Reg16& dst, const Reg& src, const Reg& count) {AppendInstr(I_OUTS_D, 0x6F, E_REP_PREFIX, Dummy(RW(src),esi), Dummy(R(dst),dx), Dummy(RW(count),ecx));} | ||
| 2639 | void pop(const Reg16& dst) {AppendInstr(I_POP, 0x58, E_OPERAND_SIZE_PREFIX, W(dst));} | ||
| 2640 | void pop(const Mem16& dst) {AppendInstr(I_POP, 0x8F, E_OPERAND_SIZE_PREFIX, Imm8(0), W(dst));} | ||
| 2641 | #ifndef JITASM64 | ||
| 2642 | void pop(const Reg32& dst) {AppendInstr(I_POP, 0x58, 0, W(dst), Dummy(RW(esp)));} | ||
| 2643 | void pop(const Mem32& dst) {AppendInstr(I_POP, 0x8F, 0, Imm8(0), W(dst), Dummy(RW(esp)));} | ||
| 2644 | #else | ||
| 2645 | ✗ | void pop(const Reg64& dst) {AppendInstr(I_POP, 0x58, 0, W(dst), Dummy(RW(esp)));} | |
| 2646 | void pop(const Mem64& dst) {AppendInstr(I_POP, 0x8F, 0, Imm8(0), W(dst), Dummy(RW(esp)));} | ||
| 2647 | #endif | ||
| 2648 | #ifndef JITASM64 | ||
| 2649 | void popa() {popad();} | ||
| 2650 | void popad() {AppendInstr(I_POPAD, 0x61, 0, Dummy(RW(esp)));} | ||
| 2651 | #endif | ||
| 2652 | #ifndef JITASM64 | ||
| 2653 | void popf() {AppendInstr(I_POPF, 0x9D, E_OPERAND_SIZE_PREFIX, Dummy(RW(esp)));} | ||
| 2654 | void popfd() {AppendInstr(I_POPFD, 0x9D, 0, Dummy(RW(esp)));} | ||
| 2655 | #else | ||
| 2656 | void popf() {AppendInstr(I_POPF, 0x9D, E_OPERAND_SIZE_PREFIX, Dummy(RW(esp)));} | ||
| 2657 | void popfq() {AppendInstr(I_POPFQ, 0x9D, 0, Dummy(RW(esp)));} | ||
| 2658 | #endif | ||
| 2659 | void push(const Reg16& src) {AppendInstr(I_PUSH, 0x50, E_OPERAND_SIZE_PREFIX, R(src), Dummy(RW(esp)));} | ||
| 2660 | void push(const Mem16& src) {AppendInstr(I_PUSH, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(6), R(src), Dummy(RW(esp)));} | ||
| 2661 | #ifndef JITASM64 | ||
| 2662 | void push(const Reg32& src) {AppendInstr(I_PUSH, 0x50, 0, R(src), Dummy(RW(esp)));} | ||
| 2663 | void push(const Mem32& src) {AppendInstr(I_PUSH, 0xFF, 0, Imm8(6), R(src), Dummy(RW(esp)));} | ||
| 2664 | #else | ||
| 2665 | ✗ | void push(const Reg64& src) {AppendInstr(I_PUSH, 0x50, 0, R(src), Dummy(RW(esp)));} | |
| 2666 | void push(const Mem64& src) {AppendInstr(I_PUSH, 0xFF, 0, Imm8(6), R(src), Dummy(RW(esp)));} | ||
| 2667 | #endif | ||
| 2668 | void push(const Imm32& imm) {AppendInstr(I_PUSH, detail::IsInt8(imm.GetImm()) ? 0x6A : 0x68, 0, detail::ImmXor8(imm), Dummy(RW(esp)));} | ||
| 2669 | #ifndef JITASM64 | ||
| 2670 | void pusha() {pushad();} | ||
| 2671 | void pushad() {AppendInstr(I_PUSHAD, 0x60, 0, Dummy(RW(esp)));} | ||
| 2672 | #endif | ||
| 2673 | void pushf() {AppendInstr(I_PUSHF, 0x9C, E_OPERAND_SIZE_PREFIX, Dummy(RW(esp)));} | ||
| 2674 | #ifndef JITASM64 | ||
| 2675 | void pushfd() {AppendInstr(I_PUSHFD, 0x9C, 0, Dummy(RW(esp)));} | ||
| 2676 | #else | ||
| 2677 | void pushfq() {AppendInstr(I_PUSHFQ, 0x9C, 0, Dummy(RW(esp)));} | ||
| 2678 | #endif | ||
| 2679 | void rcl(const Reg8& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD2, 0, Imm8(2), RW(dst), Dummy(R(shift),cl));} | ||
| 2680 | void rcl(const Mem8& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD2, 0, Imm8(2), RW(dst), Dummy(R(shift),cl));} | ||
| 2681 | void rcl(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD0, 0, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC0, 0, Imm8(2), RW(dst), shift);} | ||
| 2682 | void rcl(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD0, 0, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC0, 0, Imm8(2), RW(dst), shift);} | ||
| 2683 | void rcr(const Reg8& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD2, 0, Imm8(3), RW(dst), Dummy(R(shift),cl));} | ||
| 2684 | void rcr(const Mem8& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD2, 0, Imm8(3), RW(dst), Dummy(R(shift),cl));} | ||
| 2685 | void rcr(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD0, 0, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC0, 0, Imm8(3), RW(dst), shift);} | ||
| 2686 | void rcr(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD0, 0, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC0, 0, Imm8(3), RW(dst), shift);} | ||
| 2687 | void rol(const Reg8& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD2, 0, Imm8(0), RW(dst), Dummy(R(shift),cl));} | ||
| 2688 | void rol(const Mem8& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD2, 0, Imm8(0), RW(dst), Dummy(R(shift),cl));} | ||
| 2689 | void rol(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD0, 0, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC0, 0, Imm8(0), RW(dst), shift);} | ||
| 2690 | void rol(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD0, 0, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC0, 0, Imm8(0), RW(dst), shift);} | ||
| 2691 | void ror(const Reg8& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD2, 0, Imm8(1), RW(dst), Dummy(R(shift),cl));} | ||
| 2692 | void ror(const Mem8& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD2, 0, Imm8(1), RW(dst), Dummy(R(shift),cl));} | ||
| 2693 | void ror(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD0, 0, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC0, 0, Imm8(1), RW(dst), shift);} | ||
| 2694 | void ror(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD0, 0, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC0, 0, Imm8(1), RW(dst), shift);} | ||
| 2695 | void rcl(const Reg16& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), Dummy(R(shift),cl));} | ||
| 2696 | void rcl(const Mem16& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), Dummy(R(shift),cl));} | ||
| 2697 | void rcl(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), shift);} | ||
| 2698 | void rcl(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), shift);} | ||
| 2699 | void rcr(const Reg16& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), Dummy(R(shift),cl));} | ||
| 2700 | void rcr(const Mem16& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), Dummy(R(shift),cl));} | ||
| 2701 | void rcr(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), shift);} | ||
| 2702 | void rcr(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), shift);} | ||
| 2703 | void rol(const Reg16& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), Dummy(R(shift),cl));} | ||
| 2704 | void rol(const Mem16& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), Dummy(R(shift),cl));} | ||
| 2705 | void rol(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), shift);} | ||
| 2706 | void rol(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), shift);} | ||
| 2707 | void ror(const Reg16& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), Dummy(R(shift),cl));} | ||
| 2708 | void ror(const Mem16& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), Dummy(R(shift),cl));} | ||
| 2709 | void ror(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), shift);} | ||
| 2710 | void ror(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), shift);} | ||
| 2711 | void rcl(const Reg32& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD3, 0, Imm8(2), RW(dst), Dummy(R(shift),cl));} | ||
| 2712 | void rcl(const Mem32& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD3, 0, Imm8(2), RW(dst), Dummy(R(shift),cl));} | ||
| 2713 | void rcl(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, 0, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, 0, Imm8(2), RW(dst), shift);} | ||
| 2714 | void rcl(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, 0, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, 0, Imm8(2), RW(dst), shift);} | ||
| 2715 | void rcr(const Reg32& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD3, 0, Imm8(3), RW(dst), Dummy(R(shift),cl));} | ||
| 2716 | void rcr(const Mem32& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD3, 0, Imm8(3), RW(dst), Dummy(R(shift),cl));} | ||
| 2717 | void rcr(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, 0, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, 0, Imm8(3), RW(dst), shift);} | ||
| 2718 | void rcr(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, 0, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, 0, Imm8(3), RW(dst), shift);} | ||
| 2719 | void rol(const Reg32& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD3, 0, Imm8(0), RW(dst), Dummy(R(shift),cl));} | ||
| 2720 | void rol(const Mem32& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD3, 0, Imm8(0), RW(dst), Dummy(R(shift),cl));} | ||
| 2721 | void rol(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, 0, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, 0, Imm8(0), RW(dst), shift);} | ||
| 2722 | void rol(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, 0, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, 0, Imm8(0), RW(dst), shift);} | ||
| 2723 | void ror(const Reg32& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD3, 0, Imm8(1), RW(dst), Dummy(R(shift),cl));} | ||
| 2724 | void ror(const Mem32& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD3, 0, Imm8(1), RW(dst), Dummy(R(shift),cl));} | ||
| 2725 | void ror(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, 0, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, 0, Imm8(1), RW(dst), shift);} | ||
| 2726 | void ror(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, 0, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, 0, Imm8(1), RW(dst), shift);} | ||
| 2727 | #ifdef JITASM64 | ||
| 2728 | void rcl(const Reg64& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD3, E_REXW_PREFIX, Imm8(2), RW(dst), Dummy(R(shift),cl));} | ||
| 2729 | void rcl(const Mem64& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD3, E_REXW_PREFIX, Imm8(2), RW(dst), Dummy(R(shift),cl));} | ||
| 2730 | void rcl(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, E_REXW_PREFIX, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, E_REXW_PREFIX, Imm8(2), RW(dst), shift);} | ||
| 2731 | void rcl(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, E_REXW_PREFIX, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, E_REXW_PREFIX, Imm8(2), RW(dst), shift);} | ||
| 2732 | void rcr(const Reg64& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD3, E_REXW_PREFIX, Imm8(3), RW(dst), Dummy(R(shift),cl));} | ||
| 2733 | void rcr(const Mem64& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD3, E_REXW_PREFIX, Imm8(3), RW(dst), Dummy(R(shift),cl));} | ||
| 2734 | void rcr(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, E_REXW_PREFIX, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, E_REXW_PREFIX, Imm8(3), RW(dst), shift);} | ||
| 2735 | void rcr(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, E_REXW_PREFIX, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, E_REXW_PREFIX, Imm8(3), RW(dst), shift);} | ||
| 2736 | void rol(const Reg64& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD3, E_REXW_PREFIX, Imm8(0), RW(dst), Dummy(R(shift),cl));} | ||
| 2737 | void rol(const Mem64& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD3, E_REXW_PREFIX, Imm8(0), RW(dst), Dummy(R(shift),cl));} | ||
| 2738 | void rol(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, E_REXW_PREFIX, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, E_REXW_PREFIX, Imm8(0), RW(dst), shift);} | ||
| 2739 | void rol(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, E_REXW_PREFIX, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, E_REXW_PREFIX, Imm8(0), RW(dst), shift);} | ||
| 2740 | void ror(const Reg64& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD3, E_REXW_PREFIX, Imm8(1), RW(dst), Dummy(R(shift),cl));} | ||
| 2741 | void ror(const Mem64& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD3, E_REXW_PREFIX, Imm8(1), RW(dst), Dummy(R(shift),cl));} | ||
| 2742 | void ror(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, E_REXW_PREFIX, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, E_REXW_PREFIX, Imm8(1), RW(dst), shift);} | ||
| 2743 | void ror(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, E_REXW_PREFIX, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, E_REXW_PREFIX, Imm8(1), RW(dst), shift);} | ||
| 2744 | #endif | ||
| 2745 | void rdmsr() {AppendInstr(I_RDMSR, 0x0F32, 0, Dummy(R(ecx)), Dummy(W(edx)), Dummy(W(eax)));} | ||
| 2746 | void rdpmc() {AppendInstr(I_RDMSR, 0x0F33, 0, Dummy(R(ecx)), Dummy(W(edx)), Dummy(W(eax)));} | ||
| 2747 | void rdtsc() {AppendInstr(I_RDPMC, 0x0F31, 0, Dummy(W(edx)), Dummy(W(eax)), Dummy(W(ecx)));} | ||
| 2748 | ✗ | void ret() {AppendInstr(I_RET, 0xC3, 0, Dummy(RW(esp)));} | |
| 2749 | void ret(const Imm16& imm) {AppendInstr(I_RET, 0xC2, 0, imm, Dummy(RW(esp)));} | ||
| 2750 | void rsm() {AppendInstr(I_RSM, 0x0FAA, 0);} | ||
| 2751 | void sal(const Reg8& dst, const Reg8& shift) {shl(dst, shift);} | ||
| 2752 | void sal(const Mem8& dst, const Reg8& shift) {shl(dst, shift);} | ||
| 2753 | void sal(const Reg8& dst, const Imm8& shift) {shl(dst, shift);} | ||
| 2754 | void sal(const Mem8& dst, const Imm8& shift) {shl(dst, shift);} | ||
| 2755 | void sar(const Reg8& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD2, 0, Imm8(7), RW(dst), Dummy(R(shift),cl));} | ||
| 2756 | void sar(const Mem8& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD2, 0, Imm8(7), RW(dst), Dummy(R(shift),cl));} | ||
| 2757 | void sar(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD0, 0, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC0, 0, Imm8(7), RW(dst), shift);} | ||
| 2758 | void sar(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD0, 0, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC0, 0, Imm8(7), RW(dst), shift);} | ||
| 2759 | void shl(const Reg8& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD2, 0, Imm8(4), RW(dst), Dummy(R(shift),cl));} | ||
| 2760 | void shl(const Mem8& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD2, 0, Imm8(4), RW(dst), Dummy(R(shift),cl));} | ||
| 2761 | void shl(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD0, 0, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC0, 0, Imm8(4), RW(dst), shift);} | ||
| 2762 | void shl(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD0, 0, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC0, 0, Imm8(4), RW(dst), shift);} | ||
| 2763 | void shr(const Reg8& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD2, 0, Imm8(5), RW(dst), Dummy(R(shift),cl));} | ||
| 2764 | void shr(const Mem8& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD2, 0, Imm8(5), RW(dst), Dummy(R(shift),cl));} | ||
| 2765 | void shr(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD0, 0, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC0, 0, Imm8(5), RW(dst), shift);} | ||
| 2766 | void shr(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD0, 0, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC0, 0, Imm8(5), RW(dst), shift);} | ||
| 2767 | void sal(const Reg16& dst, const Reg8& shift) {shl(dst, shift);} | ||
| 2768 | void sal(const Mem16& dst, const Reg8& shift) {shl(dst, shift);} | ||
| 2769 | void sal(const Reg16& dst, const Imm8& shift) {shl(dst, shift);} | ||
| 2770 | void sal(const Mem16& dst, const Imm8& shift) {shl(dst, shift);} | ||
| 2771 | void sar(const Reg16& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst), Dummy(R(shift),cl));} | ||
| 2772 | void sar(const Mem16& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst), Dummy(R(shift),cl));} | ||
| 2773 | void sar(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst), shift);} | ||
| 2774 | void sar(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst), shift);} | ||
| 2775 | void shl(const Reg16& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), Dummy(R(shift),cl));} | ||
| 2776 | void shl(const Mem16& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), Dummy(R(shift),cl));} | ||
| 2777 | void shl(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), shift);} | ||
| 2778 | void shl(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), shift);} | ||
| 2779 | void shr(const Reg16& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), Dummy(R(shift),cl));} | ||
| 2780 | void shr(const Mem16& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), Dummy(R(shift),cl));} | ||
| 2781 | void shr(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), shift);} | ||
| 2782 | void shr(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), shift);} | ||
| 2783 | void sal(const Reg32& dst, const Reg8& shift) {shl(dst, shift);} | ||
| 2784 | void sal(const Mem32& dst, const Reg8& shift) {shl(dst, shift);} | ||
| 2785 | void sal(const Reg32& dst, const Imm8& shift) {shl(dst, shift);} | ||
| 2786 | void sal(const Mem32& dst, const Imm8& shift) {shl(dst, shift);} | ||
| 2787 | void sar(const Reg32& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD3, 0, Imm8(7), RW(dst), Dummy(R(shift),cl));} | ||
| 2788 | void sar(const Mem32& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD3, 0, Imm8(7), RW(dst), Dummy(R(shift),cl));} | ||
| 2789 | void sar(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, 0, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, 0, Imm8(7), RW(dst), shift);} | ||
| 2790 | void sar(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, 0, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, 0, Imm8(7), RW(dst), shift);} | ||
| 2791 | void shl(const Reg32& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD3, 0, Imm8(4), RW(dst), Dummy(R(shift),cl));} | ||
| 2792 | void shl(const Mem32& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD3, 0, Imm8(4), RW(dst), Dummy(R(shift),cl));} | ||
| 2793 | void shl(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, 0, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, 0, Imm8(4), RW(dst), shift);} | ||
| 2794 | void shl(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, 0, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, 0, Imm8(4), RW(dst), shift);} | ||
| 2795 | void shr(const Reg32& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD3, 0, Imm8(5), RW(dst), Dummy(R(shift),cl));} | ||
| 2796 | void shr(const Mem32& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD3, 0, Imm8(5), RW(dst), Dummy(R(shift),cl));} | ||
| 2797 | void shr(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, 0, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, 0, Imm8(5), RW(dst), shift);} | ||
| 2798 | void shr(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, 0, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, 0, Imm8(5), RW(dst), shift);} | ||
| 2799 | #ifdef JITASM64 | ||
| 2800 | void sal(const Reg64& dst, const Reg8& shift) {shl(dst, shift);} | ||
| 2801 | void sal(const Mem64& dst, const Reg8& shift) {shl(dst, shift);} | ||
| 2802 | void sal(const Reg64& dst, const Imm8& shift) {shl(dst, shift);} | ||
| 2803 | void sal(const Mem64& dst, const Imm8& shift) {shl(dst, shift);} | ||
| 2804 | void sar(const Reg64& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD3, E_REXW_PREFIX, Imm8(7), RW(dst), Dummy(R(shift),cl));} | ||
| 2805 | void sar(const Mem64& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD3, E_REXW_PREFIX, Imm8(7), RW(dst), Dummy(R(shift),cl));} | ||
| 2806 | void sar(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, E_REXW_PREFIX, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, E_REXW_PREFIX, Imm8(7), RW(dst), shift);} | ||
| 2807 | void sar(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, E_REXW_PREFIX, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, E_REXW_PREFIX, Imm8(7), RW(dst), shift);} | ||
| 2808 | void shl(const Reg64& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD3, E_REXW_PREFIX, Imm8(4), RW(dst), Dummy(R(shift),cl));} | ||
| 2809 | void shl(const Mem64& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD3, E_REXW_PREFIX, Imm8(4), RW(dst), Dummy(R(shift),cl));} | ||
| 2810 | ✗ | void shl(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, E_REXW_PREFIX, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, E_REXW_PREFIX, Imm8(4), RW(dst), shift);} | |
| 2811 | void shl(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, E_REXW_PREFIX, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, E_REXW_PREFIX, Imm8(4), RW(dst), shift);} | ||
| 2812 | void shr(const Reg64& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD3, E_REXW_PREFIX, Imm8(5), RW(dst), Dummy(R(shift),cl));} | ||
| 2813 | void shr(const Mem64& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD3, E_REXW_PREFIX, Imm8(5), RW(dst), Dummy(R(shift),cl));} | ||
| 2814 | void shr(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, E_REXW_PREFIX, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, E_REXW_PREFIX, Imm8(5), RW(dst), shift);} | ||
| 2815 | void shr(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, E_REXW_PREFIX, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, E_REXW_PREFIX, Imm8(5), RW(dst), shift);} | ||
| 2816 | #endif | ||
| 2817 | void sbb(const Reg8& dst, const Imm8& imm) {AppendInstr(I_SBB, 0x80, E_SPECIAL, Imm8(3), RW(dst), imm);} | ||
| 2818 | void sbb(const Mem8& dst, const Imm8& imm) {AppendInstr(I_SBB, 0x80, 0, Imm8(3), RW(dst), imm);} | ||
| 2819 | void sbb(const Reg16& dst, const Imm16& imm) {AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(3), RW(dst), detail::ImmXor8(imm));} | ||
| 2820 | void sbb(const Mem16& dst, const Imm16& imm) {AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), detail::ImmXor8(imm));} | ||
| 2821 | void sbb(const Reg32& dst, const Imm32& imm) {AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(3), RW(dst), detail::ImmXor8(imm));} | ||
| 2822 | void sbb(const Mem32& dst, const Imm32& imm) {AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(3), RW(dst), detail::ImmXor8(imm));} | ||
| 2823 | void sbb(const Reg8& dst, const Reg8& src) {AppendInstr(I_SBB, 0x1A, 0, RW(dst), R(src));} | ||
| 2824 | void sbb(const Mem8& dst, const Reg8& src) {AppendInstr(I_SBB, 0x18, 0, R(src), RW(dst));} | ||
| 2825 | void sbb(const Reg8& dst, const Mem8& src) {AppendInstr(I_SBB, 0x1A, 0, RW(dst), R(src));} | ||
| 2826 | void sbb(const Reg16& dst, const Reg16& src) {AppendInstr(I_SBB, 0x1B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2827 | void sbb(const Mem16& dst, const Reg16& src) {AppendInstr(I_SBB, 0x19, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));} | ||
| 2828 | void sbb(const Reg16& dst, const Mem16& src) {AppendInstr(I_SBB, 0x1B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2829 | void sbb(const Reg32& dst, const Reg32& src) {AppendInstr(I_SBB, 0x1B, 0, RW(dst), R(src));} | ||
| 2830 | void sbb(const Mem32& dst, const Reg32& src) {AppendInstr(I_SBB, 0x19, 0, R(src), RW(dst));} | ||
| 2831 | void sbb(const Reg32& dst, const Mem32& src) {AppendInstr(I_SBB, 0x1B, 0, RW(dst), R(src));} | ||
| 2832 | #ifdef JITASM64 | ||
| 2833 | void sbb(const Reg64& dst, const Imm32& imm) {AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(3), RW(dst), detail::ImmXor8(imm));} | ||
| 2834 | void sbb(const Mem64& dst, const Imm32& imm) {AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(3), RW(dst), detail::ImmXor8(imm));} | ||
| 2835 | void sbb(const Reg64& dst, const Reg64& src) {AppendInstr(I_SBB, 0x1B, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2836 | void sbb(const Mem64& dst, const Reg64& src) {AppendInstr(I_SBB, 0x19, E_REXW_PREFIX, R(src), RW(dst));} | ||
| 2837 | void sbb(const Reg64& dst, const Mem64& src) {AppendInstr(I_SBB, 0x1B, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 2838 | #endif | ||
| 2839 | void scasb() {AppendInstr(I_SCAS_B, 0xAE, 0, Dummy(R(al)), Dummy(RW(edi)));} | ||
| 2840 | void scasw() {AppendInstr(I_SCAS_W, 0xAF, E_OPERAND_SIZE_PREFIX, Dummy(R(ax)), Dummy(RW(edi)));} | ||
| 2841 | void scasd() {AppendInstr(I_SCAS_D, 0xAF, 0, Dummy(R(eax)), Dummy(RW(edi)));} | ||
| 2842 | #ifdef JITASM64 | ||
| 2843 | void scasq() {AppendInstr(I_SCAS_Q, 0xAF, E_REXW_PREFIX, Dummy(R(rax)), Dummy(RW(rdi)));} | ||
| 2844 | #endif | ||
| 2845 | void seta(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F97, 0, Imm8(0), W(dst));} | ||
| 2846 | void seta(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F97, 0, Imm8(0), W(dst));} | ||
| 2847 | void setae(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F93, 0, Imm8(0), W(dst));} | ||
| 2848 | void setae(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F93, 0, Imm8(0), W(dst));} | ||
| 2849 | void setb(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F92, 0, Imm8(0), W(dst));} | ||
| 2850 | void setb(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F92, 0, Imm8(0), W(dst));} | ||
| 2851 | void setbe(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F96, 0, Imm8(0), W(dst));} | ||
| 2852 | void setbe(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F96, 0, Imm8(0), W(dst));} | ||
| 2853 | void setc(const Reg8& dst) {setb(dst);} | ||
| 2854 | void setc(const Mem8& dst) {setb(dst);} | ||
| 2855 | void sete(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F94, 0, Imm8(0), W(dst));} | ||
| 2856 | void sete(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F94, 0, Imm8(0), W(dst));} | ||
| 2857 | void setg(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F9F, 0, Imm8(0), W(dst));} | ||
| 2858 | void setg(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F9F, 0, Imm8(0), W(dst));} | ||
| 2859 | void setge(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F9D, 0, Imm8(0), W(dst));} | ||
| 2860 | void setge(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F9D, 0, Imm8(0), W(dst));} | ||
| 2861 | void setl(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F9C, 0, Imm8(0), W(dst));} | ||
| 2862 | void setl(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F9C, 0, Imm8(0), W(dst));} | ||
| 2863 | void setle(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F9E, 0, Imm8(0), W(dst));} | ||
| 2864 | void setle(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F9E, 0, Imm8(0), W(dst));} | ||
| 2865 | void setna(const Reg8& dst) {setbe(dst);} | ||
| 2866 | void setna(const Mem8& dst) {setbe(dst);} | ||
| 2867 | void setnae(const Reg8& dst) {setb(dst);} | ||
| 2868 | void setnae(const Mem8& dst) {setb(dst);} | ||
| 2869 | void setnb(const Reg8& dst) {setae(dst);} | ||
| 2870 | void setnb(const Mem8& dst) {setae(dst);} | ||
| 2871 | void setnbe(const Reg8& dst) {seta(dst);} | ||
| 2872 | void setnbe(const Mem8& dst) {seta(dst);} | ||
| 2873 | void setnc(const Reg8& dst) {setae(dst);} | ||
| 2874 | void setnc(const Mem8& dst) {setae(dst);} | ||
| 2875 | void setne(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F95, 0, Imm8(0), W(dst));} | ||
| 2876 | void setne(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F95, 0, Imm8(0), W(dst));} | ||
| 2877 | void setng(const Reg8& dst) {setle(dst);} | ||
| 2878 | void setng(const Mem8& dst) {setle(dst);} | ||
| 2879 | void setnge(const Reg8& dst) {setl(dst);} | ||
| 2880 | void setnge(const Mem8& dst) {setl(dst);} | ||
| 2881 | void setnl(const Reg8& dst) {setge(dst);} | ||
| 2882 | void setnl(const Mem8& dst) {setge(dst);} | ||
| 2883 | void setnle(const Reg8& dst) {setg(dst);} | ||
| 2884 | void setnle(const Mem8& dst) {setg(dst);} | ||
| 2885 | void setno(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F91, 0, Imm8(0), W(dst));} | ||
| 2886 | void setno(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F91, 0, Imm8(0), W(dst));} | ||
| 2887 | void setnp(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F9B, 0, Imm8(0), W(dst));} | ||
| 2888 | void setnp(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F9B, 0, Imm8(0), W(dst));} | ||
| 2889 | void setns(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F99, 0, Imm8(0), W(dst));} | ||
| 2890 | void setns(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F99, 0, Imm8(0), W(dst));} | ||
| 2891 | void setnz(const Reg8& dst) {setne(dst);} | ||
| 2892 | void setnz(const Mem8& dst) {setne(dst);} | ||
| 2893 | void seto(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F90, 0, Imm8(0), W(dst));} | ||
| 2894 | void seto(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F90, 0, Imm8(0), W(dst));} | ||
| 2895 | void setp(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F9A, 0, Imm8(0), W(dst));} | ||
| 2896 | void setp(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F9A, 0, Imm8(0), W(dst));} | ||
| 2897 | void setpe(const Reg8& dst) {setp(dst);} | ||
| 2898 | void setpe(const Mem8& dst) {setp(dst);} | ||
| 2899 | void setpo(const Reg8& dst) {setnp(dst);} | ||
| 2900 | void setpo(const Mem8& dst) {setnp(dst);} | ||
| 2901 | void sets(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F98, 0, Imm8(0), W(dst));} | ||
| 2902 | void sets(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F98, 0, Imm8(0), W(dst));} | ||
| 2903 | void setz(const Reg8& dst) {sete(dst);} | ||
| 2904 | void setz(const Mem8& dst) {sete(dst);} | ||
| 2905 | void shld(const Reg16& dst, const Reg16& src, const Imm8& place) {AppendInstr(I_SHLD, 0x0FA4, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), place);} | ||
| 2906 | void shld(const Mem16& dst, const Reg16& src, const Imm8& place) {AppendInstr(I_SHLD, 0x0FA4, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), place);} | ||
| 2907 | void shld(const Reg16& dst, const Reg16& src, const Reg8& place) {AppendInstr(I_SHLD, 0x0FA5, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(R(place),cl));} | ||
| 2908 | void shld(const Mem16& dst, const Reg16& src, const Reg8& place) {AppendInstr(I_SHLD, 0x0FA5, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(R(place),cl));} | ||
| 2909 | void shld(const Reg32& dst, const Reg32& src, const Imm8& place) {AppendInstr(I_SHLD, 0x0FA4, 0, R(src), RW(dst), place);} | ||
| 2910 | void shld(const Mem32& dst, const Reg32& src, const Imm8& place) {AppendInstr(I_SHLD, 0x0FA4, 0, R(src), RW(dst), place);} | ||
| 2911 | void shld(const Reg32& dst, const Reg32& src, const Reg8& place) {AppendInstr(I_SHLD, 0x0FA5, 0, R(src), RW(dst), Dummy(R(place),cl));} | ||
| 2912 | void shld(const Mem32& dst, const Reg32& src, const Reg8& place) {AppendInstr(I_SHLD, 0x0FA5, 0, R(src), RW(dst), Dummy(R(place),cl));} | ||
| 2913 | #ifdef JITASM64 | ||
| 2914 | void shld(const Reg64& dst, const Reg64& src, const Imm8& place) {AppendInstr(I_SHLD, 0x0FA4, E_REXW_PREFIX, R(src), RW(dst), place);} | ||
| 2915 | void shld(const Mem64& dst, const Reg64& src, const Imm8& place) {AppendInstr(I_SHLD, 0x0FA4, E_REXW_PREFIX, R(src), RW(dst), place);} | ||
| 2916 | void shld(const Reg64& dst, const Reg64& src, const Reg8& place) {AppendInstr(I_SHLD, 0x0FA5, E_REXW_PREFIX, R(src), RW(dst), Dummy(R(place),cl));} | ||
| 2917 | void shld(const Mem64& dst, const Reg64& src, const Reg8& place) {AppendInstr(I_SHLD, 0x0FA5, E_REXW_PREFIX, R(src), RW(dst), Dummy(R(place),cl));} | ||
| 2918 | #endif | ||
| 2919 | void shrd(const Reg16& dst, const Reg16& src, const Imm8& place) {AppendInstr(I_SHRD, 0x0FAC, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), place);} | ||
| 2920 | void shrd(const Mem16& dst, const Reg16& src, const Imm8& place) {AppendInstr(I_SHRD, 0x0FAC, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), place);} | ||
| 2921 | void shrd(const Reg16& dst, const Reg16& src, const Reg8& place) {AppendInstr(I_SHRD, 0x0FAD, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(R(place),cl));} | ||
| 2922 | void shrd(const Mem16& dst, const Reg16& src, const Reg8& place) {AppendInstr(I_SHRD, 0x0FAD, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(R(place),cl));} | ||
| 2923 | void shrd(const Reg32& dst, const Reg32& src, const Imm8& place) {AppendInstr(I_SHRD, 0x0FAC, 0, R(src), RW(dst), place);} | ||
| 2924 | void shrd(const Mem32& dst, const Reg32& src, const Imm8& place) {AppendInstr(I_SHRD, 0x0FAC, 0, R(src), RW(dst), place);} | ||
| 2925 | void shrd(const Reg32& dst, const Reg32& src, const Reg8& place) {AppendInstr(I_SHRD, 0x0FAD, 0, R(src), RW(dst), Dummy(R(place),cl));} | ||
| 2926 | void shrd(const Mem32& dst, const Reg32& src, const Reg8& place) {AppendInstr(I_SHRD, 0x0FAD, 0, R(src), RW(dst), Dummy(R(place),cl));} | ||
| 2927 | #ifdef JITASM64 | ||
| 2928 | void shrd(const Reg64& dst, const Reg64& src, const Imm8& place) {AppendInstr(I_SHRD, 0x0FAC, E_REXW_PREFIX, R(src), RW(dst), place);} | ||
| 2929 | void shrd(const Mem64& dst, const Reg64& src, const Imm8& place) {AppendInstr(I_SHRD, 0x0FAC, E_REXW_PREFIX, R(src), RW(dst), place);} | ||
| 2930 | void shrd(const Reg64& dst, const Reg64& src, const Reg8& place) {AppendInstr(I_SHRD, 0x0FAD, E_REXW_PREFIX, R(src), RW(dst), Dummy(R(place),cl));} | ||
| 2931 | void shrd(const Mem64& dst, const Reg64& src, const Reg8& place) {AppendInstr(I_SHRD, 0x0FAD, E_REXW_PREFIX, R(src), RW(dst), Dummy(R(place),cl));} | ||
| 2932 | #endif | ||
| 2933 | template<class Ty> void sgdt(const MemT<Ty>& dst) {AppendInstr(I_SGDT, 0x0F01, 0, Imm8(0), W(dst));} | ||
| 2934 | template<class Ty> void sidt(const MemT<Ty>& dst) {AppendInstr(I_SIDT, 0x0F01, 0, Imm8(1), W(dst));} | ||
| 2935 | void sldt(const Reg16& dst) {AppendInstr(I_SLDT, 0x0F00, E_OPERAND_SIZE_PREFIX, Imm8(0), W(dst));} | ||
| 2936 | void sldt(const Mem16& dst) {AppendInstr(I_SLDT, 0x0F00, 0, Imm8(0), W(dst));} | ||
| 2937 | #ifdef JITASM64 | ||
| 2938 | void sldt(const Reg64& dst) {AppendInstr(I_SLDT, 0x0F00, E_REXW_PREFIX, Imm8(0), W(dst));} | ||
| 2939 | #endif | ||
| 2940 | void smsw(const Reg16& dst) {AppendInstr(I_SMSW, 0x0F01, E_OPERAND_SIZE_PREFIX, Imm8(4), W(dst));} | ||
| 2941 | void smsw(const Mem16& dst) {AppendInstr(I_SMSW, 0x0F01, 0, Imm8(4), W(dst));} | ||
| 2942 | #ifdef JITASM64 | ||
| 2943 | void smsw(const Reg64& dst) {AppendInstr(I_SMSW, 0x0F01, E_REXW_PREFIX, Imm8(4), W(dst));} | ||
| 2944 | #endif | ||
| 2945 | void stc() {AppendInstr(I_STC, 0xF9, 0);} | ||
| 2946 | void std() {AppendInstr(I_STD, 0xFD, 0);} | ||
| 2947 | void sti() {AppendInstr(I_STI, 0xFB, 0);} | ||
| 2948 | void stosb(const Reg& dst, const Reg8& src) {AppendInstr(I_STOS_B, 0xAA, 0, Dummy(R(src),al), Dummy(RW(dst),zdi));} | ||
| 2949 | void stosw(const Reg& dst, const Reg16& src) {AppendInstr(I_STOS_W, 0xAB, E_OPERAND_SIZE_PREFIX, Dummy(R(src),ax), Dummy(RW(dst),zdi));} | ||
| 2950 | void stosd(const Reg& dst, const Reg32& src) {AppendInstr(I_STOS_D, 0xAB, 0, Dummy(R(src),eax), Dummy(RW(dst),zdi));} | ||
| 2951 | #ifdef JITASM64 | ||
| 2952 | void stosq(const Reg& dst, const Reg64& src) {AppendInstr(I_STOS_Q, 0xAB, E_REXW_PREFIX, Dummy(R(src),rax), Dummy(RW(dst),zdi));} | ||
| 2953 | #endif | ||
| 2954 | void rep_stosb(const Reg& dst, const Reg8& src, const Reg& count) {AppendInstr(I_STOS_B, 0xAA, E_REP_PREFIX, Dummy(R(src),al), Dummy(RW(dst),zdi), Dummy(RW(count),zcx));} | ||
| 2955 | void rep_stosw(const Reg& dst, const Reg16& src, const Reg& count) {AppendInstr(I_STOS_W, 0xAB, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(R(src),ax), Dummy(RW(dst),zdi), Dummy(RW(count),zcx));} | ||
| 2956 | void rep_stosd(const Reg& dst, const Reg32& src, const Reg& count) {AppendInstr(I_STOS_D, 0xAB, E_REP_PREFIX, Dummy(R(src),eax), Dummy(RW(dst),zdi), Dummy(RW(count),zcx));} | ||
| 2957 | #ifdef JITASM64 | ||
| 2958 | void rep_stosq(const Reg& dst, const Reg64& src, const Reg& count) {AppendInstr(I_STOS_Q, 0xAB, E_REP_PREFIX | E_REXW_PREFIX, Dummy(R(src),rax), Dummy(RW(dst),zdi), Dummy(RW(count),zcx));} | ||
| 2959 | #endif | ||
| 2960 | void sub(const Reg8& dst, const Imm8& imm) {AppendInstr(I_SUB, 0x80, E_SPECIAL, Imm8(5), RW(dst), imm);} | ||
| 2961 | void sub(const Mem8& dst, const Imm8& imm) {AppendInstr(I_SUB, 0x80, 0, Imm8(5), RW(dst), imm);} | ||
| 2962 | void sub(const Reg16& dst, const Imm16& imm) {AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(5), RW(dst), detail::ImmXor8(imm));} | ||
| 2963 | void sub(const Mem16& dst, const Imm16& imm) {AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), detail::ImmXor8(imm));} | ||
| 2964 | void sub(const Reg32& dst, const Imm32& imm) {AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(5), RW(dst), detail::ImmXor8(imm));} | ||
| 2965 | void sub(const Mem32& dst, const Imm32& imm) {AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(5), RW(dst), detail::ImmXor8(imm));} | ||
| 2966 | void sub(const Reg8& dst, const Reg8& src) {AppendInstr(I_SUB, 0x2A, 0, RW(dst), R(src));} | ||
| 2967 | void sub(const Mem8& dst, const Reg8& src) {AppendInstr(I_SUB, 0x28, 0, R(src), RW(dst));} | ||
| 2968 | void sub(const Reg8& dst, const Mem8& src) {AppendInstr(I_SUB, 0x2A, 0, RW(dst), R(src));} | ||
| 2969 | void sub(const Reg16& dst, const Reg16& src) {AppendInstr(I_SUB, 0x2B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2970 | void sub(const Mem16& dst, const Reg16& src) {AppendInstr(I_SUB, 0x29, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));} | ||
| 2971 | void sub(const Reg16& dst, const Mem16& src) {AppendInstr(I_SUB, 0x2B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 2972 | void sub(const Reg32& dst, const Reg32& src) {AppendInstr(I_SUB, 0x2B, 0, RW(dst), R(src));} | ||
| 2973 | void sub(const Mem32& dst, const Reg32& src) {AppendInstr(I_SUB, 0x29, 0, R(src), RW(dst));} | ||
| 2974 | void sub(const Reg32& dst, const Mem32& src) {AppendInstr(I_SUB, 0x2B, 0, RW(dst), R(src));} | ||
| 2975 | #ifdef JITASM64 | ||
| 2976 | ✗ | void sub(const Reg64& dst, const Imm32& imm) {AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(5), RW(dst), detail::ImmXor8(imm));} | |
| 2977 | void sub(const Mem64& dst, const Imm32& imm) {AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(5), RW(dst), detail::ImmXor8(imm));} | ||
| 2978 | ✗ | void sub(const Reg64& dst, const Reg64& src) {AppendInstr(I_SUB, 0x2B, E_REXW_PREFIX, RW(dst), R(src));} | |
| 2979 | void sub(const Mem64& dst, const Reg64& src) {AppendInstr(I_SUB, 0x29, E_REXW_PREFIX, R(src), RW(dst));} | ||
| 2980 | ✗ | void sub(const Reg64& dst, const Mem64& src) {AppendInstr(I_SUB, 0x2B, E_REXW_PREFIX, RW(dst), R(src));} | |
| 2981 | #endif | ||
| 2982 | #ifndef JITASM64 | ||
| 2983 | void sysenter() {AppendInstr(I_SYSENTER, 0x0F34, 0);} | ||
| 2984 | void sysexit() {AppendInstr(I_SYSEXIT, 0x0F35, 0);} | ||
| 2985 | #else | ||
| 2986 | void swapgs() {AppendInstr(I_SWAPGS, 0x0F01F8, 0);} // 0F 01 /7 | ||
| 2987 | void syscall() {AppendInstr(I_SYSCALL, 0x0F05, 0);} | ||
| 2988 | void sysret() {AppendInstr(I_SYSRET, 0x0F07, 0);} | ||
| 2989 | #endif | ||
| 2990 | void test(const Reg8& src1, const Imm8& src2) {AppendInstr(I_TEST, 0xF6, E_SPECIAL, Imm8(0), R(src1), R(src2));} | ||
| 2991 | void test(const Mem8& src1, const Imm8& src2) {AppendInstr(I_TEST, 0xF6, 0, Imm8(0), R(src1), R(src2));} | ||
| 2992 | void test(const Reg16& src1, const Imm16& src2) {AppendInstr(I_TEST, 0xF7, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(0), R(src1), R(src2));} | ||
| 2993 | void test(const Mem16& src1, const Imm16& src2) {AppendInstr(I_TEST, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(0), R(src1), R(src2));} | ||
| 2994 | void test(const Reg32& src1, const Imm32& src2) {AppendInstr(I_TEST, 0xF7, E_SPECIAL, Imm8(0), R(src1), R(src2));} | ||
| 2995 | void test(const Mem32& src1, const Imm32& src2) {AppendInstr(I_TEST, 0xF7, 0, Imm8(0), R(src1), R(src2));} | ||
| 2996 | void test(const Reg8& src1, const Reg8& src2) {AppendInstr(I_TEST, 0x84, 0, R(src1), R(src2));} | ||
| 2997 | void test(const Mem8& src1, const Reg8& src2) {AppendInstr(I_TEST, 0x84, 0, R(src2), R(src1));} | ||
| 2998 | void test(const Reg16& src1, const Reg16& src2) {AppendInstr(I_TEST, 0x85, E_OPERAND_SIZE_PREFIX, R(src1), R(src2));} | ||
| 2999 | void test(const Mem16& src1, const Reg16& src2) {AppendInstr(I_TEST, 0x85, E_OPERAND_SIZE_PREFIX, R(src2), R(src1));} | ||
| 3000 | void test(const Reg32& src1, const Reg32& src2) {AppendInstr(I_TEST, 0x85, 0, R(src1), R(src2));} | ||
| 3001 | void test(const Mem32& src1, const Reg32& src2) {AppendInstr(I_TEST, 0x85, 0, R(src2), R(src1));} | ||
| 3002 | #ifdef JITASM64 | ||
| 3003 | void test(const Reg64& src1, const Imm32& src2) {AppendInstr(I_TEST, 0xF7, E_REXW_PREFIX | E_SPECIAL, Imm8(0), R(src1), R(src2));} | ||
| 3004 | void test(const Mem64& src1, const Imm32& src2) {AppendInstr(I_TEST, 0xF7, E_REXW_PREFIX, Imm8(0), R(src1), R(src2));} | ||
| 3005 | void test(const Reg64& src1, const Reg64& src2) {AppendInstr(I_TEST, 0x85, E_REXW_PREFIX, R(src1), R(src2));} | ||
| 3006 | void test(const Mem64& src1, const Reg64& src2) {AppendInstr(I_TEST, 0x85, E_REXW_PREFIX, R(src2), R(src1));} | ||
| 3007 | #endif | ||
| 3008 | void ud2() {AppendInstr(I_UD2, 0x0F0B, 0);} | ||
| 3009 | void verr(const Reg16& src) {AppendInstr(I_VERR, 0x0F00, 0, Imm8(4), R(src));} | ||
| 3010 | void verr(const Mem16& src) {AppendInstr(I_VERR, 0x0F00, 0, Imm8(4), R(src));} | ||
| 3011 | void verw(const Reg16& src) {AppendInstr(I_VERW, 0x0F00, 0, Imm8(5), R(src));} | ||
| 3012 | void verw(const Mem16& src) {AppendInstr(I_VERW, 0x0F00, 0, Imm8(5), R(src));} | ||
| 3013 | void wait() {AppendInstr(I_WAIT, 0x9B, 0);} | ||
| 3014 | void wbinvd() {AppendInstr(I_WBINVD, 0x0F09, 0);} | ||
| 3015 | void wrmsr() {AppendInstr(I_WRMSR, 0x0F30, 0, Dummy(R(ecx)), Dummy(R(edx)), Dummy(R(eax)));} | ||
| 3016 | void xadd(const Reg8& dst, const Reg8& src) {AppendInstr(I_XADD, 0x0FC0, 0, RW(src), RW(dst));} | ||
| 3017 | void xadd(const Mem8& dst, const Reg8& src) {AppendInstr(I_XADD, 0x0FC0, 0, RW(src), RW(dst));} | ||
| 3018 | void xadd(const Reg16& dst, const Reg16& src) {AppendInstr(I_XADD, 0x0FC1, E_OPERAND_SIZE_PREFIX, RW(src), RW(dst));} | ||
| 3019 | void xadd(const Mem16& dst, const Reg16& src) {AppendInstr(I_XADD, 0x0FC1, E_OPERAND_SIZE_PREFIX, RW(src), RW(dst));} | ||
| 3020 | void xadd(const Reg32& dst, const Reg32& src) {AppendInstr(I_XADD, 0x0FC1, 0, RW(src), RW(dst));} | ||
| 3021 | void xadd(const Mem32& dst, const Reg32& src) {AppendInstr(I_XADD, 0x0FC1, 0, RW(src), RW(dst));} | ||
| 3022 | #ifdef JITASM64 | ||
| 3023 | void xadd(const Reg64& dst, const Reg64& src) {AppendInstr(I_XADD, 0x0FC1, E_REXW_PREFIX, RW(src), RW(dst));} | ||
| 3024 | void xadd(const Mem64& dst, const Reg64& src) {AppendInstr(I_XADD, 0x0FC1, E_REXW_PREFIX, RW(src), RW(dst));} | ||
| 3025 | #endif | ||
| 3026 | void xchg(const Reg8& dst, const Reg8& src) {AppendInstr(I_XCHG, 0x86, 0, RW(dst), RW(src));} | ||
| 3027 | void xchg(const Mem8& dst, const Reg8& src) {AppendInstr(I_XCHG, 0x86, 0, RW(src), RW(dst));} | ||
| 3028 | void xchg(const Reg8& dst, const Mem8& src) {AppendInstr(I_XCHG, 0x86, 0, RW(dst), RW(src));} | ||
| 3029 | void xchg(const Reg16& dst, const Reg16& src) {AppendInstr(I_XCHG, 0x87, E_OPERAND_SIZE_PREFIX | E_SPECIAL, RW(dst), RW(src));} | ||
| 3030 | void xchg(const Mem16& dst, const Reg16& src) {AppendInstr(I_XCHG, 0x87, E_OPERAND_SIZE_PREFIX, RW(src), RW(dst));} | ||
| 3031 | void xchg(const Reg16& dst, const Mem16& src) {AppendInstr(I_XCHG, 0x87, E_OPERAND_SIZE_PREFIX, RW(dst), RW(src));} | ||
| 3032 | void xchg(const Reg32& dst, const Reg32& src) {AppendInstr(I_XCHG, 0x87, E_SPECIAL, RW(dst), RW(src));} | ||
| 3033 | void xchg(const Mem32& dst, const Reg32& src) {AppendInstr(I_XCHG, 0x87, 0, RW(src), RW(dst));} | ||
| 3034 | void xchg(const Reg32& dst, const Mem32& src) {AppendInstr(I_XCHG, 0x87, 0, RW(dst), RW(src));} | ||
| 3035 | #ifdef JITASM64 | ||
| 3036 | ✗ | void xchg(const Reg64& dst, const Reg64& src) {AppendInstr(I_XCHG, 0x87, E_REXW_PREFIX | E_SPECIAL, RW(dst), RW(src));} | |
| 3037 | void xchg(const Mem64& dst, const Reg64& src) {AppendInstr(I_XCHG, 0x87, E_REXW_PREFIX, RW(src), RW(dst));} | ||
| 3038 | void xchg(const Reg64& dst, const Mem64& src) {AppendInstr(I_XCHG, 0x87, E_REXW_PREFIX, RW(dst), RW(src));} | ||
| 3039 | #endif | ||
| 3040 | void xgetbv() {AppendInstr(I_XGETBV, 0x0F01D0, 0, Dummy(R(ecx)), Dummy(W(edx)), Dummy(W(eax)));} | ||
| 3041 | void xlatb() {AppendInstr(I_XLATB, 0xD7, 0, Dummy(RW(al)), Dummy(R(ebx)));} | ||
| 3042 | void xor_(const Reg8& dst, const Imm8& imm) {AppendInstr(I_XOR, 0x80, E_SPECIAL, Imm8(6), RW(dst), imm);} | ||
| 3043 | void xor_(const Mem8& dst, const Imm8& imm) {AppendInstr(I_XOR, 0x80, 0, Imm8(6), RW(dst), imm);} | ||
| 3044 | void xor_(const Reg16& dst, const Imm16& imm) {AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(6), RW(dst), detail::ImmXor8(imm));} | ||
| 3045 | void xor_(const Mem16& dst, const Imm16& imm) {AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(6), RW(dst), detail::ImmXor8(imm));} | ||
| 3046 | void xor_(const Reg32& dst, const Imm32& imm) {AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(6), RW(dst), detail::ImmXor8(imm));} | ||
| 3047 | void xor_(const Mem32& dst, const Imm32& imm) {AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(6), RW(dst), detail::ImmXor8(imm));} | ||
| 3048 | void xor_(const Reg8& dst, const Reg8& src) {AppendInstr(I_XOR, 0x32, 0, RW(dst), R(src));} | ||
| 3049 | void xor_(const Mem8& dst, const Reg8& src) {AppendInstr(I_XOR, 0x30, 0, R(src), RW(dst));} | ||
| 3050 | void xor_(const Reg8& dst, const Mem8& src) {AppendInstr(I_XOR, 0x32, 0, RW(dst), R(src));} | ||
| 3051 | void xor_(const Reg16& dst, const Reg16& src) {AppendInstr(I_XOR, 0x33, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 3052 | void xor_(const Mem16& dst, const Reg16& src) {AppendInstr(I_XOR, 0x31, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));} | ||
| 3053 | void xor_(const Reg16& dst, const Mem16& src) {AppendInstr(I_XOR, 0x33, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 3054 | void xor_(const Reg32& dst, const Reg32& src) {AppendInstr(I_XOR, 0x33, 0, RW(dst), R(src));} | ||
| 3055 | void xor_(const Mem32& dst, const Reg32& src) {AppendInstr(I_XOR, 0x31, 0, R(src), RW(dst));} | ||
| 3056 | void xor_(const Reg32& dst, const Mem32& src) {AppendInstr(I_XOR, 0x33, 0, RW(dst), R(src));} | ||
| 3057 | #ifdef JITASM64 | ||
| 3058 | void xor_(const Reg64& dst, const Imm32& imm) {AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(6), RW(dst), detail::ImmXor8(imm));} | ||
| 3059 | void xor_(const Mem64& dst, const Imm32& imm) {AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(6), RW(dst), detail::ImmXor8(imm));} | ||
| 3060 | void xor_(const Reg64& dst, const Reg64& src) {AppendInstr(I_XOR, 0x33, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 3061 | void xor_(const Mem64& dst, const Reg64& src) {AppendInstr(I_XOR, 0x31, E_REXW_PREFIX, R(src), RW(dst));} | ||
| 3062 | void xor_(const Reg64& dst, const Mem64& src) {AppendInstr(I_XOR, 0x33, E_REXW_PREFIX, RW(dst), R(src));} | ||
| 3063 | #endif | ||
| 3064 | |||
| 3065 | // x87 Floating-Point Instructions | ||
| 3066 | void f2xm1() {AppendInstr(I_F2XM1, 0xD9F0, 0);} | ||
| 3067 | void fabs() {AppendInstr(I_FABS, 0xD9E1, 0);} | ||
| 3068 | void fadd(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FADD, 0xD8C0, 0, src); avoid_unused_warn(dst);} | ||
| 3069 | void fadd(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FADD, 0xDCC0, 0, dst); avoid_unused_warn(src);} | ||
| 3070 | void fadd(const Mem32& dst) {AppendInstr(I_FADD, 0xD8, 0, Imm8(0), dst);} | ||
| 3071 | void fadd(const Mem64& dst) {AppendInstr(I_FADD, 0xDC, 0, Imm8(0), dst);} | ||
| 3072 | void faddp() {AppendInstr(I_FADDP, 0xDEC1, 0);} | ||
| 3073 | void faddp(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FADDP, 0xDEC0, 0, dst); avoid_unused_warn(src);} | ||
| 3074 | void fiadd(const Mem16& dst) {AppendInstr(I_FIADD, 0xDE, 0, Imm8(0), dst);} | ||
| 3075 | void fiadd(const Mem32& dst) {AppendInstr(I_FIADD, 0xDA, 0, Imm8(0), dst);} | ||
| 3076 | void fbld(const Mem80& dst) {AppendInstr(I_FBLD, 0xDF, 0, Imm8(4), dst);} | ||
| 3077 | void fbstp(const Mem80& dst) {AppendInstr(I_FBSTP, 0xDF, 0, Imm8(6), dst);} | ||
| 3078 | void fchs() {AppendInstr(I_FCHS, 0xD9E0, 0);} | ||
| 3079 | void fclex() {AppendInstr(I_FCLEX, 0x9BDBE2, 0);} | ||
| 3080 | void fnclex() {AppendInstr(I_FNCLEX, 0xDBE2, 0);} | ||
| 3081 | void fcmovb(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDAC0, 0, src); avoid_unused_warn(dst);} | ||
| 3082 | void fcmovbe(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDAD0, 0, src); avoid_unused_warn(dst);} | ||
| 3083 | void fcmove(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDAC8, 0, src); avoid_unused_warn(dst);} | ||
| 3084 | void fcmovnb(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDBC0, 0, src); avoid_unused_warn(dst);} | ||
| 3085 | void fcmovnbe(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDBD0, 0, src); avoid_unused_warn(dst);} | ||
| 3086 | void fcmovne(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDBC8, 0, src); avoid_unused_warn(dst);} | ||
| 3087 | void fcmovnu(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDBD8, 0, src); avoid_unused_warn(dst);} | ||
| 3088 | void fcmovu(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDAD8, 0, src); avoid_unused_warn(dst);} | ||
| 3089 | void fcom() {AppendInstr(I_FCOM, 0xD8D1, 0);} | ||
| 3090 | void fcom(const FpuReg& dst) {AppendInstr(I_FCOM, 0xD8D0, 0, dst);} | ||
| 3091 | void fcom(const Mem32& dst) {AppendInstr(I_FCOM, 0xD8, 0, Imm8(2), dst);} | ||
| 3092 | void fcom(const Mem64& dst) {AppendInstr(I_FCOM, 0xDC, 0, Imm8(2), dst);} | ||
| 3093 | void fcomp() {AppendInstr(I_FCOMP, 0xD8D9, 0);} | ||
| 3094 | void fcomp(const FpuReg& dst) {AppendInstr(I_FCOMP, 0xD8D8, 0, dst);} | ||
| 3095 | void fcomp(const Mem32& dst) {AppendInstr(I_FCOMP, 0xD8, 0, Imm8(3), dst);} | ||
| 3096 | void fcomp(const Mem64& dst) {AppendInstr(I_FCOMP, 0xDC, 0, Imm8(3), dst);} | ||
| 3097 | void fcompp() {AppendInstr(I_FCOMPP, 0xDED9, 0);} | ||
| 3098 | void fcomi(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCOMI, 0xDBF0, 0, src); avoid_unused_warn(dst);} | ||
| 3099 | void fcomip(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCOMIP, 0xDFF0, 0, src); avoid_unused_warn(dst);} | ||
| 3100 | void fcos() {AppendInstr(I_FCOS, 0xD9FF, 0);} | ||
| 3101 | void fdecstp() {AppendInstr(I_FDECSTP, 0xD9F6, 0);} | ||
| 3102 | void fdiv(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FDIV, 0xD8F0, 0, src); avoid_unused_warn(dst);} | ||
| 3103 | void fdiv(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FDIV, 0xDCF8, 0, dst); avoid_unused_warn(src);} | ||
| 3104 | void fdiv(const Mem32& dst) {AppendInstr(I_FDIV, 0xD8, 0, Imm8(6), dst);} | ||
| 3105 | void fdiv(const Mem64& dst) {AppendInstr(I_FDIV, 0xDC, 0, Imm8(6), dst);} | ||
| 3106 | void fdivp() {AppendInstr(I_FDIVP, 0xDEF9, 0);} | ||
| 3107 | void fdivp(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FDIVP, 0xDEF8, 0, dst); avoid_unused_warn(src);} | ||
| 3108 | void fidiv(const Mem16& dst) {AppendInstr(I_FIDIV, 0xDE, 0, Imm8(6), dst);} | ||
| 3109 | void fidiv(const Mem32& dst) {AppendInstr(I_FIDIV, 0xDA, 0, Imm8(6), dst);} | ||
| 3110 | void fdivr(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FDIVR, 0xD8F8, 0, src); avoid_unused_warn(dst);} | ||
| 3111 | void fdivr(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FDIVR, 0xDCF0, 0, dst); avoid_unused_warn(src);} | ||
| 3112 | void fdivr(const Mem32& dst) {AppendInstr(I_FDIVR, 0xD8, 0, Imm8(7), dst);} | ||
| 3113 | void fdivr(const Mem64& dst) {AppendInstr(I_FDIVR, 0xDC, 0, Imm8(7), dst);} | ||
| 3114 | void fdivrp() {AppendInstr(I_FDIVRP, 0xDEF1, 0);} | ||
| 3115 | void fdivrp(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FDIVRP, 0xDEF0, 0, dst); avoid_unused_warn(src);} | ||
| 3116 | void fidivr(const Mem16& dst) {AppendInstr(I_FIDIVR, 0xDE, 0, Imm8(7), dst);} | ||
| 3117 | void fidivr(const Mem32& dst) {AppendInstr(I_FIDIVR, 0xDA, 0, Imm8(7), dst);} | ||
| 3118 | void ffree(const FpuReg& dst) {AppendInstr(I_FFREE, 0xDDC0, 0, dst);} | ||
| 3119 | void ficom(const Mem16& dst) {AppendInstr(I_FICOM, 0xDE, 0, Imm8(2), dst);} | ||
| 3120 | void ficom(const Mem32& dst) {AppendInstr(I_FICOM, 0xDA, 0, Imm8(2), dst);} | ||
| 3121 | void ficomp(const Mem16& dst) {AppendInstr(I_FICOMP, 0xDE, 0, Imm8(3), dst);} | ||
| 3122 | void ficomp(const Mem32& dst) {AppendInstr(I_FICOMP, 0xDA, 0, Imm8(3), dst);} | ||
| 3123 | void fild(const Mem16& dst) {AppendInstr(I_FILD, 0xDF, 0, Imm8(0), dst);} | ||
| 3124 | void fild(const Mem32& dst) {AppendInstr(I_FILD, 0xDB, 0, Imm8(0), dst);} | ||
| 3125 | void fild(const Mem64& dst) {AppendInstr(I_FILD, 0xDF, 0, Imm8(5), dst);} | ||
| 3126 | void fincstp() {AppendInstr(I_FINCSTP, 0xD9F7, 0);} | ||
| 3127 | void finit() {AppendInstr(I_FINIT, 0x9BDBE3, 0);} | ||
| 3128 | void fninit() {AppendInstr(I_FNINIT, 0xDBE3, 0);} | ||
| 3129 | void fist(const Mem16& dst) {AppendInstr(I_FIST, 0xDF, 0, Imm8(2), dst);} | ||
| 3130 | void fist(const Mem32& dst) {AppendInstr(I_FIST, 0xDB, 0, Imm8(2), dst);} | ||
| 3131 | void fistp(const Mem16& dst) {AppendInstr(I_FISTP, 0xDF, 0, Imm8(3), dst);} | ||
| 3132 | void fistp(const Mem32& dst) {AppendInstr(I_FISTP, 0xDB, 0, Imm8(3), dst);} | ||
| 3133 | void fistp(const Mem64& dst) {AppendInstr(I_FISTP, 0xDF, 0, Imm8(7), dst);} | ||
| 3134 | void fisttp(const Mem16& dst) {AppendInstr(I_FISTP, 0xDF, 0, Imm8(1), dst);} | ||
| 3135 | void fisttp(const Mem32& dst) {AppendInstr(I_FISTP, 0xDB, 0, Imm8(1), dst);} | ||
| 3136 | void fisttp(const Mem64& dst) {AppendInstr(I_FISTP, 0xDD, 0, Imm8(1), dst);} | ||
| 3137 | void fld(const Mem32& src) {AppendInstr(I_FLD, 0xD9, 0, Imm8(0), src);} | ||
| 3138 | void fld(const Mem64& src) {AppendInstr(I_FLD, 0xDD, 0, Imm8(0), src);} | ||
| 3139 | void fld(const Mem80& src) {AppendInstr(I_FLD, 0xDB, 0, Imm8(5), src);} | ||
| 3140 | void fld(const FpuReg& src) {AppendInstr(I_FLD, 0xD9C0, 0, src);} | ||
| 3141 | void fld1() {AppendInstr(I_FLD1, 0xD9E8, 0);} | ||
| 3142 | void fldcw(const Mem16& src) {AppendInstr(I_FLDCW, 0xD9, 0, Imm8(5), src);} | ||
| 3143 | void fldenv(const Mem224& src) {AppendInstr(I_FLDENV, 0xD9, 0, Imm8(4), src);} | ||
| 3144 | void fldl2e() {AppendInstr(I_FLDL2E, 0xD9EA, 0);} | ||
| 3145 | void fldl2t() {AppendInstr(I_FLDL2T, 0xD9E9, 0);} | ||
| 3146 | void fldlg2() {AppendInstr(I_FLDLG2, 0xD9EC, 0);} | ||
| 3147 | void fldln2() {AppendInstr(I_FLDLN2, 0xD9ED, 0);} | ||
| 3148 | void fldpi() {AppendInstr(I_FLDPI, 0xD9EB, 0);} | ||
| 3149 | void fldz() {AppendInstr(I_FLDZ, 0xD9EE, 0);} | ||
| 3150 | void fmul(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FMUL, 0xD8C8, 0, src); avoid_unused_warn(dst);} | ||
| 3151 | void fmul(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FMUL, 0xDCC8, 0, dst); avoid_unused_warn(src);} | ||
| 3152 | void fmul(const Mem32& dst) {AppendInstr(I_FMUL, 0xD8, 0, Imm8(1), dst);} | ||
| 3153 | void fmul(const Mem64& dst) {AppendInstr(I_FMUL, 0xDC, 0, Imm8(1), dst);} | ||
| 3154 | void fmulp() {AppendInstr(I_FMULP, 0xDEC9, 0);} | ||
| 3155 | void fmulp(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FMULP, 0xDEC8, 0, dst); avoid_unused_warn(src);} | ||
| 3156 | void fimul(const Mem16& dst) {AppendInstr(I_FIMUL, 0xDE, 0, Imm8(1), dst);} | ||
| 3157 | void fimul(const Mem32& dst) {AppendInstr(I_FIMUL, 0xDA, 0, Imm8(1), dst);} | ||
| 3158 | void fnop() {AppendInstr(I_FNOP, 0xD9D0, 0);} | ||
| 3159 | void fpatan() {AppendInstr(I_FPATAN, 0xD9F3, 0);} | ||
| 3160 | void fprem() {AppendInstr(I_FPREM, 0xD9F8, 0);} | ||
| 3161 | void fprem1() {AppendInstr(I_FPREM1, 0xD9F5, 0);} | ||
| 3162 | void fptan() {AppendInstr(I_FPTAN, 0xD9F2, 0);} | ||
| 3163 | void frndint() {AppendInstr(I_FRNDINT, 0xD9FC, 0);} | ||
| 3164 | void frstor(const Mem864& src) {AppendInstr(I_FRSTOR, 0xDD, 0, Imm8(4), src);} | ||
| 3165 | void fsave(const Mem864& dst) {AppendInstr(I_FSAVE, 0x9BDD, 0, Imm8(6), dst);} | ||
| 3166 | void fnsave(const Mem864& dst) {AppendInstr(I_FNSAVE, 0xDD, 0, Imm8(6), dst);} | ||
| 3167 | void fscale() {AppendInstr(I_FSCALE, 0xD9FD, 0);} | ||
| 3168 | void fsin() {AppendInstr(I_FSIN, 0xD9FE, 0);} | ||
| 3169 | void fsincos() {AppendInstr(I_FSINCOS, 0xD9FB, 0);} | ||
| 3170 | void fsqrt() {AppendInstr(I_FSQRT, 0xD9FA, 0);} | ||
| 3171 | void fst(const Mem32& dst) {AppendInstr(I_FST, 0xD9, 0, Imm8(2), dst);} | ||
| 3172 | void fst(const Mem64& dst) {AppendInstr(I_FST, 0xDD, 0, Imm8(2), dst);} | ||
| 3173 | void fst(const FpuReg& dst) {AppendInstr(I_FST, 0xDDD0, 0, dst);} | ||
| 3174 | void fstp(const FpuReg& dst) {AppendInstr(I_FSTP, 0xDDD8, 0, dst);} | ||
| 3175 | void fstp(const Mem32& dst) {AppendInstr(I_FSTP, 0xD9, 0, Imm8(3), dst);} | ||
| 3176 | void fstp(const Mem64& dst) {AppendInstr(I_FSTP, 0xDD, 0, Imm8(3), dst);} | ||
| 3177 | void fstp(const Mem80& dst) {AppendInstr(I_FSTP, 0xDB, 0, Imm8(7), dst);} | ||
| 3178 | void fstcw(const Mem16& dst) {AppendInstr(I_FSTCW, 0x9BD9, 0, Imm8(7), dst);} | ||
| 3179 | void fnstcw(const Mem16& dst) {AppendInstr(I_FNSTCW, 0xD9, 0, Imm8(7), dst);} | ||
| 3180 | void fstenv(const Mem224& dst) {AppendInstr(I_FSTENV, 0x9BD9, 0, Imm8(6), dst);} | ||
| 3181 | void fnstenv(const Mem224& dst) {AppendInstr(I_FNSTENV, 0xD9, 0, Imm8(6), dst);} | ||
| 3182 | void fstsw(const Mem16& dst) {AppendInstr(I_FSTSW, 0x9BDD, 0, Imm8(7), dst);} | ||
| 3183 | void fstsw(const Reg16& dst) {AppendInstr(I_FSTSW, 0x9BDFE0, 0, Dummy(W(dst), ax));} | ||
| 3184 | void fnstsw(const Mem16& dst) {AppendInstr(I_FNSTSW, 0xDD, 0, Imm8(7), dst);} | ||
| 3185 | void fnstsw(const Reg16& dst) {AppendInstr(I_FNSTSW, 0xDFE0, 0, Dummy(W(dst), ax));} | ||
| 3186 | void fsub(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FSUB, 0xD8E0, 0, src); avoid_unused_warn(dst);} | ||
| 3187 | void fsub(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FSUB, 0xDCE8, 0, dst); avoid_unused_warn(src);} | ||
| 3188 | void fsub(const Mem32& dst) {AppendInstr(I_FSUB, 0xD8, 0, Imm8(4), dst);} | ||
| 3189 | void fsub(const Mem64& dst) {AppendInstr(I_FSUB, 0xDC, 0, Imm8(4), dst);} | ||
| 3190 | void fsubp() {AppendInstr(I_FSUBP, 0xDEE9, 0);} | ||
| 3191 | void fsubp(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FSUBP, 0xDEE8, 0, dst); avoid_unused_warn(src);} | ||
| 3192 | void fisub(const Mem16& dst) {AppendInstr(I_FISUB, 0xDE, 0, Imm8(4), dst);} | ||
| 3193 | void fisub(const Mem32& dst) {AppendInstr(I_FISUB, 0xDA, 0, Imm8(4), dst);} | ||
| 3194 | void fsubr(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FSUBR, 0xD8E8, 0, src); avoid_unused_warn(dst);} | ||
| 3195 | void fsubr(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FSUBR, 0xDCE0, 0, dst); avoid_unused_warn(src);} | ||
| 3196 | void fsubr(const Mem32& dst) {AppendInstr(I_FSUBR, 0xD8, 0, Imm8(5), dst);} | ||
| 3197 | void fsubr(const Mem64& dst) {AppendInstr(I_FSUBR, 0xDC, 0, Imm8(5), dst);} | ||
| 3198 | void fsubrp() {AppendInstr(I_FSUBRP, 0xDEE1, 0);} | ||
| 3199 | void fsubrp(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FSUBRP, 0xDEE0, 0, dst); avoid_unused_warn(src);} | ||
| 3200 | void fisubr(const Mem16& dst) {AppendInstr(I_FISUBR, 0xDE, 0, Imm8(5), dst);} | ||
| 3201 | void fisubr(const Mem32& dst) {AppendInstr(I_FISUBR, 0xDA, 0, Imm8(5), dst);} | ||
| 3202 | void ftst() {AppendInstr(I_FTST, 0xD9E4, 0);} | ||
| 3203 | void fucom() {AppendInstr(I_FUCOM, 0xDDE1, 0);} | ||
| 3204 | void fucom(const FpuReg& dst) {AppendInstr(I_FUCOM, 0xDDE0, 0, dst);} | ||
| 3205 | void fucomp() {AppendInstr(I_FUCOMP, 0xDDE9, 0);} | ||
| 3206 | void fucomp(const FpuReg& dst) {AppendInstr(I_FUCOMP, 0xDDE8, 0, dst);} | ||
| 3207 | void fucompp() {AppendInstr(I_FUCOMPP, 0xDAE9, 0);} | ||
| 3208 | void fucomi(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FUCOMI, 0xDBE8, 0, src); avoid_unused_warn(dst);} | ||
| 3209 | void fucomip(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FUCOMIP, 0xDFE8, 0, src); avoid_unused_warn(dst);} | ||
| 3210 | void fwait() {wait();} | ||
| 3211 | void fxam() {AppendInstr(I_FXAM, 0xD9E5, 0);} | ||
| 3212 | void fxch() {AppendInstr(I_FXCH, 0xD9C9, 0);} | ||
| 3213 | void fxch(const FpuReg& dst) {AppendInstr(I_FXCH, 0xD9C8, 0, dst);} | ||
| 3214 | void fxrstor(const Mem4096& src) {AppendInstr(I_FXRSTOR, 0x0FAE, 0, Imm8(1), src);} | ||
| 3215 | void fxsave(const Mem4096& dst) {AppendInstr(I_FXSAVE, 0x0FAE, 0, Imm8(0), dst);} | ||
| 3216 | void fxtract() {AppendInstr(I_FXTRACT, 0xD9F4, 0);} | ||
| 3217 | void fyl2x() {AppendInstr(I_FYL2X, 0xD9F1, 0);} | ||
| 3218 | void fyl2xp1() {AppendInstr(I_FYL2XP1, 0xD9F9, 0);} | ||
| 3219 | |||
| 3220 | // MMX | ||
| 3221 | void emms() {AppendInstr(I_EMMS, 0x0F77, 0);} | ||
| 3222 | void movd(const MmxReg& dst, const Reg32& src) {AppendInstr(I_MOVD, 0x0F6E, 0, W(dst), R(src));} | ||
| 3223 | void movd(const MmxReg& dst, const Mem32& src) {AppendInstr(I_MOVD, 0x0F6E, 0, W(dst), R(src));} | ||
| 3224 | void movd(const Reg32& dst, const MmxReg& src) {AppendInstr(I_MOVD, 0x0F7E, 0, R(src), W(dst));} | ||
| 3225 | void movd(const Mem32& dst, const MmxReg& src) {AppendInstr(I_MOVD, 0x0F7E, 0, R(src), W(dst));} | ||
| 3226 | #ifdef JITASM64 | ||
| 3227 | void movd(const MmxReg& dst, const Reg64& src) {AppendInstr(I_MOVD, 0x0F6E, E_REXW_PREFIX, W(dst), R(src));} | ||
| 3228 | void movd(const Reg64& dst, const MmxReg& src) {AppendInstr(I_MOVD, 0x0F7E, E_REXW_PREFIX, R(src), W(dst));} | ||
| 3229 | #endif | ||
| 3230 | ✗ | void movq(const MmxReg& dst, const Mem64& src) {AppendInstr(I_MOVQ, 0x0F6F, 0, W(dst), R(src));} | |
| 3231 | ✗ | void movq(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_MOVQ, 0x0F7F, 0, R(src), W(dst));} | |
| 3232 | ✗ | void movq(const Mem64& dst, const MmxReg& src) {AppendInstr(I_MOVQ, 0x0F7F, 0, R(src), W(dst));} | |
| 3233 | #ifdef JITASM64 | ||
| 3234 | void movq(const MmxReg& dst, const Reg64& src) {movd(dst, src);} | ||
| 3235 | void movq(const Reg64& dst, const MmxReg& src) {movd(dst, src);} | ||
| 3236 | #endif | ||
| 3237 | void packsswb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PACKSSWB, 0x0F63, 0, RW(dst), R(src));} | ||
| 3238 | void packsswb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PACKSSWB, 0x0F63, 0, RW(dst), R(src));} | ||
| 3239 | void packssdw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PACKSSDW, 0x0F6B, 0, RW(dst), R(src));} | ||
| 3240 | void packssdw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PACKSSDW, 0x0F6B, 0, RW(dst), R(src));} | ||
| 3241 | void packuswb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PACKUSWB, 0x0F67, 0, RW(dst), R(src));} | ||
| 3242 | void packuswb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PACKUSWB, 0x0F67, 0, RW(dst), R(src));} | ||
| 3243 | void paddb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDB, 0x0FFC, 0, RW(dst), R(src));} | ||
| 3244 | void paddb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDB, 0x0FFC, 0, RW(dst), R(src));} | ||
| 3245 | void paddw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDW, 0x0FFD, 0, RW(dst), R(src));} | ||
| 3246 | void paddw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDW, 0x0FFD, 0, RW(dst), R(src));} | ||
| 3247 | void paddd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDD, 0x0FFE, 0, RW(dst), R(src));} | ||
| 3248 | void paddd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDD, 0x0FFE, 0, RW(dst), R(src));} | ||
| 3249 | void paddsb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDSB, 0x0FEC, 0, RW(dst), R(src));} | ||
| 3250 | void paddsb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDSB, 0x0FEC, 0, RW(dst), R(src));} | ||
| 3251 | void paddsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDSW, 0x0FED, 0, RW(dst), R(src));} | ||
| 3252 | void paddsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDSW, 0x0FED, 0, RW(dst), R(src));} | ||
| 3253 | void paddusb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDUSB, 0x0FDC, 0, RW(dst), R(src));} | ||
| 3254 | void paddusb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDUSB, 0x0FDC, 0, RW(dst), R(src));} | ||
| 3255 | void paddusw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDUSW, 0x0FDD, 0, RW(dst), R(src));} | ||
| 3256 | void paddusw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDUSW, 0x0FDD, 0, RW(dst), R(src));} | ||
| 3257 | void pand(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PAND, 0x0FDB, 0, RW(dst), R(src));} | ||
| 3258 | void pand(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PAND, 0x0FDB, 0, RW(dst), R(src));} | ||
| 3259 | void pandn(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PANDN, 0x0FDF, 0, RW(dst), R(src));} | ||
| 3260 | void pandn(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PANDN, 0x0FDF, 0, RW(dst), R(src));} | ||
| 3261 | void pcmpeqb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PCMPEQB, 0x0F74, 0, RW(dst), R(src));} | ||
| 3262 | void pcmpeqb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PCMPEQB, 0x0F74, 0, RW(dst), R(src));} | ||
| 3263 | void pcmpeqw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PCMPEQW, 0x0F75, 0, RW(dst), R(src));} | ||
| 3264 | void pcmpeqw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PCMPEQW, 0x0F75, 0, RW(dst), R(src));} | ||
| 3265 | void pcmpeqd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PCMPEQD, 0x0F76, 0, RW(dst), R(src));} | ||
| 3266 | void pcmpeqd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PCMPEQD, 0x0F76, 0, RW(dst), R(src));} | ||
| 3267 | void pcmpgtb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PCMPGTB, 0x0F64, 0, RW(dst), R(src));} | ||
| 3268 | void pcmpgtb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PCMPGTB, 0x0F64, 0, RW(dst), R(src));} | ||
| 3269 | void pcmpgtw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PCMPGTW, 0x0F65, 0, RW(dst), R(src));} | ||
| 3270 | void pcmpgtw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PCMPGTW, 0x0F65, 0, RW(dst), R(src));} | ||
| 3271 | void pcmpgtd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PCMPGTD, 0x0F66, 0, RW(dst), R(src));} | ||
| 3272 | void pcmpgtd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PCMPGTD, 0x0F66, 0, RW(dst), R(src));} | ||
| 3273 | void pmaddwd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMADDWD, 0x0FF5, 0, RW(dst), R(src));} | ||
| 3274 | void pmaddwd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMADDWD, 0x0FF5, 0, RW(dst), R(src));} | ||
| 3275 | void pmulhw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMULHW, 0x0FE5, 0, RW(dst), R(src));} | ||
| 3276 | void pmulhw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMULHW, 0x0FE5, 0, RW(dst), R(src));} | ||
| 3277 | void pmullw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMULLW, 0x0FD5, 0, RW(dst), R(src));} | ||
| 3278 | void pmullw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMULLW, 0x0FD5, 0, RW(dst), R(src));} | ||
| 3279 | void por(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_POR, 0x0FEB, 0, RW(dst), R(src));} | ||
| 3280 | void por(const MmxReg& dst, const Mem64& src) {AppendInstr(I_POR, 0x0FEB, 0, RW(dst), R(src));} | ||
| 3281 | void psllw(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSLLW, 0x0FF1, 0, RW(dst), R(count));} | ||
| 3282 | void psllw(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSLLW, 0x0FF1, 0, RW(dst), R(count));} | ||
| 3283 | void psllw(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSLLW, 0x0F71, 0, Imm8(6), RW(dst), count);} | ||
| 3284 | void pslld(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSLLD, 0x0FF2, 0, RW(dst), R(count));} | ||
| 3285 | void pslld(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSLLD, 0x0FF2, 0, RW(dst), R(count));} | ||
| 3286 | void pslld(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSLLD, 0x0F72, 0, Imm8(6), RW(dst), count);} | ||
| 3287 | void psllq(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSLLQ, 0x0FF3, 0, RW(dst), R(count));} | ||
| 3288 | void psllq(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSLLQ, 0x0FF3, 0, RW(dst), R(count));} | ||
| 3289 | void psllq(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSLLQ, 0x0F73, 0, Imm8(6), RW(dst), count);} | ||
| 3290 | void psraw(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSRAW, 0x0FE1, 0, RW(dst), R(count));} | ||
| 3291 | void psraw(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSRAW, 0x0FE1, 0, RW(dst), R(count));} | ||
| 3292 | void psraw(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSRAW, 0x0F71, 0, Imm8(4), RW(dst), count);} | ||
| 3293 | void psrad(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSRAD, 0x0FE2, 0, RW(dst), R(count));} | ||
| 3294 | void psrad(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSRAD, 0x0FE2, 0, RW(dst), R(count));} | ||
| 3295 | void psrad(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSRAD, 0x0F72, 0, Imm8(4), RW(dst), count);} | ||
| 3296 | void psrlw(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSRLW, 0x0FD1, 0, RW(dst), R(count));} | ||
| 3297 | void psrlw(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSRLW, 0x0FD1, 0, RW(dst), R(count));} | ||
| 3298 | void psrlw(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSRLW, 0x0F71, 0, Imm8(2), RW(dst), count);} | ||
| 3299 | void psrld(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSRLD, 0x0FD2, 0, RW(dst), R(count));} | ||
| 3300 | void psrld(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSRLD, 0x0FD2, 0, RW(dst), R(count));} | ||
| 3301 | void psrld(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSRLD, 0x0F72, 0, Imm8(2), RW(dst), count);} | ||
| 3302 | void psrlq(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSRLQ, 0x0FD3, 0, RW(dst), R(count));} | ||
| 3303 | void psrlq(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSRLQ, 0x0FD3, 0, RW(dst), R(count));} | ||
| 3304 | void psrlq(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSRLQ, 0x0F73, 0, Imm8(2), RW(dst), count);} | ||
| 3305 | void psubb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBB, 0x0FF8, 0, RW(dst), R(src));} | ||
| 3306 | void psubb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBB, 0x0FF8, 0, RW(dst), R(src));} | ||
| 3307 | void psubw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBW, 0x0FF9, 0, RW(dst), R(src));} | ||
| 3308 | void psubw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBW, 0x0FF9, 0, RW(dst), R(src));} | ||
| 3309 | void psubd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBD, 0x0FFA, 0, RW(dst), R(src));} | ||
| 3310 | void psubd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBD, 0x0FFA, 0, RW(dst), R(src));} | ||
| 3311 | void psubsb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBSB, 0x0FE8, 0, RW(dst), R(src));} | ||
| 3312 | void psubsb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBSB, 0x0FE8, 0, RW(dst), R(src));} | ||
| 3313 | void psubsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBSW, 0x0FE9, 0, RW(dst), R(src));} | ||
| 3314 | void psubsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBSW, 0x0FE9, 0, RW(dst), R(src));} | ||
| 3315 | void psubusb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBUSB, 0x0FD8, 0, RW(dst), R(src));} | ||
| 3316 | void psubusb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBUSB, 0x0FD8, 0, RW(dst), R(src));} | ||
| 3317 | void psubusw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBUSW, 0x0FD9, 0, RW(dst), R(src));} | ||
| 3318 | void psubusw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBUSW, 0x0FD9, 0, RW(dst), R(src));} | ||
| 3319 | void punpckhbw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PUNPCKHBW, 0x0F68, 0, RW(dst), R(src));} | ||
| 3320 | void punpckhbw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PUNPCKHBW, 0x0F68, 0, RW(dst), R(src));} | ||
| 3321 | void punpckhwd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PUNPCKHWD, 0x0F69, 0, RW(dst), R(src));} | ||
| 3322 | void punpckhwd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PUNPCKHWD, 0x0F69, 0, RW(dst), R(src));} | ||
| 3323 | void punpckhdq(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PUNPCKHDQ, 0x0F6A, 0, RW(dst), R(src));} | ||
| 3324 | void punpckhdq(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PUNPCKHDQ, 0x0F6A, 0, RW(dst), R(src));} | ||
| 3325 | void punpcklbw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PUNPCKLBW, 0x0F60, 0, RW(dst), R(src));} | ||
| 3326 | void punpcklbw(const MmxReg& dst, const Mem32& src) {AppendInstr(I_PUNPCKLBW, 0x0F60, 0, RW(dst), R(src));} | ||
| 3327 | void punpcklwd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PUNPCKLWD, 0x0F61, 0, RW(dst), R(src));} | ||
| 3328 | void punpcklwd(const MmxReg& dst, const Mem32& src) {AppendInstr(I_PUNPCKLWD, 0x0F61, 0, RW(dst), R(src));} | ||
| 3329 | void punpckldq(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PUNPCKLDQ, 0x0F62, 0, RW(dst), R(src));} | ||
| 3330 | void punpckldq(const MmxReg& dst, const Mem32& src) {AppendInstr(I_PUNPCKLDQ, 0x0F62, 0, RW(dst), R(src));} | ||
| 3331 | ✗ | void pxor(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PXOR, 0x0FEF, 0, RW(dst), R(src));} | |
| 3332 | void pxor(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PXOR, 0x0FEF, 0, RW(dst), R(src));} | ||
| 3333 | |||
| 3334 | // MMX2 | ||
| 3335 | void pavgb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PAVGB, 0x0FE0, 0, RW(dst), R(src));} | ||
| 3336 | void pavgb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PAVGB, 0x0FE0, 0, RW(dst), R(src));} | ||
| 3337 | void pavgw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PAVGW, 0x0FE3, 0, RW(dst), R(src));} | ||
| 3338 | void pavgw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PAVGW, 0x0FE3, 0, RW(dst), R(src));} | ||
| 3339 | void pextrw(const Reg32& dst, const MmxReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0x0FC5, 0, W(dst), R(src), i);} | ||
| 3340 | #ifdef JITASM64 | ||
| 3341 | void pextrw(const Reg64& dst, const MmxReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0x0FC5, E_REXW_PREFIX, W(dst), R(src), i);} | ||
| 3342 | #endif | ||
| 3343 | void pinsrw(const MmxReg& dst, const Reg32& src, const Imm8& i) {AppendInstr(I_PINSRW, 0x0FC4, 0, RW(dst), R(src), i);} | ||
| 3344 | void pinsrw(const MmxReg& dst, const Mem16& src, const Imm8& i) {AppendInstr(I_PINSRW, 0x0FC4, 0, RW(dst), R(src), i);} | ||
| 3345 | #ifdef JITASM64 | ||
| 3346 | void pinsrw(const MmxReg& dst, const Reg64& src, const Imm8& i) {AppendInstr(I_PINSRW, 0x0FC4, E_REXW_PREFIX, RW(dst), R(src), i);} | ||
| 3347 | #endif | ||
| 3348 | void pmaxsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMAXSW, 0x0FEE, 0, RW(dst), R(src));} | ||
| 3349 | void pmaxsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMAXSW, 0x0FEE, 0, RW(dst), R(src));} | ||
| 3350 | void pmaxub(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMAXUB, 0x0FDE, 0, RW(dst), R(src));} | ||
| 3351 | void pmaxub(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMAXUB, 0x0FDE, 0, RW(dst), R(src));} | ||
| 3352 | void pminsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMINSW, 0x0FEA, 0, RW(dst), R(src));} | ||
| 3353 | void pminsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMINSW, 0x0FEA, 0, RW(dst), R(src));} | ||
| 3354 | void pminub(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMINUB, 0x0FDA, 0, RW(dst), R(src));} | ||
| 3355 | void pminub(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMINUB, 0x0FDA, 0, RW(dst), R(src));} | ||
| 3356 | void pmovmskb(const Reg32& dst, const MmxReg& src) {AppendInstr(I_PMOVMSKB, 0x0FD7, 0, W(dst), R(src));} | ||
| 3357 | #ifdef JITASM64 | ||
| 3358 | void pmovmskb(const Reg64& dst, const MmxReg& src) {AppendInstr(I_PMOVMSKB, 0x0FD7, E_REXW_PREFIX, W(dst), R(src));} | ||
| 3359 | #endif | ||
| 3360 | void pmulhuw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMULHUW, 0x0FE4, 0, RW(dst), R(src));} | ||
| 3361 | void pmulhuw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMULHUW, 0x0FE4, 0, RW(dst), R(src));} | ||
| 3362 | void psadbw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSADBW, 0x0FF6, 0, RW(dst), R(src));} | ||
| 3363 | void psadbw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSADBW, 0x0FF6, 0, RW(dst), R(src));} | ||
| 3364 | void pshufw(const MmxReg& dst, const MmxReg& src, const Imm8& order) {AppendInstr(I_PSHUFW, 0x0F70, 0, RW(dst), R(src), order);} | ||
| 3365 | void pshufw(const MmxReg& dst, const Mem64& src, const Imm8& order) {AppendInstr(I_PSHUFW, 0x0F70, 0, RW(dst), R(src), order);} | ||
| 3366 | |||
| 3367 | // SSE | ||
| 3368 | ✗ | void addps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ADDPS, 0x0F58, 0, RW(dst), R(src));} | |
| 3369 | ✗ | void addps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ADDPS, 0x0F58, 0, RW(dst), R(src));} | |
| 3370 | void addss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ADDSS, 0x0F58, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3371 | void addss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_ADDSS, 0x0F58, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3372 | ✗ | void andps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ANDPS, 0x0F54, 0, RW(dst), R(src));} | |
| 3373 | ✗ | void andps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ANDPS, 0x0F54, 0, RW(dst), R(src));} | |
| 3374 | ✗ | void andnps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ANDNPS, 0x0F55, 0, RW(dst), R(src));} | |
| 3375 | void andnps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ANDNPS, 0x0F55, 0, RW(dst), R(src));} | ||
| 3376 | ✗ | void cmpps(const XmmReg& dst, const XmmReg& src, const Imm8& opd3) {AppendInstr(I_CMPPS, 0x0FC2, 0, RW(dst), R(src), opd3);} | |
| 3377 | ✗ | void cmpps(const XmmReg& dst, const Mem128& src, const Imm8& opd3) {AppendInstr(I_CMPPS, 0x0FC2, 0, RW(dst), R(src), opd3);} | |
| 3378 | ✗ | void cmpeqps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 0);} | |
| 3379 | void cmpeqps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 0);} | ||
| 3380 | ✗ | void cmpltps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 1);} | |
| 3381 | ✗ | void cmpltps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 1);} | |
| 3382 | ✗ | void cmpleps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 2);} | |
| 3383 | void cmpleps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 2);} | ||
| 3384 | void cmpunordps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 3);} | ||
| 3385 | void cmpunordps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 3);} | ||
| 3386 | ✗ | void cmpneqps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 4);} | |
| 3387 | void cmpneqps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 4);} | ||
| 3388 | ✗ | void cmpnltps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 5);} | |
| 3389 | void cmpnltps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 5);} | ||
| 3390 | ✗ | void cmpnleps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 6);} | |
| 3391 | void cmpnleps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 6);} | ||
| 3392 | ✗ | void cmpordps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 7);} | |
| 3393 | void cmpordps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 7);} | ||
| 3394 | void cmpss(const XmmReg& dst, const XmmReg& src, const Imm8& opd3) {AppendInstr(I_CMPSS, 0x0FC2, E_MANDATORY_PREFIX_F3, RW(dst), R(src), opd3);} | ||
| 3395 | void cmpss(const XmmReg& dst, const Mem32& src, const Imm8& opd3) {AppendInstr(I_CMPSS, 0x0FC2, E_MANDATORY_PREFIX_F3, RW(dst), R(src), opd3);} | ||
| 3396 | void cmpeqss(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 0);} | ||
| 3397 | void cmpeqss(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 0);} | ||
| 3398 | void cmpltss(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 1);} | ||
| 3399 | void cmpltss(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 1);} | ||
| 3400 | void cmpless(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 2);} | ||
| 3401 | void cmpless(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 2);} | ||
| 3402 | void cmpunordss(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 3);} | ||
| 3403 | void cmpunordss(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 3);} | ||
| 3404 | void cmpneqss(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 4);} | ||
| 3405 | void cmpneqss(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 4);} | ||
| 3406 | void cmpnltss(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 5);} | ||
| 3407 | void cmpnltss(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 5);} | ||
| 3408 | void cmpnless(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 6);} | ||
| 3409 | void cmpnless(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 6);} | ||
| 3410 | void cmpordss(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 7);} | ||
| 3411 | void cmpordss(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 7);} | ||
| 3412 | void comiss(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_COMISS, 0x0F2F, 0, R(src1), R(src2));} | ||
| 3413 | void comiss(const XmmReg& src1, const Mem32& src2) {AppendInstr(I_COMISS, 0x0F2F, 0, R(src1), R(src2));} | ||
| 3414 | void cvtpi2ps(const XmmReg& dst, const MmxReg& src) {AppendInstr(I_CVTPI2PS, 0x0F2A, 0, RW(dst), R(src));} | ||
| 3415 | void cvtpi2ps(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTPI2PS, 0x0F2A, 0, RW(dst), R(src));} | ||
| 3416 | void cvtps2pi(const MmxReg& dst, const XmmReg& src) {AppendInstr(I_CVTPS2PI, 0x0F2D, 0, W(dst), R(src));} | ||
| 3417 | void cvtps2pi(const MmxReg& dst, const Mem64& src) {AppendInstr(I_CVTPS2PI, 0x0F2D, 0, W(dst), R(src));} | ||
| 3418 | void cvtsi2ss(const XmmReg& dst, const Reg32& src) {AppendInstr(I_CVTSI2SS, 0x0F2A, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3419 | void cvtsi2ss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_CVTSI2SS, 0x0F2A, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3420 | void cvtss2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SI, 0x0F2D, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3421 | void cvtss2si(const Reg32& dst, const Mem32& src) {AppendInstr(I_CVTSS2SI, 0x0F2D, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3422 | void cvttps2pi(const MmxReg& dst, const XmmReg& src) {AppendInstr(I_CVTTPS2PI, 0x0F2C, 0, W(dst), R(src));} | ||
| 3423 | void cvttps2pi(const MmxReg& dst, const Mem64& src) {AppendInstr(I_CVTTPS2PI, 0x0F2C, 0, W(dst), R(src));} | ||
| 3424 | void cvttss2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTTSS2SI, 0x0F2C, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3425 | void cvttss2si(const Reg32& dst, const Mem32& src) {AppendInstr(I_CVTTSS2SI, 0x0F2C, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3426 | #ifdef JITASM64 | ||
| 3427 | void cvtsi2ss(const XmmReg& dst, const Reg64& src) {AppendInstr(I_CVTSI2SS, 0x0F2A, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, RW(dst), R(src));} | ||
| 3428 | void cvtsi2ss(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTSI2SS, 0x0F2A, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, RW(dst), R(src));} | ||
| 3429 | void cvtss2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SI, 0x0F2D, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 3430 | void cvtss2si(const Reg64& dst, const Mem32& src) {AppendInstr(I_CVTSS2SI, 0x0F2D, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 3431 | void cvttss2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTTSS2SI, 0x0F2C, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 3432 | void cvttss2si(const Reg64& dst, const Mem32& src) {AppendInstr(I_CVTTSS2SI, 0x0F2C, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 3433 | #endif | ||
| 3434 | ✗ | void divps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_DIVPS, 0x0F5E, 0, RW(dst), R(src));} | |
| 3435 | void divps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_DIVPS, 0x0F5E, 0, RW(dst), R(src));} | ||
| 3436 | void divss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_DIVSS, 0x0F5E, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3437 | void divss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_DIVSS, 0x0F5E, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3438 | void ldmxcsr(const Mem32& src) {AppendInstr(I_LDMXCSR, 0x0FAE, 0, Imm8(2), R(src));} | ||
| 3439 | void maskmovq(const MmxReg& src, const MmxReg& mask, const Reg& dstptr) {AppendInstr(I_MASKMOVQ, 0x0FF7, 0, R(src), R(mask), Dummy(R(dstptr),zdi));} | ||
| 3440 | ✗ | void maxps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MAXPS, 0x0F5F, 0, RW(dst), R(src));} | |
| 3441 | ✗ | void maxps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MAXPS, 0x0F5F, 0, RW(dst), R(src));} | |
| 3442 | void maxss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MAXSS, 0x0F5F, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3443 | void maxss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MAXSS, 0x0F5F, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3444 | ✗ | void minps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MINPS, 0x0F5D, 0, RW(dst), R(src));} | |
| 3445 | ✗ | void minps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MINPS, 0x0F5D, 0, RW(dst), R(src));} | |
| 3446 | void minss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MINSS, 0x0F5D, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3447 | void minss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MINSS, 0x0F5D, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3448 | ✗ | void movaps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVAPS, 0x0F28, 0, W(dst), R(src));} | |
| 3449 | ✗ | void movaps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVAPS, 0x0F28, 0, W(dst), R(src));} | |
| 3450 | ✗ | void movaps(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVAPS, 0x0F29, 0, R(src), W(dst));} | |
| 3451 | void movhlps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVHLPS, 0x0F12, 0, RW(dst), R(src));} | ||
| 3452 | void movhps(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVHPS, 0x0F16, 0, RW(dst), R(src));} | ||
| 3453 | void movhps(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVHPS, 0x0F17, 0, R(src), W(dst));} | ||
| 3454 | void movlhps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVLHPS, 0x0F16, 0, RW(dst), R(src));} | ||
| 3455 | void movlps(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVLPS, 0x0F12, 0, RW(dst), R(src));} | ||
| 3456 | void movlps(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVLPS, 0x0F13, 0, R(src), W(dst));} | ||
| 3457 | void movmskps(const Reg32& dst, const XmmReg& src) {AppendInstr(I_MOVMSKPS, 0x0F50, 0, W(dst), R(src));} | ||
| 3458 | #ifdef JITASM64 | ||
| 3459 | void movmskps(const Reg64& dst, const XmmReg& src) {AppendInstr(I_MOVMSKPS, 0x0F50, E_REXW_PREFIX, W(dst), R(src));} | ||
| 3460 | #endif | ||
| 3461 | void movntps(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVNTPS, 0x0F2B, 0, R(src), W(dst));} | ||
| 3462 | void movntq(const Mem64& dst, const MmxReg& src) {AppendInstr(I_MOVNTQ, 0x0FE7, 0, R(src), W(dst));} | ||
| 3463 | void movss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVSS, 0x0F10, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3464 | void movss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MOVSS, 0x0F10, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3465 | void movss(const Mem32& dst, const XmmReg& src) {AppendInstr(I_MOVSS, 0x0F11, E_MANDATORY_PREFIX_F3, R(src), W(dst));} | ||
| 3466 | void movups(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVUPS, 0x0F10, 0, W(dst), R(src));} | ||
| 3467 | void movups(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVUPS, 0x0F10, 0, W(dst), R(src));} | ||
| 3468 | void movups(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVUPS, 0x0F11, 0, R(src), W(dst));} | ||
| 3469 | ✗ | void mulps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MULPS, 0x0F59, 0, RW(dst), R(src));} | |
| 3470 | ✗ | void mulps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MULPS, 0x0F59, 0, RW(dst), R(src));} | |
| 3471 | void mulss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MULSS, 0x0F59, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3472 | void mulss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MULSS, 0x0F59, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3473 | ✗ | void orps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ORPS, 0x0F56, 0, RW(dst), R(src));} | |
| 3474 | ✗ | void orps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ORPS, 0x0F56, 0, RW(dst), R(src));} | |
| 3475 | void prefetcht0(const Mem8& mem) {AppendInstr(I_PREFETCH, 0x0F18, 0, Imm8(1), R(mem));} | ||
| 3476 | void prefetcht1(const Mem8& mem) {AppendInstr(I_PREFETCH, 0x0F18, 0, Imm8(2), R(mem));} | ||
| 3477 | void prefetcht2(const Mem8& mem) {AppendInstr(I_PREFETCH, 0x0F18, 0, Imm8(3), R(mem));} | ||
| 3478 | void prefetchnta(const Mem8& mem) {AppendInstr(I_PREFETCH, 0x0F18, 0, Imm8(0), R(mem));} | ||
| 3479 | void rcpps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_RCPPS, 0x0F53, 0, W(dst), R(src));} | ||
| 3480 | void rcpps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_RCPPS, 0x0F53, 0, W(dst), R(src));} | ||
| 3481 | void rcpss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_RCPSS, 0x0F53, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3482 | void rcpss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_RCPSS, 0x0F53, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3483 | void rsqrtps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_RSQRTPS, 0x0F52, 0, W(dst), R(src));} | ||
| 3484 | void rsqrtps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_RSQRTPS, 0x0F52, 0, W(dst), R(src));} | ||
| 3485 | void rsqrtss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_RSQRTSS, 0x0F52, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3486 | void rsqrtss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_RSQRTSS, 0x0F52, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3487 | void sfence() {AppendInstr(I_SFENCE, 0x0FAEF8, 0);} | ||
| 3488 | ✗ | void shufps(const XmmReg& dst, const XmmReg& src, const Imm8& sel) {AppendInstr(I_SHUFPS, 0x0FC6, 0, RW(dst), R(src), sel);} | |
| 3489 | void shufps(const XmmReg& dst, const Mem128& src, const Imm8& sel) {AppendInstr(I_SHUFPS, 0x0FC6, 0, RW(dst), R(src), sel);} | ||
| 3490 | ✗ | void sqrtps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SQRTPS, 0x0F51, 0, W(dst), R(src));} | |
| 3491 | void sqrtps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_SQRTPS, 0x0F51, 0, W(dst), R(src));} | ||
| 3492 | void sqrtss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SQRTSS, 0x0F51, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3493 | void sqrtss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_SQRTSS, 0x0F51, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3494 | void stmxcsr(const Mem32& dst) {AppendInstr(I_STMXCSR, 0x0FAE, 0, Imm8(3), W(dst));} | ||
| 3495 | ✗ | void subps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SUBPS, 0x0F5C, 0, RW(dst), R(src));} | |
| 3496 | ✗ | void subps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_SUBPS, 0x0F5C, 0, RW(dst), R(src));} | |
| 3497 | void subss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SUBSS, 0x0F5C, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3498 | void subss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_SUBSS, 0x0F5C, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3499 | void ucomiss(const XmmReg& src1, const XmmReg& src2){AppendInstr(I_UCOMISS, 0x0F2E, 0, R(src1), R(src2));} | ||
| 3500 | void ucomiss(const XmmReg& src1, const Mem32& src2) {AppendInstr(I_UCOMISS, 0x0F2E, 0, R(src1), R(src2));} | ||
| 3501 | void unpckhps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_UNPCKHPS, 0x0F15, 0, RW(dst), R(src));} | ||
| 3502 | void unpckhps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_UNPCKHPS, 0x0F15, 0, RW(dst), R(src));} | ||
| 3503 | void unpcklps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_UNPCKLPS, 0x0F14, 0, RW(dst), R(src));} | ||
| 3504 | void unpcklps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_UNPCKLPS, 0x0F14, 0, RW(dst), R(src));} | ||
| 3505 | ✗ | void xorps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_XORPS, 0x0F57, 0, RW(dst), R(src));} | |
| 3506 | ✗ | void xorps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_XORPS, 0x0F57, 0, RW(dst), R(src));} | |
| 3507 | |||
| 3508 | // SSE2 | ||
| 3509 | void addpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ADDPD, 0x0F58, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3510 | void addpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ADDPD, 0x0F58, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3511 | void addsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ADDSD, 0x0F58, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3512 | void addsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_ADDSD, 0x0F58, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3513 | void andpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ANDPD, 0x0F54, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3514 | void andpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ANDPD, 0x0F54, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3515 | void andnpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ANDNPD, 0x0F55, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3516 | void andnpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ANDNPD, 0x0F55, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3517 | void clflush(const Mem8& src) {AppendInstr(I_CLFLUSH, 0x0FAE, 0, Imm8(7), R(src));} | ||
| 3518 | void cmppd(const XmmReg& dst, const XmmReg& src, const Imm8& opd3) {AppendInstr(I_CMPPD, 0x0FC2, E_MANDATORY_PREFIX_66, RW(dst), R(src), opd3);} | ||
| 3519 | void cmppd(const XmmReg& dst, const Mem128& src, const Imm8& opd3) {AppendInstr(I_CMPPD, 0x0FC2, E_MANDATORY_PREFIX_66, RW(dst), R(src), opd3);} | ||
| 3520 | void cmpeqpd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 0);} | ||
| 3521 | void cmpeqpd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 0);} | ||
| 3522 | void cmpltpd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 1);} | ||
| 3523 | void cmpltpd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 1);} | ||
| 3524 | void cmplepd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 2);} | ||
| 3525 | void cmplepd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 2);} | ||
| 3526 | void cmpunordpd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 3);} | ||
| 3527 | void cmpunordpd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 3);} | ||
| 3528 | void cmpneqpd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 4);} | ||
| 3529 | void cmpneqpd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 4);} | ||
| 3530 | void cmpnltpd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 5);} | ||
| 3531 | void cmpnltpd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 5);} | ||
| 3532 | void cmpnlepd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 6);} | ||
| 3533 | void cmpnlepd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 6);} | ||
| 3534 | void cmpordpd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 7);} | ||
| 3535 | void cmpordpd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 7);} | ||
| 3536 | void cmpsd(const XmmReg& dst, const XmmReg& src, const Imm8& opd3) {AppendInstr(I_CMPSD, 0x0FC2, E_MANDATORY_PREFIX_F2, RW(dst), R(src), opd3);} | ||
| 3537 | void cmpsd(const XmmReg& dst, const Mem64& src, const Imm8& opd3) {AppendInstr(I_CMPSD, 0x0FC2, E_MANDATORY_PREFIX_F2, RW(dst), R(src), opd3);} | ||
| 3538 | void cmpeqsd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 0);} | ||
| 3539 | void cmpeqsd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 0);} | ||
| 3540 | void cmpltsd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 1);} | ||
| 3541 | void cmpltsd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 1);} | ||
| 3542 | void cmplesd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 2);} | ||
| 3543 | void cmplesd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 2);} | ||
| 3544 | void cmpunordsd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 3);} | ||
| 3545 | void cmpunordsd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 3);} | ||
| 3546 | void cmpneqsd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 4);} | ||
| 3547 | void cmpneqsd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 4);} | ||
| 3548 | void cmpnltsd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 5);} | ||
| 3549 | void cmpnltsd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 5);} | ||
| 3550 | void cmpnlesd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 6);} | ||
| 3551 | void cmpnlesd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 6);} | ||
| 3552 | void cmpordsd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 7);} | ||
| 3553 | void cmpordsd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 7);} | ||
| 3554 | void comisd(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_COMISD, 0x0F2F, E_MANDATORY_PREFIX_66, R(src1), R(src2));} | ||
| 3555 | void comisd(const XmmReg& src1, const Mem64& src2) {AppendInstr(I_COMISD, 0x0F2F, E_MANDATORY_PREFIX_66, R(src1), R(src2));} | ||
| 3556 | void cvtdq2pd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTDQ2PD, 0x0FE6, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3557 | void cvtdq2pd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTDQ2PD, 0x0FE6, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3558 | void cvtpd2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPD2DQ, 0x0FE6, E_MANDATORY_PREFIX_F2, W(dst), R(src));} | ||
| 3559 | void cvtpd2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPD2DQ, 0x0FE6, E_MANDATORY_PREFIX_F2, W(dst), R(src));} | ||
| 3560 | void cvtpd2pi(const MmxReg& dst, const XmmReg& src) {AppendInstr(I_CVTPD2PI, 0x0F2D, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3561 | void cvtpd2pi(const MmxReg& dst, const Mem128& src) {AppendInstr(I_CVTPD2PI, 0x0F2D, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3562 | void cvtpd2ps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPD2PS, 0x0F5A, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3563 | void cvtpd2ps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPD2PS, 0x0F5A, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3564 | void cvtpi2pd(const XmmReg& dst, const MmxReg& src) {AppendInstr(I_CVTPI2PD, 0x0F2A, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3565 | void cvtpi2pd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTPI2PD, 0x0F2A, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3566 | void cvtps2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPS2DQ, 0x0F5B, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3567 | void cvtps2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPS2DQ, 0x0F5B, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3568 | ✗ | void cvtdq2ps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTDQ2PS, 0x0F5B, 0, W(dst), R(src));} | |
| 3569 | void cvtdq2ps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTDQ2PS, 0x0F5B, 0, W(dst), R(src));} | ||
| 3570 | void cvtps2pd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPS2PD, 0x0F5A, 0, W(dst), R(src));} | ||
| 3571 | void cvtps2pd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTPS2PD, 0x0F5A, 0, W(dst), R(src));} | ||
| 3572 | void cvtsd2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTSD2SI, 0x0F2D, E_MANDATORY_PREFIX_F2, W(dst), R(src));} | ||
| 3573 | void cvtsd2si(const Reg32& dst, const Mem64& src) {AppendInstr(I_CVTSD2SI, 0x0F2D, E_MANDATORY_PREFIX_F2, W(dst), R(src));} | ||
| 3574 | #ifdef JITASM64 | ||
| 3575 | void cvtsd2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTSD2SI, 0x0F2D, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 3576 | void cvtsd2si(const Reg64& dst, const Mem64& src) {AppendInstr(I_CVTSD2SI, 0x0F2D, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 3577 | #endif | ||
| 3578 | void cvtsd2ss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTSD2SS, 0x0F5A, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3579 | void cvtsd2ss(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTSD2SS, 0x0F5A, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3580 | void cvtsi2sd(const XmmReg& dst, const Reg32& src) {AppendInstr(I_CVTSI2SD, 0x0F2A, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3581 | void cvtsi2sd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_CVTSI2SD, 0x0F2A, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3582 | #ifdef JITASM64 | ||
| 3583 | void cvtsi2sd(const XmmReg& dst, const Reg64& src) {AppendInstr(I_CVTSI2SD, 0x0F2A, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));} | ||
| 3584 | void cvtsi2sd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTSI2SD, 0x0F2A, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));} | ||
| 3585 | #endif | ||
| 3586 | void cvtss2sd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SD, 0x0F5A, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3587 | void cvtss2sd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_CVTSS2SD, 0x0F5A, E_MANDATORY_PREFIX_F3, RW(dst), R(src));} | ||
| 3588 | void cvttpd2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTTPD2DQ, 0x0FE6, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3589 | void cvttpd2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTTPD2DQ, 0x0FE6, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3590 | void cvttpd2pi(const MmxReg& dst, const XmmReg& src) {AppendInstr(I_CVTTPD2PI, 0x0F2C, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3591 | void cvttpd2pi(const MmxReg& dst, const Mem128& src) {AppendInstr(I_CVTTPD2PI, 0x0F2C, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3592 | ✗ | void cvttps2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTTPS2DQ, 0x0F5B, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | |
| 3593 | void cvttps2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTTPS2DQ, 0x0F5B, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3594 | void cvttsd2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTTSD2SI, 0x0F2C, E_MANDATORY_PREFIX_F2, W(dst), R(src));} | ||
| 3595 | void cvttsd2si(const Reg32& dst, const Mem64& src) {AppendInstr(I_CVTTSD2SI, 0x0F2C, E_MANDATORY_PREFIX_F2, W(dst), R(src));} | ||
| 3596 | #ifdef JITASM64 | ||
| 3597 | void cvttsd2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTTSD2SI, 0x0F2C, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 3598 | void cvttsd2si(const Reg64& dst, const Mem64& src) {AppendInstr(I_CVTTSD2SI, 0x0F2C, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 3599 | #endif | ||
| 3600 | void divpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_DIVPD, 0x0F5E, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3601 | void divpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_DIVPD, 0x0F5E, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3602 | void divsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_DIVSD, 0x0F5E, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3603 | void divsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_DIVSD, 0x0F5E, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3604 | void lfence() {AppendInstr(I_LFENCE, 0x0FAEE8, 0);} | ||
| 3605 | void maskmovdqu(const XmmReg& src, const XmmReg& mask, const Reg& dstptr) {AppendInstr(I_MASKMOVDQU, 0x0FF7, E_MANDATORY_PREFIX_66, R(src), R(mask), Dummy(R(dstptr), zdi));} | ||
| 3606 | void maxpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MAXPD, 0x0F5F, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3607 | void maxpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MAXPD, 0x0F5F, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3608 | void maxsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MAXSD, 0x0F5F, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3609 | void maxsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MAXSD, 0x0F5F, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3610 | void mfence() {AppendInstr(I_MFENCE, 0x0FAEF0, 0);} | ||
| 3611 | void minpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MINPD, 0x0F5D, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3612 | void minpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MINPD, 0x0F5D, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3613 | void minsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MINSD, 0x0F5D, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3614 | void minsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MINSD, 0x0F5D, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3615 | void movapd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVAPD, 0x0F28, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3616 | void movapd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVAPD, 0x0F28, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3617 | void movapd(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVAPD, 0x0F29, E_MANDATORY_PREFIX_66, R(src), W(dst));} | ||
| 3618 | void movd(const XmmReg& dst, const Reg32& src) {AppendInstr(I_MOVD, 0x0F6E, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3619 | ✗ | void movd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MOVD, 0x0F6E, E_MANDATORY_PREFIX_66, W(dst), R(src));} | |
| 3620 | void movd(const Reg32& dst, const XmmReg& src) {AppendInstr(I_MOVD, 0x0F7E, E_MANDATORY_PREFIX_66, R(src), W(dst));} | ||
| 3621 | ✗ | void movd(const Mem32& dst, const XmmReg& src) {AppendInstr(I_MOVD, 0x0F7E, E_MANDATORY_PREFIX_66, R(src), W(dst));} | |
| 3622 | #ifdef JITASM64 | ||
| 3623 | ✗ | void movd(const XmmReg& dst, const Reg64& src) {AppendInstr(I_MOVD, 0x0F6E, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, W(dst), R(src));} | |
| 3624 | void movd(const Reg64& dst, const XmmReg& src) {AppendInstr(I_MOVD, 0x0F7E, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst));} | ||
| 3625 | #endif | ||
| 3626 | ✗ | void movdqa(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVDQA, 0x0F6F, E_MANDATORY_PREFIX_66, W(dst), R(src));} | |
| 3627 | ✗ | void movdqa(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVDQA, 0x0F6F, E_MANDATORY_PREFIX_66, W(dst), R(src));} | |
| 3628 | ✗ | void movdqa(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVDQA, 0x0F7F, E_MANDATORY_PREFIX_66, R(src), W(dst));} | |
| 3629 | void movdqu(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVDQU, 0x0F6F, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3630 | ✗ | void movdqu(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVDQU, 0x0F6F, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | |
| 3631 | ✗ | void movdqu(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVDQU, 0x0F7F, E_MANDATORY_PREFIX_F3, R(src), W(dst));} | |
| 3632 | void movdq2q(const MmxReg& dst, const XmmReg& src) {AppendInstr(I_MOVDQ2Q, 0x0FD6, E_MANDATORY_PREFIX_F2, W(dst), R(src));} | ||
| 3633 | void movhpd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVHPD, 0x0F16, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3634 | void movhpd(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVHPD, 0x0F17, E_MANDATORY_PREFIX_66, R(src), W(dst));} | ||
| 3635 | void movlpd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVLPD, 0x0F12, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3636 | void movlpd(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVLPD, 0x0F13, E_MANDATORY_PREFIX_66, R(src), W(dst));} | ||
| 3637 | void movmskpd(const Reg32& dst, XmmReg& src) {AppendInstr(I_MOVMSKPD, 0x0F50, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3638 | #ifdef JITASM64 | ||
| 3639 | void movmskpd(const Reg64& dst, XmmReg& src) {AppendInstr(I_MOVMSKPD, 0x0F50, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 3640 | #endif | ||
| 3641 | void movntdq(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVNTDQ, 0x0FE7, E_MANDATORY_PREFIX_66, R(src), W(dst));} | ||
| 3642 | void movnti(const Mem32& dst, const Reg32& src) {AppendInstr(I_MOVNTI, 0x0FC3, 0, R(src), W(dst));} | ||
| 3643 | #ifdef JITASM64 | ||
| 3644 | void movnti(const Mem64& dst, const Reg64& src) {AppendInstr(I_MOVNTI, 0x0FC3, E_REXW_PREFIX, R(src), W(dst));} | ||
| 3645 | #endif | ||
| 3646 | void movntpd(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVNTPD, 0x0F2B, E_MANDATORY_PREFIX_66, R(src), W(dst));} | ||
| 3647 | void movq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVQ, 0x0F7E, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3648 | ✗ | void movq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVQ, 0x0F7E, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | |
| 3649 | ✗ | void movq(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVQ, 0x0FD6, E_MANDATORY_PREFIX_66, R(src), W(dst));} | |
| 3650 | #ifdef JITASM64 | ||
| 3651 | void movq(const XmmReg& dst, const Reg64& src) {movd(dst, src);} | ||
| 3652 | void movq(const Reg64& dst, const XmmReg& src) {movd(dst, src);} | ||
| 3653 | #endif | ||
| 3654 | void movq2dq(const XmmReg& dst, const MmxReg& src) {AppendInstr(I_MOVQ2DQ, 0x0FD6, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3655 | void movsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVSD, 0x0F10, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} // 64~127bits are unchanged | ||
| 3656 | void movsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVSD, 0x0F10, E_MANDATORY_PREFIX_F2, W(dst), R(src));} | ||
| 3657 | void movsd(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVSD, 0x0F11, E_MANDATORY_PREFIX_F2, R(src), W(dst));} | ||
| 3658 | void movupd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVUPD, 0x0F10, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3659 | void movupd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVUPD, 0x0F10, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3660 | void movupd(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVUPD, 0x0F11, E_MANDATORY_PREFIX_66, R(src), W(dst));} | ||
| 3661 | void mulpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MULPD, 0x0F59, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3662 | void mulpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MULPD, 0x0F59, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3663 | void mulsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MULSD, 0x0F59, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3664 | void mulsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MULSD, 0x0F59, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3665 | void orpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ORPD, 0x0F56, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3666 | void orpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ORPD, 0x0F56, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3667 | void packsswb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PACKSSWB, 0x0F63, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3668 | void packsswb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PACKSSWB, 0x0F63, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3669 | ✗ | void packssdw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PACKSSDW, 0x0F6B, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | |
| 3670 | void packssdw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PACKSSDW, 0x0F6B, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3671 | ✗ | void packuswb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PACKUSWB, 0x0F67, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | |
| 3672 | void packuswb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PACKUSWB, 0x0F67, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3673 | void paddb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDB, 0x0FFC, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3674 | void paddb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDB, 0x0FFC, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3675 | void paddw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDW, 0x0FFD, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3676 | void paddw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDW, 0x0FFD, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3677 | void paddd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDD, 0x0FFE, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3678 | ✗ | void paddd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDD, 0x0FFE, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | |
| 3679 | void paddq(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDQ, 0x0FD4, 0, RW(dst), R(src));} | ||
| 3680 | void paddq(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDQ, 0x0FD4, 0, RW(dst), R(src));} | ||
| 3681 | ✗ | void paddq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDQ, 0x0FD4, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | |
| 3682 | void paddq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDQ, 0x0FD4, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3683 | void paddsb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDSB, 0x0FEC, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3684 | void paddsb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDSB, 0x0FEC, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3685 | void paddsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDSW, 0x0FED, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3686 | void paddsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDSW, 0x0FED, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3687 | void paddusb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDUSB, 0x0FDC, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3688 | void paddusb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDUSB, 0x0FDC, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3689 | void paddusw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDUSW, 0x0FDD, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3690 | void paddusw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDUSW, 0x0FDD, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3691 | void pand(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PAND, 0x0FDB, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3692 | void pand(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PAND, 0x0FDB, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3693 | void pandn(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PANDN, 0x0FDF, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3694 | void pandn(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PANDN, 0x0FDF, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3695 | void pause() {AppendInstr(I_PAUSE, 0xF390, 0);} | ||
| 3696 | void pavgb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PAVGB, 0x0FE0, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3697 | void pavgb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PAVGB, 0x0FE0, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3698 | void pavgw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PAVGW, 0x0FE3, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3699 | void pavgw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PAVGW, 0x0FE3, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3700 | void pcmpeqb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPEQB, 0x0F74, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3701 | void pcmpeqb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPEQB, 0x0F74, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3702 | void pcmpeqw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPEQW, 0x0F75, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3703 | void pcmpeqw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPEQW, 0x0F75, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3704 | void pcmpeqd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPEQD, 0x0F76, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3705 | void pcmpeqd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPEQD, 0x0F76, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3706 | void pcmpgtb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPGTB, 0x0F64, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3707 | void pcmpgtb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPGTB, 0x0F64, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3708 | void pcmpgtw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPGTW, 0x0F65, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3709 | void pcmpgtw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPGTW, 0x0F65, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3710 | void pcmpgtd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPGTD, 0x0F66, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3711 | void pcmpgtd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPGTD, 0x0F66, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3712 | void pextrw(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0x0FC5, E_MANDATORY_PREFIX_66, W(dst), R(src), i);} | ||
| 3713 | #ifdef JITASM64 | ||
| 3714 | void pextrw(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0x0FC5, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, W(dst), R(src), i);} | ||
| 3715 | #endif | ||
| 3716 | void pinsrw(const XmmReg& dst, const Reg32& src, const Imm8& i) {AppendInstr(I_PINSRW, 0x0FC4, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);} | ||
| 3717 | void pinsrw(const XmmReg& dst, const Mem16& src, const Imm8& i) {AppendInstr(I_PINSRW, 0x0FC4, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);} | ||
| 3718 | #ifdef JITASM64 | ||
| 3719 | void pinsrw(const XmmReg& dst, const Reg64& src, const Imm8& i) {AppendInstr(I_PINSRW, 0x0FC4, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, RW(dst), R(src), i);} | ||
| 3720 | #endif | ||
| 3721 | void pmaddwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMADDWD, 0x0FF5, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3722 | void pmaddwd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMADDWD, 0x0FF5, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3723 | void pmaxsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMAXSW, 0x0FEE, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3724 | void pmaxsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMAXSW, 0x0FEE, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3725 | void pmaxub(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMAXUB, 0x0FDE, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3726 | void pmaxub(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMAXUB, 0x0FDE, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3727 | void pminsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMINSW, 0x0FEA, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3728 | void pminsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMINSW, 0x0FEA, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3729 | void pminub(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMINUB, 0x0FDA, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3730 | void pminub(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMINUB, 0x0FDA, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3731 | void pmovmskb(const Reg32& dst, const XmmReg& src) {AppendInstr(I_PMOVMSKB, 0x0FD7, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3732 | #ifdef JITASM64 | ||
| 3733 | void pmovmskb(const Reg64& dst, const XmmReg& src) {AppendInstr(I_PMOVMSKB, 0x0FD7, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 3734 | #endif | ||
| 3735 | void pmulhuw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULHUW, 0x0FE4, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3736 | void pmulhuw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULHUW, 0x0FE4, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3737 | void pmulhw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULHW, 0x0FE5, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3738 | void pmulhw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULHW, 0x0FE5, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3739 | void pmullw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULLW, 0x0FD5, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3740 | void pmullw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULLW, 0x0FD5, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3741 | void pmuludq(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMULUDQ, 0x0FF4, 0, RW(dst), R(src));} | ||
| 3742 | void pmuludq(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMULUDQ, 0x0FF4, 0, RW(dst), R(src));} | ||
| 3743 | void pmuludq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULUDQ, 0x0FF4, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3744 | void pmuludq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULUDQ, 0x0FF4, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3745 | ✗ | void por(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_POR, 0x0FEB, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | |
| 3746 | void por(const XmmReg& dst, const Mem128& src) {AppendInstr(I_POR, 0x0FEB, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3747 | void psadbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSADBW, 0x0FF6, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3748 | void psadbw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSADBW, 0x0FF6, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3749 | ✗ | void pshufd(const XmmReg& dst, const XmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFD, 0x0F70, E_MANDATORY_PREFIX_66, W(dst), R(src), order);} | |
| 3750 | void pshufd(const XmmReg& dst, const Mem128& src, const Imm8& order) {AppendInstr(I_PSHUFD, 0x0F70, E_MANDATORY_PREFIX_66, W(dst), R(src), order);} | ||
| 3751 | void pshufhw(const XmmReg& dst, const XmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFHW, 0x0F70, E_MANDATORY_PREFIX_F3, W(dst), R(src), order);} | ||
| 3752 | void pshufhw(const XmmReg& dst, const Mem128& src, const Imm8& order) {AppendInstr(I_PSHUFHW, 0x0F70, E_MANDATORY_PREFIX_F3, W(dst), R(src), order);} | ||
| 3753 | ✗ | void pshuflw(const XmmReg& dst, const XmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFLW, 0x0F70, E_MANDATORY_PREFIX_F2, W(dst), R(src), order);} | |
| 3754 | void pshuflw(const XmmReg& dst, const Mem128& src, const Imm8& order) {AppendInstr(I_PSHUFLW, 0x0F70, E_MANDATORY_PREFIX_F2, W(dst), R(src), order);} | ||
| 3755 | void psllw(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSLLW, 0x0FF1, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3756 | void psllw(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSLLW, 0x0FF1, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3757 | void psllw(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSLLW, 0x0F71, E_MANDATORY_PREFIX_66, Imm8(6), RW(dst), count);} | ||
| 3758 | void pslld(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSLLD, 0x0FF2, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3759 | void pslld(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSLLD, 0x0FF2, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3760 | ✗ | void pslld(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSLLD, 0x0F72, E_MANDATORY_PREFIX_66, Imm8(6), RW(dst), count);} | |
| 3761 | void psllq(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSLLQ, 0x0FF3, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3762 | void psllq(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSLLQ, 0x0FF3, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3763 | void psllq(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSLLQ, 0x0F73, E_MANDATORY_PREFIX_66, Imm8(6), RW(dst), count);} | ||
| 3764 | ✗ | void pslldq(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSLLDQ, 0x0F73, E_MANDATORY_PREFIX_66, Imm8(7), RW(dst), count);} | |
| 3765 | void psraw(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSRAW, 0x0FE1, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3766 | void psraw(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSRAW, 0x0FE1, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3767 | void psraw(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSRAW, 0x0F71, E_MANDATORY_PREFIX_66, Imm8(4), RW(dst), count);} | ||
| 3768 | void psrad(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSRAD, 0x0FE2, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3769 | void psrad(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSRAD, 0x0FE2, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3770 | void psrad(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSRAD, 0x0F72, E_MANDATORY_PREFIX_66, Imm8(4), RW(dst), count);} | ||
| 3771 | void psrlw(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSRLW, 0x0FD1, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3772 | void psrlw(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSRLW, 0x0FD1, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3773 | void psrlw(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSRLW, 0x0F71, E_MANDATORY_PREFIX_66, Imm8(2), RW(dst), count);} | ||
| 3774 | void psrld(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSRLD, 0x0FD2, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3775 | void psrld(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSRLD, 0x0FD2, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3776 | ✗ | void psrld(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSRLD, 0x0F72, E_MANDATORY_PREFIX_66, Imm8(2), RW(dst), count);} | |
| 3777 | void psrlq(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSRLQ, 0x0FD3, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3778 | void psrlq(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSRLQ, 0x0FD3, E_MANDATORY_PREFIX_66, RW(dst), R(count));} | ||
| 3779 | void psrlq(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSRLQ, 0x0F73, E_MANDATORY_PREFIX_66, Imm8(2), RW(dst), count);} | ||
| 3780 | ✗ | void psrldq(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSRLDQ, 0x0F73, E_MANDATORY_PREFIX_66, Imm8(3), RW(dst), count);} | |
| 3781 | void psubb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBB, 0x0FF8, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3782 | void psubb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBB, 0x0FF8, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3783 | void psubw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBW, 0x0FF9, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3784 | void psubw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBW, 0x0FF9, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3785 | void psubd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBD, 0x0FFA, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3786 | ✗ | void psubd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBD, 0x0FFA, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | |
| 3787 | void psubq(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBQ, 0x0FFB, 0, RW(dst), R(src));} | ||
| 3788 | void psubq(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBQ, 0x0FFB, 0, RW(dst), R(src));} | ||
| 3789 | void psubq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBQ, 0x0FFB, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3790 | void psubq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBQ, 0x0FFB, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3791 | void psubsb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBSB, 0x0FE8, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3792 | void psubsb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBSB, 0x0FE8, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3793 | void psubsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBSW, 0x0FE9, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3794 | void psubsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBSW, 0x0FE9, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3795 | void psubusb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBUSB, 0x0FD8, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3796 | void psubusb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBUSB, 0x0FD8, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3797 | void psubusw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBUSW, 0x0FD9, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3798 | void psubusw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBUSW, 0x0FD9, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3799 | void punpckhbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKHBW, 0x0F68, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3800 | void punpckhbw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKHBW, 0x0F68, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3801 | ✗ | void punpckhwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKHWD, 0x0F69, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | |
| 3802 | void punpckhwd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKHWD, 0x0F69, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3803 | void punpckhdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKHDQ, 0x0F6A, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3804 | void punpckhdq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKHDQ, 0x0F6A, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3805 | void punpckhqdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKHQDQ, 0x0F6D, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3806 | void punpckhqdq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKHQDQ, 0x0F6D, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3807 | ✗ | void punpcklbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKLBW, 0x0F60, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | |
| 3808 | void punpcklbw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKLBW, 0x0F60, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3809 | ✗ | void punpcklwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKLWD, 0x0F61, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | |
| 3810 | void punpcklwd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKLWD, 0x0F61, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3811 | void punpckldq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKLDQ, 0x0F62, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3812 | void punpckldq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKLDQ, 0x0F62, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3813 | ✗ | void punpcklqdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKLQDQ, 0x0F6C, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | |
| 3814 | void punpcklqdq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKLQDQ, 0x0F6C, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3815 | ✗ | void pxor(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PXOR, 0x0FEF, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | |
| 3816 | void pxor(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PXOR, 0x0FEF, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3817 | void shufpd(const XmmReg& dst, const XmmReg& src, const Imm8& sel) {AppendInstr(I_SHUFPD, 0x0FC6, E_MANDATORY_PREFIX_66, RW(dst), R(src), sel);} | ||
| 3818 | void shufpd(const XmmReg& dst, const Mem128& src, const Imm8& sel) {AppendInstr(I_SHUFPD, 0x0FC6, E_MANDATORY_PREFIX_66, RW(dst), R(src), sel);} | ||
| 3819 | void sqrtpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SQRTPD, 0x0F51, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3820 | void sqrtpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_SQRTPD, 0x0F51, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3821 | void sqrtsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SQRTSD, 0x0F51, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3822 | void sqrtsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_SQRTSD, 0x0F51, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3823 | void subpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SUBPD, 0x0F5C, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3824 | void subpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_SUBPD, 0x0F5C, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3825 | void subsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SUBSD, 0x0F5C, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3826 | void subsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_SUBSD, 0x0F5C, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3827 | void ucomisd(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UCOMISD, 0x0F2E, E_MANDATORY_PREFIX_66, R(src1), R(src2));} | ||
| 3828 | void ucomisd(const XmmReg& src1, const Mem64& src2) {AppendInstr(I_UCOMISD, 0x0F2E, E_MANDATORY_PREFIX_66, R(src1), R(src2));} | ||
| 3829 | void unpckhpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_UNPCKHPD, 0x0F15, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3830 | void unpckhpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_UNPCKHPD, 0x0F15, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3831 | void unpcklpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_UNPCKLPD, 0x0F14, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3832 | void unpcklpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_UNPCKLPD, 0x0F14, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3833 | void xorpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_XORPD, 0x0F57, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3834 | void xorpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_XORPD, 0x0F57, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3835 | |||
| 3836 | // SSE3 | ||
| 3837 | void addsubps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ADDSUBPS, 0x0FD0, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3838 | void addsubps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ADDSUBPS, 0x0FD0, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3839 | void addsubpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ADDSUBPD, 0x0FD0, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3840 | void addsubpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ADDSUBPD, 0x0FD0, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3841 | void haddps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_HADDPS, 0x0F7C, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3842 | void haddps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_HADDPS, 0x0F7C, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3843 | void haddpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_HADDPD, 0x0F7C, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3844 | void haddpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_HADDPD, 0x0F7C, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3845 | void hsubps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_HSUBPS, 0x0F7D, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3846 | void hsubps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_HSUBPS, 0x0F7D, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 3847 | void hsubpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_HSUBPD, 0x0F7D, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3848 | void hsubpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_HSUBPD, 0x0F7D, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3849 | void lddqu(const XmmReg& dst, const Mem128& src) {AppendInstr(I_LDDQU, 0x0FF0, E_MANDATORY_PREFIX_F2, W(dst), R(src));} | ||
| 3850 | void monitor() {AppendInstr(I_MONITOR, 0x0F01C8, 0);} | ||
| 3851 | void movddup(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVDDUP, 0x0F12, E_MANDATORY_PREFIX_F2, W(dst), R(src));} | ||
| 3852 | void movddup(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVDDUP, 0x0F12, E_MANDATORY_PREFIX_F2, W(dst), R(src));} | ||
| 3853 | void movshdup(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVSHDUP, 0x0F16, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3854 | void movshdup(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVSHDUP, 0x0F16, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3855 | void movsldup(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVSLDUP, 0x0F12, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3856 | void movsldup(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVSLDUP, 0x0F12, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 3857 | void mwait() {AppendInstr(I_MWAIT, 0x0F01C9, 0);} | ||
| 3858 | |||
| 3859 | // SSSE3 | ||
| 3860 | void pabsb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PABSB, 0x0F381C, 0, RW(dst), R(src));} | ||
| 3861 | void pabsb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PABSB, 0x0F381C, 0, RW(dst), R(src));} | ||
| 3862 | void pabsb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PABSB, 0x0F381C, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3863 | void pabsb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PABSB, 0x0F381C, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3864 | void pabsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PABSW, 0x0F381D, 0, RW(dst), R(src));} | ||
| 3865 | void pabsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PABSW, 0x0F381D, 0, RW(dst), R(src));} | ||
| 3866 | void pabsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PABSW, 0x0F381D, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3867 | void pabsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PABSW, 0x0F381D, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3868 | void pabsd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PABSD, 0x0F381E, 0, RW(dst), R(src));} | ||
| 3869 | void pabsd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PABSD, 0x0F381E, 0, RW(dst), R(src));} | ||
| 3870 | void pabsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PABSD, 0x0F381E, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3871 | void pabsd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PABSD, 0x0F381E, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3872 | void palignr(const MmxReg& dst, const MmxReg& src, const Imm8& n) {AppendInstr(I_PALIGNR, 0x0F3A0F, 0, RW(dst), R(src), n);} | ||
| 3873 | void palignr(const MmxReg& dst, const Mem64& src, const Imm8& n) {AppendInstr(I_PALIGNR, 0x0F3A0F, 0, RW(dst), R(src), n);} | ||
| 3874 | ✗ | void palignr(const XmmReg& dst, const XmmReg& src, const Imm8& n) {AppendInstr(I_PALIGNR, 0x0F3A0F, E_MANDATORY_PREFIX_66, RW(dst), R(src), n);} | |
| 3875 | void palignr(const XmmReg& dst, const Mem128& src, const Imm8& n) {AppendInstr(I_PALIGNR, 0x0F3A0F, E_MANDATORY_PREFIX_66, RW(dst), R(src), n);} | ||
| 3876 | void phaddw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PHADDW, 0x0F3801, 0, RW(dst), R(src));} | ||
| 3877 | void phaddw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PHADDW, 0x0F3801, 0, RW(dst), R(src));} | ||
| 3878 | void phaddw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHADDW, 0x0F3801, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3879 | void phaddw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHADDW, 0x0F3801, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3880 | void phaddd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PHADDD, 0x0F3802, 0, RW(dst), R(src));} | ||
| 3881 | void phaddd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PHADDD, 0x0F3802, 0, RW(dst), R(src));} | ||
| 3882 | void phaddd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHADDD, 0x0F3802, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3883 | void phaddd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHADDD, 0x0F3802, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3884 | void phaddsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PHADDSW, 0x0F3803, 0, RW(dst), R(src));} | ||
| 3885 | void phaddsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PHADDSW, 0x0F3803, 0, RW(dst), R(src));} | ||
| 3886 | void phaddsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHADDSW, 0x0F3803, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3887 | void phaddsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHADDSW, 0x0F3803, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3888 | void phsubw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PHSUBW, 0x0F3805, 0, RW(dst), R(src));} | ||
| 3889 | void phsubw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PHSUBW, 0x0F3805, 0, RW(dst), R(src));} | ||
| 3890 | void phsubw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHSUBW, 0x0F3805, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3891 | void phsubw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHSUBW, 0x0F3805, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3892 | void phsubd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PHSUBD, 0x0F3806, 0, RW(dst), R(src));} | ||
| 3893 | void phsubd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PHSUBD, 0x0F3806, 0, RW(dst), R(src));} | ||
| 3894 | void phsubd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHSUBD, 0x0F3806, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3895 | void phsubd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHSUBD, 0x0F3806, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3896 | void phsubsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PHSUBSW, 0x0F3807, 0, RW(dst), R(src));} | ||
| 3897 | void phsubsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PHSUBSW, 0x0F3807, 0, RW(dst), R(src));} | ||
| 3898 | void phsubsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHSUBSW, 0x0F3807, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3899 | void phsubsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHSUBSW, 0x0F3807, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3900 | void pmaddubsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMADDUBSW,0x0F3804, 0, RW(dst), R(src));} | ||
| 3901 | void pmaddubsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMADDUBSW,0x0F3804, 0, RW(dst), R(src));} | ||
| 3902 | void pmaddubsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMADDUBSW,0x0F3804, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3903 | void pmaddubsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMADDUBSW,0x0F3804, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3904 | void pmulhrsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMULHRSW, 0x0F380B, 0, RW(dst), R(src));} | ||
| 3905 | void pmulhrsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMULHRSW, 0x0F380B, 0, RW(dst), R(src));} | ||
| 3906 | void pmulhrsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULHRSW, 0x0F380B, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3907 | void pmulhrsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULHRSW, 0x0F380B, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3908 | void pshufb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSHUFB, 0x0F3800, 0, RW(dst), R(src));} | ||
| 3909 | void pshufb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSHUFB, 0x0F3800, 0, RW(dst), R(src));} | ||
| 3910 | void pshufb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSHUFB, 0x0F3800, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3911 | ✗ | void pshufb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSHUFB, 0x0F3800, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | |
| 3912 | void psignb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSIGNB, 0x0F3808, 0, RW(dst), R(src));} | ||
| 3913 | void psignb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSIGNB, 0x0F3808, 0, RW(dst), R(src));} | ||
| 3914 | void psignb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSIGNB, 0x0F3808, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3915 | void psignb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSIGNB, 0x0F3808, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3916 | void psignw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSIGNW, 0x0F3809, 0, RW(dst), R(src));} | ||
| 3917 | void psignw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSIGNW, 0x0F3809, 0, RW(dst), R(src));} | ||
| 3918 | void psignw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSIGNW, 0x0F3809, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3919 | void psignw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSIGNW, 0x0F3809, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3920 | void psignd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSIGND, 0x0F380A, 0, RW(dst), R(src));} | ||
| 3921 | void psignd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSIGND, 0x0F380A, 0, RW(dst), R(src));} | ||
| 3922 | void psignd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSIGND, 0x0F380A, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3923 | void psignd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSIGND, 0x0F380A, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3924 | |||
| 3925 | // SSE4.1 | ||
| 3926 | void blendps(const XmmReg& dst, const XmmReg& src, const Imm8& mask) {AppendInstr(I_BLENDPS, 0x0F3A0C, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);} | ||
| 3927 | void blendps(const XmmReg& dst, const Mem128& src, const Imm8& mask) {AppendInstr(I_BLENDPS, 0x0F3A0C, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);} | ||
| 3928 | void blendpd(const XmmReg& dst, const XmmReg& src, const Imm8& mask) {AppendInstr(I_BLENDPD, 0x0F3A0D, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);} | ||
| 3929 | void blendpd(const XmmReg& dst, const Mem128& src, const Imm8& mask) {AppendInstr(I_BLENDPD, 0x0F3A0D, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);} | ||
| 3930 | void blendvps(const XmmReg& dst, const XmmReg& src, const XmmReg& mask) {AppendInstr(I_BLENDVPS, 0x0F3814, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));} | ||
| 3931 | void blendvps(const XmmReg& dst, const Mem128& src, const XmmReg& mask) {AppendInstr(I_BLENDVPS, 0x0F3814, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));} | ||
| 3932 | void blendvpd(const XmmReg& dst, const XmmReg& src, const XmmReg& mask) {AppendInstr(I_BLENDVPD, 0x0F3815, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));} | ||
| 3933 | void blendvpd(const XmmReg& dst, const Mem128& src, const XmmReg& mask) {AppendInstr(I_BLENDVPD, 0x0F3815, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));} | ||
| 3934 | void dpps(const XmmReg& dst, const XmmReg& src, const Imm8& mask) {AppendInstr(I_DPPS, 0x0F3A40, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);} | ||
| 3935 | void dpps(const XmmReg& dst, const Mem128& src, const Imm8& mask) {AppendInstr(I_DPPS, 0x0F3A40, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);} | ||
| 3936 | void dppd(const XmmReg& dst, const XmmReg& src, const Imm8& mask) {AppendInstr(I_DPPD, 0x0F3A41, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);} | ||
| 3937 | void dppd(const XmmReg& dst, const Mem128& src, const Imm8& mask) {AppendInstr(I_DPPD, 0x0F3A41, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);} | ||
| 3938 | void extractps(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_EXTRACTPS,0x0F3A17, E_MANDATORY_PREFIX_66, R(src), W(dst), i);} | ||
| 3939 | void extractps(const Mem32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_EXTRACTPS,0x0F3A17, E_MANDATORY_PREFIX_66, R(src), W(dst), i);} | ||
| 3940 | #ifdef JITASM64 | ||
| 3941 | void extractps(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_EXTRACTPS,0x0F3A17, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst), i);} | ||
| 3942 | #endif | ||
| 3943 | void insertps(const XmmReg& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_INSERTPS, 0x0F3A21, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);} | ||
| 3944 | void insertps(const XmmReg& dst, const Mem32& src, const Imm8& i) {AppendInstr(I_INSERTPS, 0x0F3A21, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);} | ||
| 3945 | void movntdqa(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVNTDQA, 0x0F382A, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3946 | void mpsadbw(const XmmReg& dst, const XmmReg& src, const Imm8& offsets) {AppendInstr(I_MPSADBW, 0x0F3A42, E_MANDATORY_PREFIX_66, RW(dst), R(src), offsets);} | ||
| 3947 | void mpsadbw(const XmmReg& dst, const Mem128& src, const Imm8& offsets) {AppendInstr(I_MPSADBW, 0x0F3A42, E_MANDATORY_PREFIX_66, RW(dst), R(src), offsets);} | ||
| 3948 | ✗ | void packusdw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PACKUSDW, 0x0F382B, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | |
| 3949 | void packusdw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PACKUSDW, 0x0F382B, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3950 | void pblendvb(const XmmReg& dst, const XmmReg& src, const XmmReg& mask) {AppendInstr(I_PBLENDVB, 0x0F3810, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));} | ||
| 3951 | void pblendvb(const XmmReg& dst, const Mem128& src, const XmmReg& mask) {AppendInstr(I_PBLENDVB, 0x0F3810, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));} | ||
| 3952 | void pblendw(const XmmReg& dst, const XmmReg& src, const Imm8& mask) {AppendInstr(I_PBLENDW, 0x0F3A0E, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);} | ||
| 3953 | void pblendw(const XmmReg& dst, const Mem128& src, const Imm8& mask) {AppendInstr(I_PBLENDW, 0x0F3A0E, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);} | ||
| 3954 | void pcmpeqq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPEQQ, 0x0F3829, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3955 | void pcmpeqq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPEQQ, 0x0F3829, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3956 | void pextrb(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRB, 0x0F3A14, E_MANDATORY_PREFIX_66, R(src), W(dst), i);} | ||
| 3957 | void pextrb(const Mem8& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRB, 0x0F3A14, E_MANDATORY_PREFIX_66, R(src), W(dst), i);} | ||
| 3958 | void pextrw(const Mem16& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0x0F3A15, E_MANDATORY_PREFIX_66, R(src), W(dst), i);} | ||
| 3959 | void pextrd(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRD, 0x0F3A16, E_MANDATORY_PREFIX_66, R(src), W(dst), i);} | ||
| 3960 | void pextrd(const Mem32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRD, 0x0F3A16, E_MANDATORY_PREFIX_66, R(src), W(dst), i);} | ||
| 3961 | #ifdef JITASM64 | ||
| 3962 | void pextrb(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRB, 0x0F3A14, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst), i);} | ||
| 3963 | void pextrd(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRD, 0x0F3A16, E_MANDATORY_PREFIX_66, R(src), W(dst), i);} | ||
| 3964 | void pextrq(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRQ, 0x0F3A16, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst), i);} | ||
| 3965 | void pextrq(const Mem64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRQ, 0x0F3A16, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst), i);} | ||
| 3966 | #endif | ||
| 3967 | void phminposuw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHMINPOSUW, 0x0F3841, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3968 | void phminposuw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHMINPOSUW, 0x0F3841, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3969 | void pinsrb(const XmmReg& dst, const Reg32& src, const Imm8& i) {AppendInstr(I_PINSRB, 0x0F3A20, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);} | ||
| 3970 | void pinsrb(const XmmReg& dst, const Mem8& src, const Imm8& i) {AppendInstr(I_PINSRB, 0x0F3A20, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);} | ||
| 3971 | void pinsrd(const XmmReg& dst, const Reg32& src, const Imm8& i) {AppendInstr(I_PINSRD, 0x0F3A22, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);} | ||
| 3972 | void pinsrd(const XmmReg& dst, const Mem32& src, const Imm8& i) {AppendInstr(I_PINSRD, 0x0F3A22, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);} | ||
| 3973 | #ifdef JITASM64 | ||
| 3974 | void pinsrb(const XmmReg& dst, const Reg64& src, const Imm8& i) {AppendInstr(I_PINSRB, 0x0F3A20, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);} | ||
| 3975 | void pinsrd(const XmmReg& dst, const Reg64& src, const Imm8& i) {AppendInstr(I_PINSRD, 0x0F3A22, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);} | ||
| 3976 | void pinsrq(const XmmReg& dst, const Reg64& src, const Imm8& i) {AppendInstr(I_PINSRQ, 0x0F3A22, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, RW(dst), R(src), i);} | ||
| 3977 | void pinsrq(const XmmReg& dst, const Mem64& src, const Imm8& i) {AppendInstr(I_PINSRQ, 0x0F3A22, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, RW(dst), R(src), i);} | ||
| 3978 | #endif | ||
| 3979 | void pmaxsb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMAXSB, 0x0F383C, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3980 | void pmaxsb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMAXSB, 0x0F383C, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3981 | void pmaxsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMAXSD, 0x0F383D, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3982 | void pmaxsd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMAXSD, 0x0F383D, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3983 | void pmaxuw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMAXUW, 0x0F383E, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3984 | void pmaxuw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMAXUW, 0x0F383E, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3985 | void pmaxud(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMAXUD, 0x0F383F, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3986 | void pmaxud(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMAXUD, 0x0F383F, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3987 | void pminsb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMINSB, 0x0F3838, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3988 | void pminsb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMINSB, 0x0F3838, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3989 | void pminsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMINSD, 0x0F3839, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3990 | void pminsd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMINSD, 0x0F3839, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3991 | void pminuw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMINUW, 0x0F383A, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3992 | void pminuw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMINUW, 0x0F383A, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3993 | void pminud(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMINUD, 0x0F383B, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3994 | void pminud(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMINUD, 0x0F383B, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 3995 | void pmovsxbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBW, 0x0F3820, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3996 | void pmovsxbw(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXBW, 0x0F3820, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3997 | void pmovsxbd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBD, 0x0F3821, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3998 | void pmovsxbd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVSXBD, 0x0F3821, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 3999 | void pmovsxbq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBQ, 0x0F3822, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4000 | void pmovsxbq(const XmmReg& dst, const Mem16& src) {AppendInstr(I_PMOVSXBQ, 0x0F3822, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4001 | void pmovsxwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXWD, 0x0F3823, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4002 | void pmovsxwd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXWD, 0x0F3823, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4003 | void pmovsxwq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXWQ, 0x0F3824, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4004 | void pmovsxwq(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVSXWQ, 0x0F3824, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4005 | void pmovsxdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXDQ, 0x0F3825, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4006 | void pmovsxdq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXDQ, 0x0F3825, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4007 | void pmovzxbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBW, 0x0F3830, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4008 | void pmovzxbw(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXBW, 0x0F3830, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4009 | void pmovzxbd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBD, 0x0F3831, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4010 | void pmovzxbd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVZXBD, 0x0F3831, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4011 | void pmovzxbq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBQ, 0x0F3832, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4012 | void pmovzxbq(const XmmReg& dst, const Mem16& src) {AppendInstr(I_PMOVZXBQ, 0x0F3832, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4013 | void pmovzxwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXWD, 0x0F3833, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4014 | void pmovzxwd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXWD, 0x0F3833, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4015 | void pmovzxwq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXWQ, 0x0F3834, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4016 | void pmovzxwq(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVZXWQ, 0x0F3834, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4017 | void pmovzxdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXDQ, 0x0F3835, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4018 | void pmovzxdq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXDQ, 0x0F3835, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4019 | void pmuldq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULDQ, 0x0F3828, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 4020 | void pmuldq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULDQ, 0x0F3828, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 4021 | void pmulld(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULLD, 0x0F3840, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 4022 | void pmulld(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULLD, 0x0F3840, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 4023 | void ptest(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PTEST, 0x0F3817, E_MANDATORY_PREFIX_66, R(src1), R(src2));} | ||
| 4024 | void ptest(const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PTEST, 0x0F3817, E_MANDATORY_PREFIX_66, R(src1), R(src2));} | ||
| 4025 | ✗ | void roundps(const XmmReg& dst, const XmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDPS, 0x0F3A08, E_MANDATORY_PREFIX_66, W(dst), R(src), mode);} | |
| 4026 | void roundps(const XmmReg& dst, const Mem128& src, const Imm8& mode) {AppendInstr(I_ROUNDPS, 0x0F3A08, E_MANDATORY_PREFIX_66, W(dst), R(src), mode);} | ||
| 4027 | void roundpd(const XmmReg& dst, const XmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDPD, 0x0F3A09, E_MANDATORY_PREFIX_66, W(dst), R(src), mode);} | ||
| 4028 | void roundpd(const XmmReg& dst, const Mem128& src, const Imm8& mode) {AppendInstr(I_ROUNDPD, 0x0F3A09, E_MANDATORY_PREFIX_66, W(dst), R(src), mode);} | ||
| 4029 | void roundss(const XmmReg& dst, const XmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDSS, 0x0F3A0A, E_MANDATORY_PREFIX_66, RW(dst), R(src), mode);} | ||
| 4030 | void roundss(const XmmReg& dst, const Mem32& src, const Imm8& mode) {AppendInstr(I_ROUNDSS, 0x0F3A0A, E_MANDATORY_PREFIX_66, RW(dst), R(src), mode);} | ||
| 4031 | void roundsd(const XmmReg& dst, const XmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDSD, 0x0F3A0B, E_MANDATORY_PREFIX_66, RW(dst), R(src), mode);} | ||
| 4032 | void roundsd(const XmmReg& dst, const Mem64& src, const Imm8& mode) {AppendInstr(I_ROUNDSD, 0x0F3A0B, E_MANDATORY_PREFIX_66, RW(dst), R(src), mode);} | ||
| 4033 | |||
| 4034 | // SSE4.2 | ||
| 4035 | void crc32(const Reg32& dst, const Reg8& src) {AppendInstr(I_CRC32, 0x0F38F0, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 4036 | void crc32(const Reg32& dst, const Mem8& src) {AppendInstr(I_CRC32, 0x0F38F0, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 4037 | void crc32(const Reg32& dst, const Reg16& src) {AppendInstr(I_CRC32, 0x0F38F1, E_MANDATORY_PREFIX_F2 | E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 4038 | void crc32(const Reg32& dst, const Mem16& src) {AppendInstr(I_CRC32, 0x0F38F1, E_MANDATORY_PREFIX_F2 | E_OPERAND_SIZE_PREFIX, RW(dst), R(src));} | ||
| 4039 | void crc32(const Reg32& dst, const Reg32& src) {AppendInstr(I_CRC32, 0x0F38F1, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 4040 | void crc32(const Reg32& dst, const Mem32& src) {AppendInstr(I_CRC32, 0x0F38F1, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} | ||
| 4041 | #ifdef JITASM64 | ||
| 4042 | void crc32(const Reg64& dst, const Reg8& src) {AppendInstr(I_CRC32, 0x0F38F0, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));} | ||
| 4043 | void crc32(const Reg64& dst, const Mem8& src) {AppendInstr(I_CRC32, 0x0F38F0, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));} | ||
| 4044 | void crc32(const Reg64& dst, const Reg64& src) {AppendInstr(I_CRC32, 0x0F38F1, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));} | ||
| 4045 | void crc32(const Reg64& dst, const Mem64& src) {AppendInstr(I_CRC32, 0x0F38F1, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));} | ||
| 4046 | #endif | ||
| 4047 | void pcmpestri(const Reg& result, const XmmReg& src1, const Reg& len1, const XmmReg& src2, const Reg& len2, const Imm8& mode) {AppendInstr(I_PCMPESTRI, 0x0F3A61, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), ecx), Dummy(R(len1), eax), Dummy(R(len2), edx));} | ||
| 4048 | void pcmpestri(const Reg& result, const XmmReg& src1, const Reg& len1, const Mem128& src2, const Reg& len2, const Imm8& mode) {AppendInstr(I_PCMPESTRI, 0x0F3A61, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), ecx), Dummy(R(len1), eax), Dummy(R(len2), edx));} | ||
| 4049 | void pcmpestrm(const XmmReg& result, const XmmReg& src1, const Reg& len1, const XmmReg& src2, const Reg& len2, const Imm8& mode){AppendInstr(I_PCMPESTRM, 0x0F3A60, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), xmm0), Dummy(R(len1), eax), Dummy(R(len2), edx));} | ||
| 4050 | void pcmpestrm(const XmmReg& result, const XmmReg& src1, const Reg& len1, const Mem128& src2, const Reg& len2, const Imm8& mode){AppendInstr(I_PCMPESTRM, 0x0F3A60, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), xmm0), Dummy(R(len1), eax), Dummy(R(len2), edx));} | ||
| 4051 | void pcmpistri(const Reg& result, const XmmReg& src1, const XmmReg& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRI, 0x0F3A63, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), ecx));} | ||
| 4052 | void pcmpistri(const Reg& result, const XmmReg& src1, const Mem128& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRI, 0x0F3A63, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), ecx));} | ||
| 4053 | void pcmpistrm(const XmmReg& result, const XmmReg& src1, const XmmReg& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRM, 0x0F3A62, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), xmm0));} | ||
| 4054 | void pcmpistrm(const XmmReg& result, const XmmReg& src1, const Mem128& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRM, 0x0F3A62, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), xmm0));} | ||
| 4055 | void pcmpgtq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPGTQ, 0x0F3837, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 4056 | void pcmpgtq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPGTQ, 0x0F3837, E_MANDATORY_PREFIX_66, RW(dst), R(src));} | ||
| 4057 | void popcnt(const Reg16& dst, const Reg16& src) {AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 4058 | void popcnt(const Reg16& dst, const Mem16& src) {AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 4059 | void popcnt(const Reg32& dst, const Reg32& src) {AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 4060 | void popcnt(const Reg32& dst, const Mem32& src) {AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 4061 | #ifdef JITASM64 | ||
| 4062 | void popcnt(const Reg64& dst, const Reg64& src) {AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 4063 | void popcnt(const Reg64& dst, const Mem64& src) {AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 4064 | #endif | ||
| 4065 | |||
| 4066 | // AVX | ||
| 4067 | void vaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ADDPD, 0x58, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4068 | void vaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ADDPD, 0x58, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4069 | void vaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ADDPD, 0x58, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4070 | void vaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ADDPD, 0x58, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4071 | void vaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ADDPS, 0x58, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4072 | void vaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ADDPS, 0x58, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4073 | ✗ | void vaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ADDPS, 0x58, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4074 | ✗ | void vaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ADDPS, 0x58, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4075 | void vaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ADDSD, 0x58, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4076 | void vaddsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_ADDSD, 0x58, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4077 | void vaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ADDSS, 0x58, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));} | ||
| 4078 | void vaddss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_ADDSS, 0x58, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));} | ||
| 4079 | void vaddsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ADDSUBPD, 0xD0, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4080 | void vaddsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ADDSUBPD, 0xD0, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4081 | void vaddsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ADDSUBPD, 0xD0, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4082 | void vaddsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ADDSUBPD, 0xD0, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4083 | void vaddsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ADDSUBPS, 0xD0, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4084 | void vaddsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ADDSUBPS, 0xD0, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4085 | void vaddsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ADDSUBPS, 0xD0, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4086 | void vaddsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ADDSUBPS, 0xD0, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4087 | void aesenc(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_AESENC, 0x0F38DC, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4088 | void aesenc(const XmmReg& dst, const Mem128& src) {AppendInstr(I_AESENC, 0x0F38DC, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4089 | void vaesenc(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_AESENC, 0xDC, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4090 | void vaesenc(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_AESENC, 0xDC, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4091 | void aesenclast(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_AESENCLAST, 0x0F38DD, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4092 | void aesenclast(const XmmReg& dst, const Mem128& src) {AppendInstr(I_AESENCLAST, 0x0F38DD, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4093 | void vaesenclast(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_AESENCLAST, 0xDD, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4094 | void vaesenclast(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_AESENCLAST, 0xDD, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4095 | void aesdec(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_AESDEC, 0x0F38DE, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4096 | void aesdec(const XmmReg& dst, const Mem128& src) {AppendInstr(I_AESDEC, 0x0F38DE, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4097 | void vaesdec(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_AESDEC, 0xDE, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4098 | void vaesdec(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_AESDEC, 0xDE, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4099 | void aesdeclast(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_AESDECLAST, 0x0F38DF, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4100 | void aesdeclast(const XmmReg& dst, const Mem128& src) {AppendInstr(I_AESDECLAST, 0x0F38DF, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4101 | void vaesdeclast(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_AESDECLAST, 0xDF, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4102 | void vaesdeclast(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_AESDECLAST, 0xDF, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4103 | void aesimc(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_AESIMC, 0x0F38DB, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4104 | void aesimc(const XmmReg& dst, const Mem128& src) {AppendInstr(I_AESIMC, 0x0F38DB, E_MANDATORY_PREFIX_66, W(dst), R(src));} | ||
| 4105 | void vaesimc(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_AESIMC, 0xDB, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4106 | void vaesimc(const XmmReg& dst, const Mem128& src) {AppendInstr(I_AESIMC, 0xDB, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4107 | void aeskeygenassist(const XmmReg& dst, const XmmReg& src, const Imm8& imm) {AppendInstr(I_AESKEYGENASSIST, 0x0F3ADF, E_MANDATORY_PREFIX_66, W(dst), R(src), imm);} | ||
| 4108 | void aeskeygenassist(const XmmReg& dst, const Mem128& src, const Imm8& imm) {AppendInstr(I_AESKEYGENASSIST, 0x0F3ADF, E_MANDATORY_PREFIX_66, W(dst), R(src), imm);} | ||
| 4109 | void vaeskeygenassist(const XmmReg& dst, const XmmReg& src, const Imm8& imm) {AppendInstr(I_AESKEYGENASSIST, 0xDF, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src), imm);} | ||
| 4110 | void vaeskeygenassist(const XmmReg& dst, const Mem128& src, const Imm8& imm) {AppendInstr(I_AESKEYGENASSIST, 0xDF, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src), imm);} | ||
| 4111 | void vandpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ANDPD, 0x54, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4112 | void vandpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ANDPD, 0x54, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4113 | void vandpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ANDPD, 0x54, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4114 | void vandpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ANDPD, 0x54, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4115 | void vandps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ANDPS, 0x54, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4116 | void vandps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ANDPS, 0x54, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4117 | ✗ | void vandps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ANDPS, 0x54, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4118 | ✗ | void vandps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ANDPS, 0x54, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4119 | void vandnpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ANDNPD, 0x55, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4120 | void vandnpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ANDNPD, 0x55, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4121 | void vandnpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ANDNPD, 0x55, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4122 | void vandnpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ANDNPD, 0x55, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4123 | void vandnps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ANDNPS, 0x55, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4124 | void vandnps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ANDNPS, 0x55, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4125 | ✗ | void vandnps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ANDNPS, 0x55, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4126 | void vandnps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ANDNPS, 0x55, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4127 | void vblendpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_BLENDPD, 0x0D, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4128 | void vblendpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_BLENDPD, 0x0D, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4129 | void vblendpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask) {AppendInstr(I_BLENDPD, 0x0D, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4130 | void vblendpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask) {AppendInstr(I_BLENDPD, 0x0D, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4131 | void vblendps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_BLENDPS, 0x0C, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4132 | void vblendps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_BLENDPS, 0x0C, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4133 | ✗ | void vblendps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask) {AppendInstr(I_BLENDPS, 0x0C, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | |
| 4134 | void vblendps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask) {AppendInstr(I_BLENDPS, 0x0C, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4135 | void vblendvpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& mask) {AppendInstr(I_BLENDVPD, 0x4B, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));} | ||
| 4136 | void vblendvpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& mask) {AppendInstr(I_BLENDVPD, 0x4B, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));} | ||
| 4137 | void vblendvpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& mask) {AppendInstr(I_BLENDVPD, 0x4B, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));} | ||
| 4138 | void vblendvpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& mask) {AppendInstr(I_BLENDVPD, 0x4B, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));} | ||
| 4139 | void vblendvps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& mask) {AppendInstr(I_BLENDVPS, 0x4A, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));} | ||
| 4140 | void vblendvps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& mask) {AppendInstr(I_BLENDVPS, 0x4A, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));} | ||
| 4141 | ✗ | void vblendvps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& mask) {AppendInstr(I_BLENDVPS, 0x4A, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));} | |
| 4142 | void vblendvps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& mask) {AppendInstr(I_BLENDVPS, 0x4A, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));} | ||
| 4143 | void vbroadcastss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_VBROADCASTSS, 0x18, E_VEX_128_66_0F38_W0, W(dst), R(src));} | ||
| 4144 | void vbroadcastss(const YmmReg& dst, const Mem32& src) {AppendInstr(I_VBROADCASTSS, 0x18, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 4145 | void vbroadcastsd(const YmmReg& dst, const Mem64 src) {AppendInstr(I_VBROADCASTSD, 0x19, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 4146 | void vbroadcastf128(const YmmReg& dst, const Mem128& src) {AppendInstr(I_VBROADCASTF128, 0x1A, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 4147 | void vcmppd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& imm) {AppendInstr(I_CMPPD, 0xC2, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1), imm);} | ||
| 4148 | void vcmppd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& imm) {AppendInstr(I_CMPPD, 0xC2, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1), imm);} | ||
| 4149 | void vcmppd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& imm) {AppendInstr(I_CMPPD, 0xC2, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1), imm);} | ||
| 4150 | void vcmppd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& imm) {AppendInstr(I_CMPPD, 0xC2, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1), imm);} | ||
| 4151 | void vcmpps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& imm) {AppendInstr(I_CMPPS, 0xC2, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1), imm);} | ||
| 4152 | void vcmpps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& imm) {AppendInstr(I_CMPPS, 0xC2, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1), imm);} | ||
| 4153 | ✗ | void vcmpps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& imm) {AppendInstr(I_CMPPS, 0xC2, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1), imm);} | |
| 4154 | ✗ | void vcmpps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& imm) {AppendInstr(I_CMPPS, 0xC2, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1), imm);} | |
| 4155 | void vcmpsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& imm) {AppendInstr(I_CMPSD, 0xC2, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1), imm);} | ||
| 4156 | void vcmpsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const Imm8& imm) {AppendInstr(I_CMPSD, 0xC2, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1), imm);} | ||
| 4157 | void vcmpss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& imm) {AppendInstr(I_CMPSS, 0xC2, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1), imm);} | ||
| 4158 | void vcmpss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const Imm8& imm) {AppendInstr(I_CMPSS, 0xC2, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1), imm);} | ||
| 4159 | void vcomisd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_COMISD, 0x2F, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4160 | void vcomisd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_COMISD, 0x2F, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4161 | void vcomiss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_COMISS, 0x2F, E_VEX_LIG | E_VEX_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4162 | void vcomiss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_COMISS, 0x2F, E_VEX_LIG | E_VEX_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4163 | void vcvtdq2pd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTDQ2PD, 0xE6, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src));} | ||
| 4164 | void vcvtdq2pd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTDQ2PD, 0xE6, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src));} | ||
| 4165 | void vcvtdq2pd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTDQ2PD, 0xE6, E_VEX_256 | E_VEX_F3_0F, W(dst), R(src));} | ||
| 4166 | void vcvtdq2pd(const YmmReg& dst, const Mem128& src) {AppendInstr(I_CVTDQ2PD, 0xE6, E_VEX_256 | E_VEX_F3_0F, W(dst), R(src));} | ||
| 4167 | ✗ | void vcvtdq2ps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTDQ2PS, 0x5B, E_VEX_128_0F_WIG, W(dst), R(src));} | |
| 4168 | void vcvtdq2ps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTDQ2PS, 0x5B, E_VEX_128_0F_WIG, W(dst), R(src));} | ||
| 4169 | ✗ | void vcvtdq2ps(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_CVTDQ2PS, 0x5B, E_VEX_256_0F_WIG, W(dst), R(src));} | |
| 4170 | void vcvtdq2ps(const YmmReg& dst, const Mem256& src) {AppendInstr(I_CVTDQ2PS, 0x5B, E_VEX_256_0F_WIG, W(dst), R(src));} | ||
| 4171 | void vcvtpd2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPD2DQ, 0xE6, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src));} | ||
| 4172 | void vcvtpd2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPD2DQ, 0xE6, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src));} | ||
| 4173 | void vcvtpd2dq(const XmmReg& dst, const YmmReg& src) {AppendInstr(I_CVTPD2DQ, 0xE6, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src));} | ||
| 4174 | void vcvtpd2dq(const XmmReg& dst, const Mem256& src) {AppendInstr(I_CVTPD2DQ, 0xE6, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src));} | ||
| 4175 | void vcvtpd2ps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPD2PS, 0x5A, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4176 | void vcvtpd2ps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPD2PS, 0x5A, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4177 | void vcvtpd2ps(const XmmReg& dst, const YmmReg& src) {AppendInstr(I_CVTPD2PS, 0x5A, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4178 | void vcvtpd2ps(const XmmReg& dst, const Mem256& src) {AppendInstr(I_CVTPD2PS, 0x5A, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4179 | void vcvtps2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPS2DQ, 0x5B, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4180 | void vcvtps2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPS2DQ, 0x5B, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4181 | void vcvtps2dq(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_CVTPS2DQ, 0x5B, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4182 | void vcvtps2dq(const YmmReg& dst, const Mem256& src) {AppendInstr(I_CVTPS2DQ, 0x5B, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4183 | void vcvtps2pd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPS2PD, 0x5A, E_VEX_128_0F_WIG, W(dst), R(src));} | ||
| 4184 | void vcvtps2pd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTPS2PD, 0x5A, E_VEX_128_0F_WIG, W(dst), R(src));} | ||
| 4185 | void vcvtps2pd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPS2PD, 0x5A, E_VEX_256_0F_WIG, W(dst), R(src));} | ||
| 4186 | void vcvtps2pd(const YmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPS2PD, 0x5A, E_VEX_256_0F_WIG, W(dst), R(src));} | ||
| 4187 | void vcvtsd2si(const Reg32 dst, const XmmReg& src) {AppendInstr(I_CVTSD2SI, 0x2D, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src));} | ||
| 4188 | void vcvtsd2si(const Reg32 dst, const Mem64& src) {AppendInstr(I_CVTSD2SI, 0x2D, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src));} | ||
| 4189 | #ifdef JITASM64 | ||
| 4190 | void vcvtsd2si(const Reg64 dst, const XmmReg& src) {AppendInstr(I_CVTSD2SI, 0x2D, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src));} | ||
| 4191 | void vcvtsd2si(const Reg64 dst, const Mem64& src) {AppendInstr(I_CVTSD2SI, 0x2D, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src));} | ||
| 4192 | #endif | ||
| 4193 | void vcvtsd2ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_CVTSD2SS, 0x5A, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4194 | void vcvtsd2ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_CVTSD2SS, 0x5A, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4195 | void vcvtsi2sd(const XmmReg& dst, const XmmReg& src1, const Reg32& src2) {AppendInstr(I_CVTSI2SD, 0x2A, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src2), R(src1));} | ||
| 4196 | void vcvtsi2sd(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_CVTSI2SD, 0x2A, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src2), R(src1));} | ||
| 4197 | #ifdef JITASM64 | ||
| 4198 | void vcvtsi2sd(const XmmReg& dst, const XmmReg& src1, const Reg64& src2) {AppendInstr(I_CVTSI2SD, 0x2A, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src2), R(src1));} | ||
| 4199 | void vcvtsi2sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_CVTSI2SD, 0x2A, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src2), R(src1));} | ||
| 4200 | #endif | ||
| 4201 | void vcvtsi2ss(const XmmReg& dst, const XmmReg& src1, const Reg32& src2) {AppendInstr(I_CVTSI2SS, 0x2A, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src2), R(src1));} | ||
| 4202 | void vcvtsi2ss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_CVTSI2SS, 0x2A, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src2), R(src1));} | ||
| 4203 | #ifdef JITASM64 | ||
| 4204 | void vcvtsi2ss(const XmmReg& dst, const XmmReg& src1, const Reg64& src2) {AppendInstr(I_CVTSI2SS, 0x2A, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src2), R(src1));} | ||
| 4205 | void vcvtsi2ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_CVTSI2SS, 0x2A, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src2), R(src1));} | ||
| 4206 | #endif | ||
| 4207 | void vcvtss2sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_CVTSS2SD, 0x5A, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));} | ||
| 4208 | void vcvtss2sd(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_CVTSS2SD, 0x5A, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));} | ||
| 4209 | void vcvtss2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SI, 0x2D, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src));} | ||
| 4210 | void vcvtss2si(const Reg32& dst, const Mem32& src) {AppendInstr(I_CVTSS2SI, 0x2D, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src));} | ||
| 4211 | #ifdef JITASM64 | ||
| 4212 | void vcvtss2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SI, 0x2D, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src));} | ||
| 4213 | void vcvtss2si(const Reg64& dst, const Mem32& src) {AppendInstr(I_CVTSS2SI, 0x2D, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src));} | ||
| 4214 | #endif | ||
| 4215 | void vcvttpd2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTTPD2DQ, 0xE6, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4216 | void vcvttpd2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTTPD2DQ, 0xE6, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4217 | void vcvttpd2dq(const XmmReg& dst, const YmmReg& src) {AppendInstr(I_CVTTPD2DQ, 0xE6, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4218 | void vcvttpd2dq(const XmmReg& dst, const Mem256& src) {AppendInstr(I_CVTTPD2DQ, 0xE6, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4219 | void vcvttps2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTTPS2DQ, 0x5B, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src));} | ||
| 4220 | void vcvttps2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTTPS2DQ, 0x5B, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src));} | ||
| 4221 | ✗ | void vcvttps2dq(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_CVTTPS2DQ, 0x5B, E_VEX_256 | E_VEX_F3_0F, W(dst), R(src));} | |
| 4222 | void vcvttps2dq(const YmmReg& dst, const Mem256& src) {AppendInstr(I_CVTTPS2DQ, 0x5B, E_VEX_256 | E_VEX_F3_0F, W(dst), R(src));} | ||
| 4223 | void vcvttsd2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTSD2SI, 0x2C, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src));} | ||
| 4224 | void vcvttsd2si(const Reg32& dst, const Mem64& src) {AppendInstr(I_CVTSD2SI, 0x2C, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src));} | ||
| 4225 | #ifdef JITASM64 | ||
| 4226 | void vcvttsd2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTSD2SI, 0x2C, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src));} | ||
| 4227 | void vcvttsd2si(const Reg64& dst, const Mem64& src) {AppendInstr(I_CVTSD2SI, 0x2C, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src));} | ||
| 4228 | #endif | ||
| 4229 | void vcvttss2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SI, 0x2C, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src));} | ||
| 4230 | void vcvttss2si(const Reg32& dst, const Mem32& src) {AppendInstr(I_CVTSS2SI, 0x2C, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src));} | ||
| 4231 | #ifdef JITASM64 | ||
| 4232 | void vcvttss2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SI, 0x2C, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src));} | ||
| 4233 | void vcvttss2si(const Reg64& dst, const Mem32& src) {AppendInstr(I_CVTSS2SI, 0x2C, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src));} | ||
| 4234 | #endif | ||
| 4235 | void vdivpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_DIVPD, 0x5E, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4236 | void vdivpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_DIVPD, 0x5E, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4237 | void vdivpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_DIVPD, 0x5E, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4238 | void vdivpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_DIVPD, 0x5E, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4239 | void vdivps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_DIVPS, 0x5E, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4240 | void vdivps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_DIVPS, 0x5E, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4241 | ✗ | void vdivps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_DIVPS, 0x5E, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4242 | void vdivps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_DIVPS, 0x5E, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4243 | void vdivsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_DIVSD, 0x5E, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4244 | void vdivsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_DIVSD, 0x5E, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4245 | void vdivss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_DIVSS, 0x5E, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));} | ||
| 4246 | void vdivss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_DIVSS, 0x5E, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));} | ||
| 4247 | void vdppd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_DPPD, 0x41, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4248 | void vdppd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_DPPD, 0x41, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4249 | void vdpps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_DPPS, 0x40, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4250 | void vdpps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_DPPS, 0x40, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4251 | void vdpps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask) {AppendInstr(I_DPPS, 0x40, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4252 | void vdpps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask) {AppendInstr(I_DPPS, 0x40, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4253 | void vextractf128(const XmmReg& dst, const YmmReg& src, const Imm8& i) {AppendInstr(I_VEXTRACTF128, 0x19, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);} | ||
| 4254 | void vextractf128(const Mem128& dst, const YmmReg& src, const Imm8& i) {AppendInstr(I_VEXTRACTF128, 0x19, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);} | ||
| 4255 | void vextractps(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_EXTRACTPS, 0x17, E_VEX_128 | E_VEX_66_0F3A, R(src), W(dst), i);} | ||
| 4256 | void vextractps(const Mem32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_EXTRACTPS, 0x17, E_VEX_128 | E_VEX_66_0F3A, R(src), W(dst), i);} | ||
| 4257 | void vhaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4258 | void vhaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4259 | void vhaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4260 | void vhaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4261 | void vhaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4262 | void vhaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4263 | void vhaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4264 | void vhaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4265 | void vhsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4266 | void vhsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4267 | void vhsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4268 | void vhsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4269 | void vhsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4270 | void vhsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4271 | void vhsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4272 | void vhsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4273 | void vinsertf128(const YmmReg& dst, const YmmReg& src1, const XmmReg& src2, const Imm8& i) {AppendInstr(I_VINSERTF128, 0x18, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);} | ||
| 4274 | void vinsertf128(const YmmReg& dst, const YmmReg& src1, const Mem128& src2, const Imm8& i) {AppendInstr(I_VINSERTF128, 0x18, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);} | ||
| 4275 | void vinsertps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& i) {AppendInstr(I_INSERTPS, 0x21, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);} | ||
| 4276 | void vinsertps(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const Imm8& i) {AppendInstr(I_INSERTPS, 0x21, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);} | ||
| 4277 | void vlddqu(const XmmReg& dst, const Mem128& src) {AppendInstr(I_LDDQU, 0xF0, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src));} | ||
| 4278 | void vlddqu(const YmmReg& dst, const Mem256& src) {AppendInstr(I_LDDQU, 0xF0, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src));} | ||
| 4279 | void vldmxcsr(const Mem32& src) {AppendInstr(I_LDMXCSR, 0xAE, E_VEX_LZ | E_VEX_0F | E_VEX_WIG, Imm8(2), R(src));} | ||
| 4280 | void vmaskmovdqu(const XmmReg& src, const XmmReg& mask, const Reg& dstptr) {AppendInstr(I_MASKMOVDQU, 0xF7, E_VEX_128_66_0F_WIG, R(src), R(mask), Dummy(R(dstptr), zdi));} | ||
| 4281 | void vmaskmovps(const XmmReg& dst, const XmmReg& mask, const Mem128& src) {AppendInstr(I_VMASKMOVPS, 0x2C, E_VEX_128_66_0F38_W0, W(dst), R(src), R(mask));} | ||
| 4282 | void vmaskmovps(const YmmReg& dst, const YmmReg& mask, const Mem256& src) {AppendInstr(I_VMASKMOVPS, 0x2C, E_VEX_256_66_0F38_W0, W(dst), R(src), R(mask));} | ||
| 4283 | void vmaskmovpd(const XmmReg& dst, const XmmReg& mask, const Mem128& src) {AppendInstr(I_VMASKMOVPD, 0x2D, E_VEX_128_66_0F38_W0, W(dst), R(src), R(mask));} | ||
| 4284 | void vmaskmovpd(const YmmReg& dst, const YmmReg& mask, const Mem256& src) {AppendInstr(I_VMASKMOVPD, 0x2D, E_VEX_256_66_0F38_W0, W(dst), R(src), R(mask));} | ||
| 4285 | void vmaskmovps(const Mem128& dst, const XmmReg& mask, const XmmReg& src) {AppendInstr(I_VMASKMOVPS, 0x2E, E_VEX_128_66_0F38_W0, R(src), W(dst), R(mask));} | ||
| 4286 | void vmaskmovps(const Mem256& dst, const YmmReg& mask, const YmmReg& src) {AppendInstr(I_VMASKMOVPS, 0x2E, E_VEX_256_66_0F38_W0, R(src), W(dst), R(mask));} | ||
| 4287 | void vmaskmovpd(const Mem128& dst, const XmmReg& mask, const XmmReg& src) {AppendInstr(I_VMASKMOVPD, 0x2F, E_VEX_128_66_0F38_W0, R(src), W(dst), R(mask));} | ||
| 4288 | void vmaskmovpd(const Mem256& dst, const YmmReg& mask, const YmmReg& src) {AppendInstr(I_VMASKMOVPD, 0x2F, E_VEX_256_66_0F38_W0, R(src), W(dst), R(mask));} | ||
| 4289 | void vmaxpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MAXPD, 0x5F, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4290 | void vmaxpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_MAXPD, 0x5F, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4291 | void vmaxpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_MAXPD, 0x5F, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4292 | void vmaxpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_MAXPD, 0x5F, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4293 | void vmaxps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MAXPS, 0x5F, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4294 | void vmaxps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_MAXPS, 0x5F, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4295 | ✗ | void vmaxps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_MAXPS, 0x5F, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4296 | ✗ | void vmaxps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_MAXPS, 0x5F, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4297 | void vmaxsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MAXSD, 0x5F, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4298 | void vmaxsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MAXSD, 0x5F, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4299 | void vmaxss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MAXSS, 0x5F, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));} | ||
| 4300 | void vmaxss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_MAXSS, 0x5F, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));} | ||
| 4301 | void vminpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MINPD, 0x5D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4302 | void vminpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_MINPD, 0x5D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4303 | void vminpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_MINPD, 0x5D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4304 | void vminpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_MINPD, 0x5D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4305 | void vminps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MINPS, 0x5D, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4306 | void vminps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_MINPS, 0x5D, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4307 | ✗ | void vminps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_MINPS, 0x5D, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4308 | ✗ | void vminps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_MINPS, 0x5D, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4309 | void vminsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MINSD, 0x5D, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4310 | void vminsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MINSD, 0x5D, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));} | ||
| 4311 | void vminss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MINSS, 0x5D, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));} | ||
| 4312 | void vminss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_MINSS, 0x5D, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));} | ||
| 4313 | void vmovapd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVAPD, 0x28, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4314 | void vmovapd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVAPD, 0x28, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4315 | void vmovapd(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVAPD, 0x29, E_VEX_128_66_0F_WIG, R(src), W(dst));} | ||
| 4316 | void vmovapd(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVAPD, 0x28, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4317 | void vmovapd(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVAPD, 0x28, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4318 | void vmovapd(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVAPD, 0x29, E_VEX_256_66_0F_WIG, R(src), W(dst));} | ||
| 4319 | ✗ | void vmovaps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVAPS, 0x28, E_VEX_128_0F_WIG, W(dst), R(src));} | |
| 4320 | ✗ | void vmovaps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVAPS, 0x28, E_VEX_128_0F_WIG, W(dst), R(src));} | |
| 4321 | ✗ | void vmovaps(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVAPS, 0x29, E_VEX_128_0F_WIG, R(src), W(dst));} | |
| 4322 | ✗ | void vmovaps(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVAPS, 0x28, E_VEX_256_0F_WIG, W(dst), R(src));} | |
| 4323 | ✗ | void vmovaps(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVAPS, 0x28, E_VEX_256_0F_WIG, W(dst), R(src));} | |
| 4324 | ✗ | void vmovaps(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVAPS, 0x29, E_VEX_256_0F_WIG, R(src), W(dst));} | |
| 4325 | ✗ | void vmovd(const XmmReg& dst, const Reg32& src) {AppendInstr(I_MOVD, 0x6E, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(src));} | |
| 4326 | ✗ | void vmovd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MOVD, 0x6E, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(src));} | |
| 4327 | void vmovd(const Reg32& dst, const XmmReg& src) {AppendInstr(I_MOVD, 0x7E, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, R(src), W(dst));} | ||
| 4328 | void vmovd(const Mem32& dst, const XmmReg& src) {AppendInstr(I_MOVD, 0x7E, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, R(src), W(dst));} | ||
| 4329 | void vmovq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVQ, 0x7E, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4330 | ✗ | void vmovq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVQ, 0x7E, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | |
| 4331 | ✗ | void vmovq(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVQ, 0xD6, E_VEX_128_66_0F_WIG, R(src), W(dst));} | |
| 4332 | #ifdef JITASM64 | ||
| 4333 | ✗ | void vmovq(const XmmReg& dst, const Reg64& src) {AppendInstr(I_MOVQ, 0x6E, E_VEX_128 | E_VEX_66_0F | E_VEX_W1, W(dst), R(src));} | |
| 4334 | void vmovq(const Reg64& dst, const XmmReg& src) {AppendInstr(I_MOVQ, 0x7E, E_VEX_128 | E_VEX_66_0F | E_VEX_W1, R(src), W(dst));} | ||
| 4335 | #endif | ||
| 4336 | void vmovddup(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVDDUP, 0x12, E_VEX_128 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4337 | void vmovddup(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVDDUP, 0x12, E_VEX_128 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4338 | void vmovddup(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVDDUP, 0x12, E_VEX_256 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4339 | void vmovddup(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVDDUP, 0x12, E_VEX_256 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4340 | void vmovdqa(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVDQA, 0x6F, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4341 | ✗ | void vmovdqa(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVDQA, 0x6F, E_VEX_128_66_0F_WIG, W(dst), R(src));} | |
| 4342 | ✗ | void vmovdqa(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVDQA, 0x7F, E_VEX_128_66_0F_WIG, R(src), W(dst));} | |
| 4343 | void vmovdqa(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVDQA, 0x6F, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4344 | ✗ | void vmovdqa(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVDQA, 0x6F, E_VEX_256_66_0F_WIG, W(dst), R(src));} | |
| 4345 | void vmovdqa(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVDQA, 0x7F, E_VEX_256_66_0F_WIG, R(src), W(dst));} | ||
| 4346 | void vmovdqu(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVDQU, 0x6F, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4347 | ✗ | void vmovdqu(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVDQU, 0x6F, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | |
| 4348 | ✗ | void vmovdqu(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVDQU, 0x7F, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, R(src), W(dst));} | |
| 4349 | void vmovdqu(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVDQU, 0x6F, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4350 | void vmovdqu(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVDQU, 0x6F, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4351 | void vmovdqu(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVDQU, 0x7F, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, R(src), W(dst));} | ||
| 4352 | void vmovhlps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MOVHLPS, 0x12, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4353 | void vmovhpd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MOVHPD, 0x16, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4354 | void vmovhpd(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVHPD, 0x17, E_VEX_128_66_0F_WIG, R(src), W(dst));} | ||
| 4355 | void vmovhps(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MOVHPS, 0x16, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4356 | void vmovhps(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVHPS, 0x17, E_VEX_128_0F_WIG, R(src), W(dst));} | ||
| 4357 | void vmovlhps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MOVHLPS, 0x16, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4358 | void vmovlpd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MOVLPD, 0x12, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4359 | void vmovlpd(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVLPD, 0x13, E_VEX_128_66_0F_WIG, R(src), W(dst));} | ||
| 4360 | void vmovlps(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MOVLPS, 0x12, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4361 | void vmovlps(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVLPS, 0x13, E_VEX_128_0F_WIG, R(src), W(dst));} | ||
| 4362 | void vmovmskpd(const Reg32& dst, const XmmReg& src) {AppendInstr(I_MOVMSKPD, 0x50, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4363 | void vmovmskpd(const Reg32& dst, const YmmReg& src) {AppendInstr(I_MOVMSKPD, 0x50, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4364 | #ifdef JITASM64 | ||
| 4365 | void vmovmskpd(const Reg64& dst, const XmmReg& src) {AppendInstr(I_MOVMSKPD, 0x50, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4366 | void vmovmskpd(const Reg64& dst, const YmmReg& src) {AppendInstr(I_MOVMSKPD, 0x50, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4367 | #endif | ||
| 4368 | void vmovmskps(const Reg32& dst, const XmmReg& src) {AppendInstr(I_MOVMSKPS, 0x50, E_VEX_128_0F_WIG, W(dst), R(src));} | ||
| 4369 | void vmovmskps(const Reg32& dst, const YmmReg& src) {AppendInstr(I_MOVMSKPS, 0x50, E_VEX_256_0F_WIG, W(dst), R(src));} | ||
| 4370 | #ifdef JITASM64 | ||
| 4371 | void vmovmskps(const Reg64& dst, const XmmReg& src) {AppendInstr(I_MOVMSKPS, 0x50, E_VEX_128_0F_WIG, W(dst), R(src));} | ||
| 4372 | void vmovmskps(const Reg64& dst, const YmmReg& src) {AppendInstr(I_MOVMSKPS, 0x50, E_VEX_256_0F_WIG, W(dst), R(src));} | ||
| 4373 | #endif | ||
| 4374 | void vmovntdq(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVNTDQ, 0xE7, E_VEX_128_66_0F_WIG, R(src), W(dst));} | ||
| 4375 | void vmovntdq(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVNTDQ, 0xE7, E_VEX_256_66_0F_WIG, R(src), W(dst));} | ||
| 4376 | void vmovntdqa(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVNTDQA, 0x2A, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4377 | void vmovntpd(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVNTPD, 0x2B, E_VEX_128_66_0F_WIG, R(src), W(dst));} | ||
| 4378 | void vmovntpd(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVNTPD, 0x2B, E_VEX_256_66_0F_WIG, R(src), W(dst));} | ||
| 4379 | void vmovntps(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVNTPS, 0x2B, E_VEX_128_0F_WIG, R(src), W(dst));} | ||
| 4380 | void vmovntps(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVNTPS, 0x2B, E_VEX_256_0F_WIG, R(src), W(dst));} | ||
| 4381 | void vmovsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MOVSD, 0x10, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4382 | void vmovsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVSD, 0x10, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4383 | void vmovsd(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVSD, 0x11, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, R(src), W(dst));} | ||
| 4384 | void vmovshdup(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVSHDUP, 0x16, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4385 | void vmovshdup(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVSHDUP, 0x16, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4386 | void vmovshdup(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVSHDUP, 0x16, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4387 | void vmovshdup(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVSHDUP, 0x16, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4388 | void vmovsldup(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVSLDUP, 0x12, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4389 | void vmovsldup(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVSLDUP, 0x12, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4390 | void vmovsldup(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVSLDUP, 0x12, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4391 | void vmovsldup(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVSLDUP, 0x12, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4392 | void vmovss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MOVSS, 0x10, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4393 | void vmovss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MOVSS, 0x10, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));} | ||
| 4394 | void vmovss(const Mem32& dst, const XmmReg& src) {AppendInstr(I_MOVSS, 0x11, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, R(src), W(dst));} | ||
| 4395 | void vmovupd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVUPD, 0x10, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4396 | void vmovupd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVUPD, 0x10, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4397 | void vmovupd(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVUPD, 0x11, E_VEX_128_66_0F_WIG, R(src), W(dst));} | ||
| 4398 | void vmovupd(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVUPD, 0x10, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4399 | void vmovupd(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVUPD, 0x10, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4400 | void vmovupd(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVUPD, 0x11, E_VEX_256_66_0F_WIG, R(src), W(dst));} | ||
| 4401 | void vmovups(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVUPS, 0x10, E_VEX_128_0F_WIG, W(dst), R(src));} | ||
| 4402 | void vmovups(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVUPS, 0x10, E_VEX_128_0F_WIG, W(dst), R(src));} | ||
| 4403 | void vmovups(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVUPS, 0x11, E_VEX_128_0F_WIG, R(src), W(dst));} | ||
| 4404 | void vmovups(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVUPS, 0x10, E_VEX_256_0F_WIG, W(dst), R(src));} | ||
| 4405 | void vmovups(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVUPS, 0x10, E_VEX_256_0F_WIG, W(dst), R(src));} | ||
| 4406 | void vmovups(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVUPS, 0x11, E_VEX_256_0F_WIG, R(src), W(dst));} | ||
| 4407 | void vmpsadbw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& i) {AppendInstr(I_MPSADBW, 0x42, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src2), R(src1), i);} | ||
| 4408 | void vmpsadbw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& i) {AppendInstr(I_MPSADBW, 0x42, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src2), R(src1), i);} | ||
| 4409 | void vmulpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MULPD, 0x59, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4410 | void vmulpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_MULPD, 0x59, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4411 | void vmulpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_MULPD, 0x59, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4412 | void vmulpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_MULPD, 0x59, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4413 | void vmulps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MULPS, 0x59, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4414 | void vmulps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_MULPS, 0x59, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4415 | ✗ | void vmulps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_MULPS, 0x59, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4416 | ✗ | void vmulps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_MULPS, 0x59, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4417 | void vmulsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MULSD, 0x59, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4418 | void vmulsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MULSD, 0x59, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4419 | void vmulss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MULSS, 0x59, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4420 | void vmulss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_MULSS, 0x59, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4421 | void vorpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ORPD, 0x56, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4422 | void vorpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ORPD, 0x56, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4423 | void vorpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ORPD, 0x56, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4424 | void vorpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ORPD, 0x56, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4425 | void vorps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ORPS, 0x56, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4426 | void vorps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ORPS, 0x56, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4427 | ✗ | void vorps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ORPS, 0x56, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4428 | ✗ | void vorps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ORPS, 0x56, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4429 | void vpabsb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PABSB, 0x1C, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4430 | void vpabsb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PABSB, 0x1C, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4431 | void vpabsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PABSW, 0x1D, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4432 | void vpabsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PABSW, 0x1D, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4433 | void vpabsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PABSD, 0x1E, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4434 | void vpabsd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PABSD, 0x1E, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4435 | void vpacksswb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PACKSSWB, 0x63, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4436 | void vpacksswb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PACKSSWB, 0x63, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4437 | void vpackssdw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PACKSSDW, 0x6B, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4438 | void vpackssdw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PACKSSDW, 0x6B, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4439 | ✗ | void vpackuswb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PACKUSWB, 0x67, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4440 | void vpackuswb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PACKUSWB, 0x67, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4441 | ✗ | void vpackusdw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PACKUSDW, 0x2B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | |
| 4442 | void vpackusdw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PACKUSDW, 0x2B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4443 | void vpaddb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDB, 0xFC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4444 | void vpaddb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDB, 0xFC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4445 | void vpaddw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDW, 0xFD, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4446 | void vpaddw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDW, 0xFD, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4447 | void vpaddd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDD, 0xFE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4448 | void vpaddd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDD, 0xFE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4449 | ✗ | void vpaddq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDQ, 0xD4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4450 | void vpaddq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDQ, 0xD4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4451 | void vpaddsb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDSB, 0xEC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4452 | void vpaddsb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDSB, 0xEC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4453 | void vpaddsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDSW, 0xED, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4454 | void vpaddsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDSW, 0xED, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4455 | void vpaddusb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDUSB, 0xDC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4456 | void vpaddusb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDUSB, 0xDC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4457 | void vpaddusw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDUSW, 0xDD, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4458 | void vpaddusw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDUSW, 0xDD, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4459 | void vpalignr(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& i) {AppendInstr(I_PALIGNR, 0x0F, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);} | ||
| 4460 | void vpalignr(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& i) {AppendInstr(I_PALIGNR, 0x0F, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);} | ||
| 4461 | void vpand(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PAND, 0xDB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4462 | void vpand(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PAND, 0xDB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4463 | void vpandn(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PANDN, 0xDF, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4464 | void vpandn(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PANDN, 0xDF, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4465 | void vpavgb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PAVGB, 0xE0, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4466 | void vpavgb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PAVGB, 0xE0, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4467 | void vpavgw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PAVGW, 0xE3, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4468 | void vpavgw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PAVGW, 0xE3, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4469 | void vpblendvb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& mask) {AppendInstr(I_PBLENDVB, 0x4C, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), R(mask));} | ||
| 4470 | void vpblendvb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& mask) {AppendInstr(I_PBLENDVB, 0x4C, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), R(mask));} | ||
| 4471 | void vpblendw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_PBLENDW, 0x0E, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4472 | void vpblendw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_PBLENDW, 0x0E, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4473 | void pclmulqdq(const XmmReg& dst, const XmmReg& src, const Imm8& mask) {AppendInstr(I_PCLMULQDQ, 0x0F3A44, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);} | ||
| 4474 | void pclmulqdq(const XmmReg& dst, const Mem128& src, const Imm8& mask) {AppendInstr(I_PCLMULQDQ, 0x0F3A44, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);} | ||
| 4475 | void vpclmulqdq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_PCLMULQDQ, 0x44, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4476 | void vpclmulqdq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_PCLMULQDQ, 0x44, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 4477 | void vpcmpeqb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPEQB, 0x74, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4478 | void vpcmpeqb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPEQB, 0x74, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4479 | void vpcmpeqw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPEQW, 0x75, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4480 | void vpcmpeqw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPEQW, 0x75, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4481 | void vpcmpeqd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPEQD, 0x76, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4482 | void vpcmpeqd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPEQD, 0x76, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4483 | void vpcmpeqq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPEQQ, 0x29, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4484 | void vpcmpeqq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPEQQ, 0x29, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4485 | void vpcmpgtb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPGTB, 0x64, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4486 | void vpcmpgtb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPGTB, 0x64, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4487 | void vpcmpgtw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPGTW, 0x65, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4488 | void vpcmpgtw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPGTW, 0x65, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4489 | void vpcmpgtd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPGTD, 0x66, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4490 | void vpcmpgtd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPGTD, 0x66, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4491 | void vpcmpgtq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPGTQ, 0x37, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4492 | void vpcmpgtq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPGTQ, 0x37, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4493 | void vpcmpestri(const Reg& result, const XmmReg& src1, const Reg& len1, const XmmReg& src2, const Reg& len2, const Imm8& mode) {AppendInstr(I_PCMPESTRI, 0x61, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), ecx), Dummy(R(len1), eax), Dummy(R(len2), edx));} | ||
| 4494 | void vpcmpestri(const Reg& result, const XmmReg& src1, const Reg& len1, const Mem128& src2, const Reg& len2, const Imm8& mode) {AppendInstr(I_PCMPESTRI, 0x61, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), ecx), Dummy(R(len1), eax), Dummy(R(len2), edx));} | ||
| 4495 | void vpcmpestrm(const XmmReg& result, const XmmReg& src1, const Reg& len1, const XmmReg& src2, const Reg& len2, const Imm8& mode) {AppendInstr(I_PCMPESTRM, 0x60, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), xmm0), Dummy(R(len1), eax), Dummy(R(len2), edx));} | ||
| 4496 | void vpcmpestrm(const XmmReg& result, const XmmReg& src1, const Reg& len1, const Mem128& src2, const Reg& len2, const Imm8& mode) {AppendInstr(I_PCMPESTRM, 0x60, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), xmm0), Dummy(R(len1), eax), Dummy(R(len2), edx));} | ||
| 4497 | void vpcmpistri(const Reg& result, const XmmReg& src1, const XmmReg& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRI, 0x63, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), ecx));} | ||
| 4498 | void vpcmpistri(const Reg& result, const XmmReg& src1, const Mem128& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRI, 0x63, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), ecx));} | ||
| 4499 | void vpcmpistrm(const XmmReg& result, const XmmReg& src1, const XmmReg& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRM, 0x62, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), xmm0));} | ||
| 4500 | void vpcmpistrm(const XmmReg& result, const XmmReg& src1, const Mem128& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRM, 0x62, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), xmm0));} | ||
| 4501 | void vpermilpd(const XmmReg& dst, const XmmReg& src, const XmmReg& ctrl) {AppendInstr(I_VPERMILPD, 0x0D, E_VEX_128_66_0F38_W0, W(dst), R(ctrl), R(src));} | ||
| 4502 | void vpermilpd(const XmmReg& dst, const XmmReg& src, const Mem128& ctrl) {AppendInstr(I_VPERMILPD, 0x0D, E_VEX_128_66_0F38_W0, W(dst), R(ctrl), R(src));} | ||
| 4503 | void vpermilpd(const YmmReg& dst, const YmmReg& src, const YmmReg& ctrl) {AppendInstr(I_VPERMILPD, 0x0D, E_VEX_256_66_0F38_W0, W(dst), R(ctrl), R(src));} | ||
| 4504 | void vpermilpd(const YmmReg& dst, const YmmReg& src, const Mem256& ctrl) {AppendInstr(I_VPERMILPD, 0x0D, E_VEX_256_66_0F38_W0, W(dst), R(ctrl), R(src));} | ||
| 4505 | void vpermilpd(const XmmReg& dst, const XmmReg& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPD, 0x05, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);} | ||
| 4506 | void vpermilpd(const XmmReg& dst, const Mem128& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPD, 0x05, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);} | ||
| 4507 | void vpermilpd(const YmmReg& dst, const YmmReg& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPD, 0x05, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);} | ||
| 4508 | void vpermilpd(const YmmReg& dst, const Mem256& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPD, 0x05, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);} | ||
| 4509 | void vpermilps(const XmmReg& dst, const XmmReg& src, const XmmReg& ctrl) {AppendInstr(I_VPERMILPS, 0x0C, E_VEX_128_66_0F38_W0, W(dst), R(ctrl), R(src));} | ||
| 4510 | void vpermilps(const XmmReg& dst, const XmmReg& src, const Mem128& ctrl) {AppendInstr(I_VPERMILPS, 0x0C, E_VEX_128_66_0F38_W0, W(dst), R(ctrl), R(src));} | ||
| 4511 | void vpermilps(const YmmReg& dst, const YmmReg& src, const YmmReg& ctrl) {AppendInstr(I_VPERMILPS, 0x0C, E_VEX_256_66_0F38_W0, W(dst), R(ctrl), R(src));} | ||
| 4512 | void vpermilps(const YmmReg& dst, const YmmReg& src, const Mem256& ctrl) {AppendInstr(I_VPERMILPS, 0x0C, E_VEX_256_66_0F38_W0, W(dst), R(ctrl), R(src));} | ||
| 4513 | void vpermilps(const XmmReg& dst, const XmmReg& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPS, 0x04, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);} | ||
| 4514 | void vpermilps(const XmmReg& dst, const Mem128& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPS, 0x04, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);} | ||
| 4515 | void vpermilps(const YmmReg& dst, const YmmReg& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPS, 0x04, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);} | ||
| 4516 | void vpermilps(const YmmReg& dst, const Mem256& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPS, 0x04, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);} | ||
| 4517 | void vperm2f128(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& ctrl) {AppendInstr(I_VPERM2F128, 0x06, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), ctrl);} | ||
| 4518 | void vperm2f128(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& ctrl) {AppendInstr(I_VPERM2F128, 0x06, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), ctrl);} | ||
| 4519 | void vpextrb(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRB, 0x14, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);} | ||
| 4520 | void vpextrb(const Mem8& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRB, 0x14, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);} | ||
| 4521 | void vpextrw(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0xC5, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(src), i);} | ||
| 4522 | void vpextrw(const Mem16& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0x15, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);} | ||
| 4523 | void vpextrd(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRD, 0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);} | ||
| 4524 | void vpextrd(const Mem32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRD, 0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);} | ||
| 4525 | #ifdef JITASM64 | ||
| 4526 | void vpextrb(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRB, 0x14, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);} | ||
| 4527 | void vpextrw(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0xC5, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(src), i);} | ||
| 4528 | void vpextrd(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRD, 0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);} | ||
| 4529 | void vpextrq(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRQ, 0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W1, R(src), W(dst), i);} | ||
| 4530 | void vpextrq(const Mem64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRQ, 0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W1, R(src), W(dst), i);} | ||
| 4531 | #endif | ||
| 4532 | void vphaddw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PHADDW, 0x01, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4533 | void vphaddw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PHADDW, 0x01, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4534 | void vphaddd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PHADDD, 0x02, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4535 | void vphaddd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PHADDD, 0x02, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4536 | void vphaddsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PHADDSW, 0x03, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4537 | void vphaddsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PHADDSW, 0x03, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4538 | void vphminposuw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHMINPOSUW, 0x41, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4539 | void vphminposuw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHMINPOSUW, 0x41, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4540 | void vphsubw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PHSUBW, 0x05, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4541 | void vphsubw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PHSUBW, 0x05, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4542 | void vphsubd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PHSUBD, 0x06, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4543 | void vphsubd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PHSUBD, 0x06, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4544 | void vphsubsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PHSUBSW, 0x07, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4545 | void vphsubsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PHSUBSW, 0x07, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4546 | void vpinsrb(const XmmReg& dst, const XmmReg& src, const Reg32& val, const Imm8& i) {AppendInstr(I_PINSRB, 0x20, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);} | ||
| 4547 | void vpinsrb(const XmmReg& dst, const XmmReg& src, const Mem8& val, const Imm8& i) {AppendInstr(I_PINSRB, 0x20, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);} | ||
| 4548 | void vpinsrw(const XmmReg& dst, const XmmReg& src, const Reg32& val, const Imm8& i) {AppendInstr(I_PINSRW, 0xC4, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(val), R(src), i);} | ||
| 4549 | void vpinsrw(const XmmReg& dst, const XmmReg& src, const Mem16& val, const Imm8& i) {AppendInstr(I_PINSRW, 0xC4, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(val), R(src), i);} | ||
| 4550 | void vpinsrd(const XmmReg& dst, const XmmReg& src, const Reg32& val, const Imm8& i) {AppendInstr(I_PINSRD, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);} | ||
| 4551 | void vpinsrd(const XmmReg& dst, const XmmReg& src, const Mem32& val, const Imm8& i) {AppendInstr(I_PINSRD, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);} | ||
| 4552 | #ifdef JITASM64 | ||
| 4553 | void vpinsrb(const XmmReg& dst, const XmmReg& src, const Reg64& val, const Imm8& i) {AppendInstr(I_PINSRB, 0x20, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);} | ||
| 4554 | void vpinsrw(const XmmReg& dst, const XmmReg& src, const Reg64& val, const Imm8& i) {AppendInstr(I_PINSRW, 0xC4, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(val), R(src), i);} | ||
| 4555 | void vpinsrd(const XmmReg& dst, const XmmReg& src, const Reg64& val, const Imm8& i) {AppendInstr(I_PINSRD, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);} | ||
| 4556 | void vpinsrq(const XmmReg& dst, const XmmReg& src, const Reg64& val, const Imm8& i) {AppendInstr(I_PINSRQ, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(val), R(src), i);} | ||
| 4557 | void vpinsrq(const XmmReg& dst, const XmmReg& src, const Mem64& val, const Imm8& i) {AppendInstr(I_PINSRQ, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(val), R(src), i);} | ||
| 4558 | #endif | ||
| 4559 | void vpmaddwd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMADDWD, 0xF5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4560 | void vpmaddwd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMADDWD, 0xF5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4561 | void vpmaddubsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMADDUBSW,0x04, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4562 | void vpmaddubsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMADDUBSW,0x04, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4563 | void vpmaxsb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMAXSB, 0x3C, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4564 | void vpmaxsb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMAXSB, 0x3C, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4565 | void vpmaxsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMAXSW, 0xEE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4566 | void vpmaxsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMAXSW, 0xEE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4567 | void vpmaxsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMAXSD, 0x3D, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4568 | void vpmaxsd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMAXSD, 0x3D, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4569 | void vpmaxub(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMAXUB, 0xDE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4570 | void vpmaxub(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMAXUB, 0xDE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4571 | void vpmaxuw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMAXUW, 0x3E, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4572 | void vpmaxuw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMAXUW, 0x3E, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4573 | void vpmaxud(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMAXUD, 0x3F, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4574 | void vpmaxud(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMAXUD, 0x3F, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4575 | void vpminsb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMINSB, 0x38, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4576 | void vpminsb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMINSB, 0x38, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4577 | void vpminsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMINSW, 0xEA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4578 | void vpminsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMINSW, 0xEA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4579 | void vpminsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMINSD, 0x39, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4580 | void vpminsd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMINSD, 0x39, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4581 | void vpminub(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMINUB, 0xDA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4582 | void vpminub(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMINUB, 0xDA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4583 | void vpminuw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMINUW, 0x3A, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4584 | void vpminuw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMINUW, 0x3A, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4585 | void vpminud(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMINUD, 0x3B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4586 | void vpminud(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMINUD, 0x3B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4587 | void vpmovmskb(const Reg32& dst, const XmmReg& src) {AppendInstr(I_PMOVMSKB, 0xD7, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4588 | #ifdef JITASM64 | ||
| 4589 | void vpmovmskb(const Reg64& dst, const XmmReg& src) {AppendInstr(I_PMOVMSKB, 0xD7, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4590 | #endif | ||
| 4591 | void vpmovsxbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBW, 0x20, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4592 | void vpmovsxbw(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXBW, 0x20, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4593 | void vpmovsxbd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBD, 0x21, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4594 | void vpmovsxbd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVSXBD, 0x21, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4595 | void vpmovsxbq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBQ, 0x22, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4596 | void vpmovsxbq(const XmmReg& dst, const Mem16& src) {AppendInstr(I_PMOVSXBQ, 0x22, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4597 | void vpmovsxwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXWD, 0x23, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4598 | void vpmovsxwd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXWD, 0x23, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4599 | void vpmovsxwq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXWQ, 0x24, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4600 | void vpmovsxwq(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVSXWQ, 0x24, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4601 | void vpmovsxdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXDQ, 0x25, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4602 | void vpmovsxdq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXDQ, 0x25, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4603 | void vpmovzxbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBW, 0x30, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4604 | void vpmovzxbw(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXBW, 0x30, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4605 | void vpmovzxbd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBD, 0x31, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4606 | void vpmovzxbd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVZXBD, 0x31, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4607 | void vpmovzxbq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBQ, 0x32, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4608 | void vpmovzxbq(const XmmReg& dst, const Mem16& src) {AppendInstr(I_PMOVZXBQ, 0x32, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4609 | void vpmovzxwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXWD, 0x33, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4610 | void vpmovzxwd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXWD, 0x33, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4611 | void vpmovzxwq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXWQ, 0x34, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4612 | void vpmovzxwq(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVZXWQ, 0x34, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4613 | void vpmovzxdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXDQ, 0x35, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4614 | void vpmovzxdq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXDQ, 0x35, E_VEX_128_66_0F38_WIG, W(dst), R(src));} | ||
| 4615 | void vpmulhuw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2){AppendInstr(I_PMULHUW, 0xE4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4616 | void vpmulhuw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2){AppendInstr(I_PMULHUW, 0xE4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4617 | void vpmulhrsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2){AppendInstr(I_PMULHRSW, 0x0B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4618 | void vpmulhrsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2){AppendInstr(I_PMULHRSW, 0x0B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4619 | void vpmulhw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMULHW, 0xE5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4620 | void vpmulhw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMULHW, 0xE5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4621 | void vpmullw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMULLW, 0xD5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4622 | void vpmullw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMULLW, 0xD5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4623 | void vpmulld(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMULLD, 0x40, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4624 | void vpmulld(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMULLD, 0x40, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4625 | void vpmuludq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2){AppendInstr(I_PMULUDQ, 0xF4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4626 | void vpmuludq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2){AppendInstr(I_PMULUDQ, 0xF4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4627 | void vpmuldq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMULDQ, 0x28, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4628 | void vpmuldq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMULDQ, 0x28, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4629 | void vpor(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_POR, 0xEB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4630 | void vpor(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_POR, 0xEB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4631 | void vpsadbw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSADBW, 0xF6, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4632 | void vpsadbw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSADBW, 0xF6, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4633 | void vpshufb(const XmmReg& dst, const XmmReg& src, const XmmReg& order) {AppendInstr(I_PSHUFB, 0x00, E_VEX_128_66_0F38_WIG, W(dst), R(order), R(src));} | ||
| 4634 | void vpshufb(const XmmReg& dst, const XmmReg& src, const Mem128& order) {AppendInstr(I_PSHUFB, 0x00, E_VEX_128_66_0F38_WIG, W(dst), R(order), R(src));} | ||
| 4635 | void vpshufd(const XmmReg& dst, const XmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFD, 0x70, E_VEX_128_66_0F_WIG, W(dst), R(src), order);} | ||
| 4636 | void vpshufd(const XmmReg& dst, const Mem128& src, const Imm8& order) {AppendInstr(I_PSHUFD, 0x70, E_VEX_128_66_0F_WIG, W(dst), R(src), order);} | ||
| 4637 | void vpshufhw(const XmmReg& dst, const XmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFHW, 0x70, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src), order);} | ||
| 4638 | void vpshufhw(const XmmReg& dst, const Mem128& src, const Imm8& order) {AppendInstr(I_PSHUFHW, 0x70, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src), order);} | ||
| 4639 | void vpshuflw(const XmmReg& dst, const XmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFLW, 0x70, E_VEX_128 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src), order);} | ||
| 4640 | void vpshuflw(const XmmReg& dst, const Mem128& src, const Imm8& order) {AppendInstr(I_PSHUFLW, 0x70, E_VEX_128 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src), order);} | ||
| 4641 | void vpsignb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSIGNB, 0x08, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4642 | void vpsignb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSIGNB, 0x08, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4643 | void vpsignw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSIGNW, 0x09, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4644 | void vpsignw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSIGNW, 0x09, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4645 | void vpsignd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSIGND, 0x0A, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4646 | void vpsignd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSIGND, 0x0A, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 4647 | void vpsllw(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSLLW, 0xF1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4648 | void vpsllw(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSLLW, 0xF1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4649 | void vpsllw(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSLLW, 0x71, E_VEX_128_66_0F_WIG, Imm8(6), R(src), W(dst), count);} | ||
| 4650 | void vpslld(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSLLD, 0xF2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4651 | void vpslld(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSLLD, 0xF2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4652 | void vpslld(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSLLD, 0x72, E_VEX_128_66_0F_WIG, Imm8(6), R(src), W(dst), count);} | ||
| 4653 | void vpsllq(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSLLQ, 0xF3, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4654 | void vpsllq(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSLLQ, 0xF3, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4655 | void vpsllq(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSLLQ, 0x73, E_VEX_128_66_0F_WIG, Imm8(6), R(src), W(dst), count);} | ||
| 4656 | void vpslldq(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSLLDQ, 0x73, E_VEX_128_66_0F_WIG, Imm8(7), R(src), W(dst), count);} | ||
| 4657 | void vpsraw(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSRAW, 0xE1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4658 | void vpsraw(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSRAW, 0xE1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4659 | void vpsraw(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSRAW, 0x71, E_VEX_128_66_0F_WIG, Imm8(4), R(src), W(dst), count);} | ||
| 4660 | void vpsrad(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSRAD, 0xE2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4661 | void vpsrad(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSRAD, 0xE2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4662 | void vpsrad(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSRAD, 0x72, E_VEX_128_66_0F_WIG, Imm8(4), R(src), W(dst), count);} | ||
| 4663 | void vpsrlw(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSRLW, 0xD1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4664 | void vpsrlw(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSRLW, 0xD1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4665 | void vpsrlw(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSRLW, 0x71, E_VEX_128_66_0F_WIG, Imm8(2), R(src), W(dst), count);} | ||
| 4666 | void vpsrld(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSRLD, 0xD2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4667 | void vpsrld(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSRLD, 0xD2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4668 | void vpsrld(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSRLD, 0x72, E_VEX_128_66_0F_WIG, Imm8(2), R(src), W(dst), count);} | ||
| 4669 | void vpsrlq(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSRLQ, 0xD3, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4670 | void vpsrlq(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSRLQ, 0xD3, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 4671 | void vpsrlq(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSRLQ, 0x73, E_VEX_128_66_0F_WIG, Imm8(2), R(src), W(dst), count);} | ||
| 4672 | void vpsrldq(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSRLDQ, 0x73, E_VEX_128_66_0F_WIG, Imm8(3), R(src), W(dst), count);} | ||
| 4673 | void vptest(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PTEST, 0x17, E_VEX_128_66_0F38_WIG, R(src1), R(src2));} | ||
| 4674 | void vptest(const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PTEST, 0x17, E_VEX_128_66_0F38_WIG, R(src1), R(src2));} | ||
| 4675 | void vptest(const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PTEST, 0x17, E_VEX_256_66_0F38_WIG, R(src1), R(src2));} | ||
| 4676 | void vptest(const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PTEST, 0x17, E_VEX_256_66_0F38_WIG, R(src1), R(src2));} | ||
| 4677 | void vtestps(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VTESTPS, 0x0E, E_VEX_128_66_0F38_W0, R(src1), R(src2));} | ||
| 4678 | void vtestps(const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VTESTPS, 0x0E, E_VEX_128_66_0F38_W0, R(src1), R(src2));} | ||
| 4679 | void vtestps(const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VTESTPS, 0x0E, E_VEX_256_66_0F38_W0, R(src1), R(src2));} | ||
| 4680 | void vtestps(const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VTESTPS, 0x0E, E_VEX_256_66_0F38_W0, R(src1), R(src2));} | ||
| 4681 | void vtestpd(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VTESTPD, 0x0F, E_VEX_128_66_0F38_W0, R(src1), R(src2));} | ||
| 4682 | void vtestpd(const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VTESTPD, 0x0F, E_VEX_128_66_0F38_W0, R(src1), R(src2));} | ||
| 4683 | void vtestpd(const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VTESTPD, 0x0F, E_VEX_256_66_0F38_W0, R(src1), R(src2));} | ||
| 4684 | void vtestpd(const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VTESTPD, 0x0F, E_VEX_256_66_0F38_W0, R(src1), R(src2));} | ||
| 4685 | void vpsubb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBB, 0xF8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4686 | void vpsubb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBB, 0xF8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4687 | void vpsubw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBW, 0xF9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4688 | void vpsubw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBW, 0xF9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4689 | void vpsubd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBD, 0xFA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4690 | void vpsubd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBD, 0xFA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4691 | void vpsubq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBQ, 0xFB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4692 | void vpsubq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBQ, 0xFB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4693 | void vpsubsb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBSB, 0xE8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4694 | void vpsubsb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBSB, 0xE8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4695 | void vpsubsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBSW, 0xE9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4696 | void vpsubsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBSW, 0xE9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4697 | void vpsubusb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBUSB, 0xD8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4698 | void vpsubusb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBUSB, 0xD8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4699 | void vpsubusw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBUSW, 0xD9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4700 | void vpsubusw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBUSW, 0xD9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4701 | void vpunpckhbw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKHBW, 0x68, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4702 | void vpunpckhbw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKHBW, 0x68, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4703 | void vpunpckhwd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKHWD, 0x69, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4704 | void vpunpckhwd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKHWD, 0x69, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4705 | void vpunpckhdq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKHDQ, 0x6A, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4706 | void vpunpckhdq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKHDQ, 0x6A, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4707 | void vpunpckhqdq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKHQDQ, 0x6D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4708 | void vpunpckhqdq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKHQDQ, 0x6D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4709 | void vpunpcklbw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKLBW, 0x60, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4710 | void vpunpcklbw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKLBW, 0x60, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4711 | void vpunpcklwd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKLWD, 0x61, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4712 | void vpunpcklwd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKLWD, 0x61, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4713 | void vpunpckldq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKLDQ, 0x62, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4714 | void vpunpckldq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKLDQ, 0x62, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4715 | void vpunpcklqdq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKLQDQ, 0x6C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4716 | void vpunpcklqdq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKLQDQ, 0x6C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4717 | void vpxor(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PXOR, 0xEF, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4718 | void vpxor(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PXOR, 0xEF, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4719 | void vrcpps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_RCPPS, 0x53, E_VEX_128_0F_WIG, W(dst), R(src));} | ||
| 4720 | void vrcpps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_RCPPS, 0x53, E_VEX_128_0F_WIG, W(dst), R(src));} | ||
| 4721 | void vrcpps(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_RCPPS, 0x53, E_VEX_256_0F_WIG, W(dst), R(src));} | ||
| 4722 | void vrcpps(const YmmReg& dst, const Mem256& src) {AppendInstr(I_RCPPS, 0x53, E_VEX_256_0F_WIG, W(dst), R(src));} | ||
| 4723 | void vrcpss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_RCPSS, 0x53, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4724 | void vrcpss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_RCPSS, 0x53, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4725 | void vrsqrtps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_RSQRTPS, 0x52, E_VEX_128_0F_WIG, W(dst), R(src));} | ||
| 4726 | void vrsqrtps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_RSQRTPS, 0x52, E_VEX_128_0F_WIG, W(dst), R(src));} | ||
| 4727 | void vrsqrtps(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_RSQRTPS, 0x52, E_VEX_256_0F_WIG, W(dst), R(src));} | ||
| 4728 | void vrsqrtps(const YmmReg& dst, const Mem256& src) {AppendInstr(I_RSQRTPS, 0x52, E_VEX_256_0F_WIG, W(dst), R(src));} | ||
| 4729 | void vrsqrtss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2){AppendInstr(I_RSQRTSS, 0x52, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4730 | void vrsqrtss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_RSQRTSS, 0x52, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4731 | void vroundpd(const XmmReg& dst, const XmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDPD, 0x09, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);} | ||
| 4732 | void vroundpd(const XmmReg& dst, const Mem128& src, const Imm8& mode) {AppendInstr(I_ROUNDPD, 0x09, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);} | ||
| 4733 | void vroundpd(const YmmReg& dst, const YmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDPD, 0x09, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);} | ||
| 4734 | void vroundpd(const YmmReg& dst, const Mem256& src, const Imm8& mode) {AppendInstr(I_ROUNDPD, 0x09, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);} | ||
| 4735 | void vroundps(const XmmReg& dst, const XmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDPS, 0x08, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);} | ||
| 4736 | void vroundps(const XmmReg& dst, const Mem128& src, const Imm8& mode) {AppendInstr(I_ROUNDPS, 0x08, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);} | ||
| 4737 | ✗ | void vroundps(const YmmReg& dst, const YmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDPS, 0x08, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);} | |
| 4738 | void vroundps(const YmmReg& dst, const Mem256& src, const Imm8& mode) {AppendInstr(I_ROUNDPS, 0x08, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);} | ||
| 4739 | void vroundsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mode) {AppendInstr(I_ROUNDSD, 0x0B, E_VEX_LIG | E_VEX_66_0F3A | E_VEX_WIG, RW(dst), R(src2), R(src1), mode);} | ||
| 4740 | void vroundsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const Imm8& mode) {AppendInstr(I_ROUNDSD, 0x0B, E_VEX_LIG | E_VEX_66_0F3A | E_VEX_WIG, RW(dst), R(src2), R(src1), mode);} | ||
| 4741 | void vroundss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mode) {AppendInstr(I_ROUNDSS, 0x0A, E_VEX_LIG | E_VEX_66_0F3A | E_VEX_WIG, RW(dst), R(src2), R(src1), mode);} | ||
| 4742 | void vroundss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const Imm8& mode) {AppendInstr(I_ROUNDSS, 0x0A, E_VEX_LIG | E_VEX_66_0F3A | E_VEX_WIG, RW(dst), R(src2), R(src1), mode);} | ||
| 4743 | void vshufpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& sel) {AppendInstr(I_SHUFPD, 0xC6, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1), sel);} | ||
| 4744 | void vshufpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& sel) {AppendInstr(I_SHUFPD, 0xC6, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1), sel);} | ||
| 4745 | void vshufpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& sel) {AppendInstr(I_SHUFPD, 0xC6, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1), sel);} | ||
| 4746 | void vshufpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& sel) {AppendInstr(I_SHUFPD, 0xC6, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1), sel);} | ||
| 4747 | void vshufps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& sel) {AppendInstr(I_SHUFPS, 0xC6, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1), sel);} | ||
| 4748 | void vshufps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& sel) {AppendInstr(I_SHUFPS, 0xC6, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1), sel);} | ||
| 4749 | void vshufps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& sel) {AppendInstr(I_SHUFPS, 0xC6, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1), sel);} | ||
| 4750 | void vshufps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& sel) {AppendInstr(I_SHUFPS, 0xC6, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1), sel);} | ||
| 4751 | void vsqrtpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SQRTPD, 0x51, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4752 | void vsqrtpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_SQRTPD, 0x51, E_VEX_128_66_0F_WIG, W(dst), R(src));} | ||
| 4753 | void vsqrtpd(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_SQRTPD, 0x51, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4754 | void vsqrtpd(const YmmReg& dst, const Mem256& src) {AppendInstr(I_SQRTPD, 0x51, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 4755 | void vsqrtps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SQRTPS, 0x51, E_VEX_128_0F_WIG, W(dst), R(src));} | ||
| 4756 | void vsqrtps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_SQRTPS, 0x51, E_VEX_128_0F_WIG, W(dst), R(src));} | ||
| 4757 | ✗ | void vsqrtps(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_SQRTPS, 0x51, E_VEX_256_0F_WIG, W(dst), R(src));} | |
| 4758 | void vsqrtps(const YmmReg& dst, const Mem256& src) {AppendInstr(I_SQRTPS, 0x51, E_VEX_256_0F_WIG, W(dst), R(src));} | ||
| 4759 | void vsqrtsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_SQRTSD, 0x51, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4760 | void vsqrtsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_SQRTSD, 0x51, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4761 | void vsqrtss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_SQRTSS, 0x51, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4762 | void vsqrtss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_SQRTSS, 0x51, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4763 | void vstmxcsr(const Mem32& dst) {AppendInstr(I_STMXCSR, 0xAE, E_VEX_LZ | E_VEX_0F | E_VEX_WIG, Imm8(3), W(dst));} | ||
| 4764 | void vsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_SUBPD, 0x5C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4765 | void vsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_SUBPD, 0x5C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4766 | void vsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_SUBPD, 0x5C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4767 | void vsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_SUBPD, 0x5C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4768 | void vsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_SUBPS, 0x5C, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4769 | void vsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_SUBPS, 0x5C, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4770 | ✗ | void vsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_SUBPS, 0x5C, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4771 | ✗ | void vsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_SUBPS, 0x5C, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4772 | void vsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_SUBSD, 0x5C, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4773 | void vsubsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_SUBSD, 0x5C, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4774 | void vsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_SUBSS, 0x5C, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4775 | void vsubss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_SUBSS, 0x5C, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));} | ||
| 4776 | void vucomisd(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UCOMISD, 0x2E, E_VEX_LIG | E_VEX_66_0F | E_VEX_WIG, R(src1), R(src2));} | ||
| 4777 | void vucomisd(const XmmReg& src1, const Mem64& src2) {AppendInstr(I_UCOMISD, 0x2E, E_VEX_LIG | E_VEX_66_0F | E_VEX_WIG, R(src1), R(src2));} | ||
| 4778 | void vucomiss(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UCOMISS, 0x2E, E_VEX_LIG | E_VEX_0F | E_VEX_WIG, R(src1), R(src2));} | ||
| 4779 | void vucomiss(const XmmReg& src1, const Mem32& src2) {AppendInstr(I_UCOMISS, 0x2E, E_VEX_LIG | E_VEX_0F | E_VEX_WIG, R(src1), R(src2));} | ||
| 4780 | void vunpckhpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UNPCKHPD, 0x15, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4781 | void vunpckhpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_UNPCKHPD, 0x15, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4782 | void vunpckhpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_UNPCKHPD, 0x15, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4783 | void vunpckhpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_UNPCKHPD, 0x15, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4784 | void vunpckhps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UNPCKHPS, 0x15, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4785 | void vunpckhps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_UNPCKHPS, 0x15, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4786 | void vunpckhps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_UNPCKHPS, 0x15, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4787 | void vunpckhps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_UNPCKHPS, 0x15, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4788 | void vunpcklpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UNPCKLPD, 0x14, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4789 | void vunpcklpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_UNPCKLPD, 0x14, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4790 | void vunpcklpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_UNPCKLPD, 0x14, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4791 | void vunpcklpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_UNPCKLPD, 0x14, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4792 | void vunpcklps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UNPCKLPS, 0x14, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4793 | void vunpcklps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_UNPCKLPS, 0x14, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4794 | void vunpcklps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_UNPCKLPS, 0x14, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4795 | void vunpcklps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_UNPCKLPS, 0x14, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4796 | void vxorpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_XORPD, 0x57, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4797 | void vxorpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_XORPD, 0x57, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4798 | void vxorpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_XORPD, 0x57, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4799 | void vxorpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_XORPD, 0x57, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4800 | ✗ | void vxorps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_XORPS, 0x57, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4801 | void vxorps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_XORPS, 0x57, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 4802 | ✗ | void vxorps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_XORPS, 0x57, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4803 | ✗ | void vxorps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_XORPS, 0x57, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));} | |
| 4804 | void vzeroall() {AppendInstr(I_VZEROUPPER, 0x77, E_VEX_256_0F_WIG);} | ||
| 4805 | ✗ | void vzeroupper() {AppendInstr(I_VZEROUPPER, 0x77, E_VEX_128_0F_WIG);} | |
| 4806 | |||
| 4807 | // FMA | ||
| 4808 | void vfmadd132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD132PD, 0x98, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4809 | void vfmadd132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADD132PD, 0x98, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4810 | void vfmadd132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADD132PD, 0x98, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4811 | void vfmadd132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADD132PD, 0x98, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4812 | void vfmadd213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD213PD, 0xA8, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4813 | void vfmadd213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADD213PD, 0xA8, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4814 | void vfmadd213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADD213PD, 0xA8, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4815 | void vfmadd213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADD213PD, 0xA8, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4816 | void vfmadd231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD231PD, 0xB8, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4817 | void vfmadd231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADD231PD, 0xB8, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4818 | void vfmadd231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADD231PD, 0xB8, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4819 | void vfmadd231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADD231PD, 0xB8, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4820 | void vfmadd132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD132PS, 0x98, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4821 | void vfmadd132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADD132PS, 0x98, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4822 | void vfmadd132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADD132PS, 0x98, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4823 | void vfmadd132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADD132PS, 0x98, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4824 | void vfmadd213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD213PS, 0xA8, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4825 | void vfmadd213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADD213PS, 0xA8, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4826 | ✗ | void vfmadd213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADD213PS, 0xA8, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | |
| 4827 | ✗ | void vfmadd213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADD213PS, 0xA8, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | |
| 4828 | void vfmadd231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD231PS, 0xB8, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4829 | void vfmadd231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADD231PS, 0xB8, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4830 | ✗ | void vfmadd231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADD231PS, 0xB8, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | |
| 4831 | ✗ | void vfmadd231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADD231PS, 0xB8, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | |
| 4832 | void vfmadd132sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD132SD, 0x99, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4833 | void vfmadd132sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMADD132SD, 0x99, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4834 | void vfmadd213sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD213SD, 0xA9, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4835 | void vfmadd213sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMADD213SD, 0xA9, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4836 | void vfmadd231sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD231SD, 0xB9, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4837 | void vfmadd231sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMADD231SD, 0xB9, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4838 | void vfmadd132ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD132SS, 0x99, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4839 | void vfmadd132ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMADD132SS, 0x99, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4840 | void vfmadd213ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD213SS, 0xA9, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4841 | void vfmadd213ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMADD213SS, 0xA9, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4842 | void vfmadd231ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD231SS, 0xB9, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4843 | void vfmadd231ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMADD231SS, 0xB9, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4844 | void vfmaddsub132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADDSUB132PD, 0x96, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4845 | void vfmaddsub132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADDSUB132PD, 0x96, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4846 | void vfmaddsub132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADDSUB132PD, 0x96, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4847 | void vfmaddsub132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADDSUB132PD, 0x96, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4848 | void vfmaddsub213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADDSUB213PD, 0xA6, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4849 | void vfmaddsub213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADDSUB213PD, 0xA6, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4850 | void vfmaddsub213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADDSUB213PD, 0xA6, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4851 | void vfmaddsub213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADDSUB213PD, 0xA6, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4852 | void vfmaddsub231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADDSUB231PD, 0xB6, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4853 | void vfmaddsub231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADDSUB231PD, 0xB6, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4854 | void vfmaddsub231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADDSUB231PD, 0xB6, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4855 | void vfmaddsub231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADDSUB231PD, 0xB6, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4856 | void vfmaddsub132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADDSUB132PS, 0x96, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4857 | void vfmaddsub132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADDSUB132PS, 0x96, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4858 | void vfmaddsub132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADDSUB132PS, 0x96, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4859 | void vfmaddsub132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADDSUB132PS, 0x96, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4860 | void vfmaddsub213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADDSUB213PS, 0xA6, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4861 | void vfmaddsub213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADDSUB213PS, 0xA6, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4862 | void vfmaddsub213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADDSUB213PS, 0xA6, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4863 | void vfmaddsub213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADDSUB213PS, 0xA6, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4864 | void vfmaddsub231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADDSUB231PS, 0xB6, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4865 | void vfmaddsub231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADDSUB231PS, 0xB6, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4866 | void vfmaddsub231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADDSUB231PS, 0xB6, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4867 | void vfmaddsub231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADDSUB231PS, 0xB6, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4868 | void vfmsubadd132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUBADD132PD, 0x97, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4869 | void vfmsubadd132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUBADD132PD, 0x97, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4870 | void vfmsubadd132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUBADD132PD, 0x97, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4871 | void vfmsubadd132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUBADD132PD, 0x97, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4872 | void vfmsubadd213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUBADD213PD, 0xA7, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4873 | void vfmsubadd213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUBADD213PD, 0xA7, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4874 | void vfmsubadd213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUBADD213PD, 0xA7, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4875 | void vfmsubadd213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUBADD213PD, 0xA7, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4876 | void vfmsubadd231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUBADD231PD, 0xB7, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4877 | void vfmsubadd231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUBADD231PD, 0xB7, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4878 | void vfmsubadd231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUBADD231PD, 0xB7, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4879 | void vfmsubadd231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUBADD231PD, 0xB7, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4880 | void vfmsubadd132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUBADD132PS, 0x97, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4881 | void vfmsubadd132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUBADD132PS, 0x97, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4882 | void vfmsubadd132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUBADD132PS, 0x97, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4883 | void vfmsubadd132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUBADD132PS, 0x97, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4884 | void vfmsubadd213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUBADD213PS, 0xA7, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4885 | void vfmsubadd213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUBADD213PS, 0xA7, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4886 | void vfmsubadd213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUBADD213PS, 0xA7, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4887 | void vfmsubadd213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUBADD213PS, 0xA7, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4888 | void vfmsubadd231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUBADD231PS, 0xB7, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4889 | void vfmsubadd231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUBADD231PS, 0xB7, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4890 | void vfmsubadd231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUBADD231PS, 0xB7, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4891 | void vfmsubadd231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUBADD231PS, 0xB7, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4892 | void vfmsub132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB132PD, 0x9A, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4893 | void vfmsub132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUB132PD, 0x9A, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4894 | void vfmsub132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUB132PD, 0x9A, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4895 | void vfmsub132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUB132PD, 0x9A, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4896 | void vfmsub213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB213PD, 0xAA, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4897 | void vfmsub213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUB213PD, 0xAA, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4898 | void vfmsub213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUB213PD, 0xAA, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4899 | void vfmsub213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUB213PD, 0xAA, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4900 | void vfmsub231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB231PD, 0xBA, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4901 | void vfmsub231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUB231PD, 0xBA, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4902 | void vfmsub231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUB231PD, 0xBA, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4903 | void vfmsub231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUB231PD, 0xBA, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4904 | void vfmsub132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB132PS, 0x9A, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4905 | void vfmsub132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUB132PS, 0x9A, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4906 | void vfmsub132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUB132PS, 0x9A, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4907 | void vfmsub132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUB132PS, 0x9A, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4908 | void vfmsub213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB213PS, 0xAA, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4909 | void vfmsub213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUB213PS, 0xAA, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4910 | void vfmsub213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUB213PS, 0xAA, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4911 | void vfmsub213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUB213PS, 0xAA, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4912 | void vfmsub231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB231PS, 0xBA, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4913 | void vfmsub231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUB231PS, 0xBA, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4914 | void vfmsub231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUB231PS, 0xBA, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4915 | void vfmsub231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUB231PS, 0xBA, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4916 | void vfmsub132sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB132SD, 0x9B, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4917 | void vfmsub132sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMSUB132SD, 0x9B, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4918 | void vfmsub213sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB213SD, 0xAB, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4919 | void vfmsub213sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMSUB213SD, 0xAB, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4920 | void vfmsub231sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB231SD, 0xBB, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4921 | void vfmsub231sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMSUB231SD, 0xBB, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4922 | void vfmsub132ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB132SS, 0x9B, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4923 | void vfmsub132ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMSUB132SS, 0x9B, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4924 | void vfmsub213ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB213SS, 0xAB, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4925 | void vfmsub213ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMSUB213SS, 0xAB, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4926 | void vfmsub231ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB231SS, 0xBB, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4927 | void vfmsub231ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMSUB231SS, 0xBB, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4928 | void vfnmadd132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD132PD, 0x9C, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4929 | void vfnmadd132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMADD132PD, 0x9C, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4930 | void vfnmadd132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMADD132PD, 0x9C, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4931 | void vfnmadd132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMADD132PD, 0x9C, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4932 | void vfnmadd213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD213PD, 0xAC, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4933 | void vfnmadd213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMADD213PD, 0xAC, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4934 | void vfnmadd213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMADD213PD, 0xAC, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4935 | void vfnmadd213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMADD213PD, 0xAC, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4936 | void vfnmadd231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD231PD, 0xBC, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4937 | void vfnmadd231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMADD231PD, 0xBC, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4938 | void vfnmadd231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMADD231PD, 0xBC, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4939 | void vfnmadd231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMADD231PD, 0xBC, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4940 | void vfnmadd132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD132PS, 0x9C, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4941 | void vfnmadd132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMADD132PS, 0x9C, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4942 | void vfnmadd132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMADD132PS, 0x9C, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4943 | void vfnmadd132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMADD132PS, 0x9C, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4944 | void vfnmadd213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD213PS, 0xAC, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4945 | void vfnmadd213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMADD213PS, 0xAC, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4946 | void vfnmadd213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMADD213PS, 0xAC, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4947 | void vfnmadd213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMADD213PS, 0xAC, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4948 | void vfnmadd231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD231PS, 0xBC, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4949 | void vfnmadd231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMADD231PS, 0xBC, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4950 | void vfnmadd231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMADD231PS, 0xBC, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4951 | ✗ | void vfnmadd231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMADD231PS, 0xBC, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | |
| 4952 | void vfnmadd132sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD132SD, 0x9D, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4953 | void vfnmadd132sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMADD132SD, 0x9D, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4954 | void vfnmadd213sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD213SD, 0xAD, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4955 | void vfnmadd213sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMADD213SD, 0xAD, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4956 | void vfnmadd231sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD231SD, 0xBD, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4957 | void vfnmadd231sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMADD231SD, 0xBD, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4958 | void vfnmadd132ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD132SS, 0x9D, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4959 | void vfnmadd132ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMADD132SS, 0x9D, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4960 | void vfnmadd213ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD213SS, 0xAD, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4961 | void vfnmadd213ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMADD213SS, 0xAD, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4962 | void vfnmadd231ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD231SS, 0xBD, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4963 | void vfnmadd231ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMADD231SS, 0xBD, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4964 | void vfnmsub132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB132PD, 0x9E, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4965 | void vfnmsub132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMSUB132PD, 0x9E, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4966 | void vfnmsub132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMSUB132PD, 0x9E, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4967 | void vfnmsub132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMSUB132PD, 0x9E, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4968 | void vfnmsub213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB213PD, 0xAE, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4969 | void vfnmsub213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMSUB213PD, 0xAE, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4970 | void vfnmsub213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMSUB213PD, 0xAE, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4971 | void vfnmsub213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMSUB213PD, 0xAE, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4972 | void vfnmsub231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB231PD, 0xBE, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4973 | void vfnmsub231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMSUB231PD, 0xBE, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4974 | void vfnmsub231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMSUB231PD, 0xBE, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4975 | void vfnmsub231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMSUB231PD, 0xBE, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4976 | void vfnmsub132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB132PS, 0x9E, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4977 | void vfnmsub132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMSUB132PS, 0x9E, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4978 | void vfnmsub132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMSUB132PS, 0x9E, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4979 | void vfnmsub132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMSUB132PS, 0x9E, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4980 | void vfnmsub213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB213PS, 0xAE, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4981 | void vfnmsub213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMSUB213PS, 0xAE, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4982 | void vfnmsub213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMSUB213PS, 0xAE, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4983 | void vfnmsub213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMSUB213PS, 0xAE, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4984 | void vfnmsub231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB231PS, 0xBE, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4985 | void vfnmsub231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMSUB231PS, 0xBE, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4986 | void vfnmsub231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMSUB231PS, 0xBE, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4987 | void vfnmsub231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMSUB231PS, 0xBE, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4988 | void vfnmsub132sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB132SD, 0x9F, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4989 | void vfnmsub132sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMSUB132SD, 0x9F, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4990 | void vfnmsub213sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB213SD, 0xAF, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4991 | void vfnmsub213sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMSUB213SD, 0xAF, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4992 | void vfnmsub231sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB231SD, 0xBF, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4993 | void vfnmsub231sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMSUB231SD, 0xBF, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));} | ||
| 4994 | void vfnmsub132ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB132SS, 0x9F, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4995 | void vfnmsub132ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMSUB132SS, 0x9F, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4996 | void vfnmsub213ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB213SS, 0xAF, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4997 | void vfnmsub213ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMSUB213SS, 0xAF, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4998 | void vfnmsub231ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB231SS, 0xBF, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 4999 | void vfnmsub231ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMSUB231SS, 0xBF, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));} | ||
| 5000 | |||
| 5001 | // F16C | ||
| 5002 | #ifdef JITASM64 | ||
| 5003 | void rdfsbase(const Reg32& dst) {AppendInstr(I_RDFSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3, Imm8(0), W(dst));} | ||
| 5004 | void rdfsbase(const Reg64& dst) {AppendInstr(I_RDFSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, Imm8(0), W(dst));} | ||
| 5005 | void rdgsbase(const Reg32& dst) {AppendInstr(I_RDGSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3, Imm8(1), W(dst));} | ||
| 5006 | void rdgsbase(const Reg64& dst) {AppendInstr(I_RDGSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, Imm8(1), W(dst));} | ||
| 5007 | #endif | ||
| 5008 | void rdrand(const Reg16& dst) {AppendInstr(I_RDRAND, 0x0FC7, E_OPERAND_SIZE_PREFIX, Imm8(6), W(dst));} | ||
| 5009 | void rdrand(const Reg32& dst) {AppendInstr(I_RDRAND, 0x0FC7, 0, Imm8(6), W(dst));} | ||
| 5010 | #ifdef JITASM64 | ||
| 5011 | void rdrand(const Reg64& dst) {AppendInstr(I_RDRAND, 0x0FC7, E_REXW_PREFIX, Imm8(6), W(dst));} | ||
| 5012 | #endif | ||
| 5013 | #ifdef JITASM64 | ||
| 5014 | void wrfsbase(const Reg32& src) {AppendInstr(I_WRFSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3, Imm8(2), R(src));} | ||
| 5015 | void wrfsbase(const Reg64& src) {AppendInstr(I_WRFSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, Imm8(2), R(src));} | ||
| 5016 | void wrgsbase(const Reg32& src) {AppendInstr(I_WRGSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3, Imm8(3), R(src));} | ||
| 5017 | void wrgsbase(const Reg64& src) {AppendInstr(I_WRGSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, Imm8(3), R(src));} | ||
| 5018 | #endif | ||
| 5019 | void vcvtph2ps(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VCVTPH2PS, 0x13, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 5020 | ✗ | void vcvtph2ps(const YmmReg& dst, const Mem128& src) {AppendInstr(I_VCVTPH2PS, 0x13, E_VEX_256_66_0F38_W0, W(dst), R(src));} | |
| 5021 | void vcvtph2ps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VCVTPH2PS, 0x13, E_VEX_128_66_0F38_W0, W(dst), R(src));} | ||
| 5022 | ✗ | void vcvtph2ps(const XmmReg& dst, const Mem64& src) {AppendInstr(I_VCVTPH2PS, 0x13, E_VEX_128_66_0F38_W0, W(dst), R(src));} | |
| 5023 | void vcvtps2ph(const XmmReg& dst, const YmmReg& src, const Imm8& rc) {AppendInstr(I_VCVTPS2PH, 0x1D, E_VEX_256_66_0F3A_W0, R(src), W(dst), rc);} | ||
| 5024 | ✗ | void vcvtps2ph(const Mem128& dst, const YmmReg& src, const Imm8& rc) {AppendInstr(I_VCVTPS2PH, 0x1D, E_VEX_256_66_0F3A_W0, R(src), W(dst), rc);} | |
| 5025 | void vcvtps2ph(const XmmReg& dst, const XmmReg& src, const Imm8& rc) {AppendInstr(I_VCVTPS2PH, 0x1D, E_VEX_128_66_0F3A_W0, R(src), W(dst), rc);} | ||
| 5026 | ✗ | void vcvtps2ph(const Mem64& dst, const XmmReg& src, const Imm8& rc) {AppendInstr(I_VCVTPS2PH, 0x1D, E_VEX_128_66_0F3A_W0, R(src), W(dst), rc);} | |
| 5027 | |||
| 5028 | // BMI2 | ||
| 5029 | void andn(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_ANDN, 0xF2, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));} | ||
| 5030 | void andn(const Reg32& dst, const Reg32& src1, const Mem32& src2) {AppendInstr(I_ANDN, 0xF2, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));} | ||
| 5031 | #ifdef JITASM64 | ||
| 5032 | void andn(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_ANDN, 0xF2, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));} | ||
| 5033 | void andn(const Reg64& dst, const Reg64& src1, const Mem64& src2) {AppendInstr(I_ANDN, 0xF2, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));} | ||
| 5034 | #endif | ||
| 5035 | void bextr(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_BEXTR, 0xF7, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));} | ||
| 5036 | void bextr(const Reg32& dst, const Mem32& src1, const Reg32& src2) {AppendInstr(I_BEXTR, 0xF7, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));} | ||
| 5037 | #ifdef JITASM64 | ||
| 5038 | void bextr(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_BEXTR, 0xF7, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));} | ||
| 5039 | void bextr(const Reg64& dst, const Mem64& src1, const Reg64& src2) {AppendInstr(I_BEXTR, 0xF7, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));} | ||
| 5040 | #endif | ||
| 5041 | void blsi(const Reg32& dst, const Reg32& src) {AppendInstr(I_BLSI, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(3), R(src), W(dst));} | ||
| 5042 | void blsi(const Reg32& dst, const Mem32& src) {AppendInstr(I_BLSI, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(3), R(src), W(dst));} | ||
| 5043 | #ifdef JITASM64 | ||
| 5044 | void blsi(const Reg64& dst, const Reg64& src) {AppendInstr(I_BLSI, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(3), R(src), W(dst));} | ||
| 5045 | void blsi(const Reg64& dst, const Mem64& src) {AppendInstr(I_BLSI, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(3), R(src), W(dst));} | ||
| 5046 | #endif | ||
| 5047 | void blsmsk(const Reg32& dst, const Reg32& src) {AppendInstr(I_BLSMSK, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(2), R(src), W(dst));} | ||
| 5048 | void blsmsk(const Reg32& dst, const Mem32& src) {AppendInstr(I_BLSMSK, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(2), R(src), W(dst));} | ||
| 5049 | #ifdef JITASM64 | ||
| 5050 | void blsmsk(const Reg64& dst, const Reg64& src) {AppendInstr(I_BLSMSK, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(2), R(src), W(dst));} | ||
| 5051 | void blsmsk(const Reg64& dst, const Mem64& src) {AppendInstr(I_BLSMSK, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(2), R(src), W(dst));} | ||
| 5052 | #endif | ||
| 5053 | void blsr(const Reg32& dst, const Reg32& src) {AppendInstr(I_BLSR, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(1), R(src), W(dst));} | ||
| 5054 | void blsr(const Reg32& dst, const Mem32& src) {AppendInstr(I_BLSR, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(1), R(src), W(dst));} | ||
| 5055 | #ifdef JITASM64 | ||
| 5056 | void blsr(const Reg64& dst, const Reg64& src) {AppendInstr(I_BLSR, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(1), R(src), W(dst));} | ||
| 5057 | void blsr(const Reg64& dst, const Mem64& src) {AppendInstr(I_BLSR, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(1), R(src), W(dst));} | ||
| 5058 | #endif | ||
| 5059 | void bzhi(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_BZHI, 0xF5, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));} | ||
| 5060 | void bzhi(const Reg32& dst, const Mem32& src1, const Reg32& src2) {AppendInstr(I_BZHI, 0xF5, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));} | ||
| 5061 | #ifdef JITASM64 | ||
| 5062 | void bzhi(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_BZHI, 0xF5, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));} | ||
| 5063 | void bzhi(const Reg64& dst, const Mem64& src1, const Reg64& src2) {AppendInstr(I_BZHI, 0xF5, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));} | ||
| 5064 | #endif | ||
| 5065 | void lzcnt(const Reg16& dst, const Reg16& src) {AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 5066 | void lzcnt(const Reg16& dst, const Mem16& src) {AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 5067 | void lzcnt(const Reg32& dst, const Reg32& src) {AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 5068 | void lzcnt(const Reg32& dst, const Mem32& src) {AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 5069 | #ifdef JITASM64 | ||
| 5070 | void lzcnt(const Reg64& dst, const Reg64& src) {AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 5071 | void lzcnt(const Reg64& dst, const Mem64& src) {AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 5072 | #endif | ||
| 5073 | void mulx(const Reg32& dst1, const Reg32& dst2, const Reg32& src1, const Reg32& src2) {AppendInstr(I_MULX, 0xF6, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst1), R(src2), W(dst2), Dummy(R(src1), edx));} | ||
| 5074 | void mulx(const Reg32& dst1, const Reg32& dst2, const Reg32& src1, const Mem32& src2) {AppendInstr(I_MULX, 0xF6, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst1), R(src2), W(dst2), Dummy(R(src1), edx));} | ||
| 5075 | #ifdef JITASM64 | ||
| 5076 | void mulx(const Reg64& dst1, const Reg64& dst2, const Reg64& src1, const Reg64& src2) {AppendInstr(I_MULX, 0xF6, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst1), R(src2), W(dst2), Dummy(R(src1), rdx));} | ||
| 5077 | void mulx(const Reg64& dst1, const Reg64& dst2, const Reg64& src1, const Mem64& src2) {AppendInstr(I_MULX, 0xF6, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst1), R(src2), W(dst2), Dummy(R(src1), rdx));} | ||
| 5078 | #endif | ||
| 5079 | void pdep(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_PDEP, 0xF5, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));} | ||
| 5080 | void pdep(const Reg32& dst, const Reg32& src1, const Mem32& src2) {AppendInstr(I_PDEP, 0xF5, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));} | ||
| 5081 | #ifdef JITASM64 | ||
| 5082 | void pdep(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_PDEP, 0xF5, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));} | ||
| 5083 | void pdep(const Reg64& dst, const Reg64& src1, const Mem64& src2) {AppendInstr(I_PDEP, 0xF5, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));} | ||
| 5084 | #endif | ||
| 5085 | void pext(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_PEXT, 0xF5, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));} | ||
| 5086 | void pext(const Reg32& dst, const Reg32& src1, const Mem32& src2) {AppendInstr(I_PEXT, 0xF5, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));} | ||
| 5087 | #ifdef JITASM64 | ||
| 5088 | void pext(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_PEXT, 0xF5, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));} | ||
| 5089 | void pext(const Reg64& dst, const Reg64& src1, const Mem64& src2) {AppendInstr(I_PEXT, 0xF5, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));} | ||
| 5090 | #endif | ||
| 5091 | void rorx(const Reg32& dst, const Reg32& src, const Imm8& shift) {AppendInstr(I_RORX, 0xF0, E_VEX_LZ | E_VEX_F2 | E_VEX_0F3A | E_VEX_W0, W(dst), R(src), shift);} | ||
| 5092 | void rorx(const Reg32& dst, const Mem32& src, const Imm8& shift) {AppendInstr(I_RORX, 0xF0, E_VEX_LZ | E_VEX_F2 | E_VEX_0F3A | E_VEX_W0, W(dst), R(src), shift);} | ||
| 5093 | #ifdef JITASM64 | ||
| 5094 | void rorx(const Reg64& dst, const Reg64& src, const Imm8& shift) {AppendInstr(I_RORX, 0xF0, E_VEX_LZ | E_VEX_F2 | E_VEX_0F3A | E_VEX_W1, W(dst), R(src), shift);} | ||
| 5095 | void rorx(const Reg64& dst, const Mem64& src, const Imm8& shift) {AppendInstr(I_RORX, 0xF0, E_VEX_LZ | E_VEX_F2 | E_VEX_0F3A | E_VEX_W1, W(dst), R(src), shift);} | ||
| 5096 | #endif | ||
| 5097 | void sarx(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_SARX, 0xF7, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));} | ||
| 5098 | void sarx(const Reg32& dst, const Mem32& src1, const Reg32& src2) {AppendInstr(I_SARX, 0xF7, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));} | ||
| 5099 | #ifdef JITASM64 | ||
| 5100 | void sarx(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_SARX, 0xF7, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));} | ||
| 5101 | void sarx(const Reg64& dst, const Mem64& src1, const Reg64& src2) {AppendInstr(I_SARX, 0xF7, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));} | ||
| 5102 | #endif | ||
| 5103 | void shlx(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_SHLX, 0xF7, E_VEX_LZ | E_VEX_66 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));} | ||
| 5104 | void shlx(const Reg32& dst, const Mem32& src1, const Reg32& src2) {AppendInstr(I_SHLX, 0xF7, E_VEX_LZ | E_VEX_66 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));} | ||
| 5105 | #ifdef JITASM64 | ||
| 5106 | void shlx(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_SHLX, 0xF7, E_VEX_LZ | E_VEX_66 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));} | ||
| 5107 | void shlx(const Reg64& dst, const Mem64& src1, const Reg64& src2) {AppendInstr(I_SHLX, 0xF7, E_VEX_LZ | E_VEX_66 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));} | ||
| 5108 | #endif | ||
| 5109 | void shrx(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_SHRX, 0xF7, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));} | ||
| 5110 | void shrx(const Reg32& dst, const Mem32& src1, const Reg32& src2) {AppendInstr(I_SHRX, 0xF7, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));} | ||
| 5111 | #ifdef JITASM64 | ||
| 5112 | void shrx(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_SHRX, 0xF7, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));} | ||
| 5113 | void shrx(const Reg64& dst, const Mem64& src1, const Reg64& src2) {AppendInstr(I_SHRX, 0xF7, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));} | ||
| 5114 | #endif | ||
| 5115 | void tzcnt(const Reg16& dst, const Reg16& src) {AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 5116 | void tzcnt(const Reg16& dst, const Mem16& src) {AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));} | ||
| 5117 | void tzcnt(const Reg32& dst, const Reg32& src) {AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 5118 | void tzcnt(const Reg32& dst, const Mem32& src) {AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3, W(dst), R(src));} | ||
| 5119 | #ifdef JITASM64 | ||
| 5120 | void tzcnt(const Reg64& dst, const Reg64& src) {AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 5121 | void tzcnt(const Reg64& dst, const Mem64& src) {AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));} | ||
| 5122 | #endif | ||
| 5123 | #ifndef JITASM64 | ||
| 5124 | void invpcid(const Reg32& type, const Mem128& desc) {AppendInstr(I_INVPCID, 0x0F3882, E_MANDATORY_PREFIX_66, W(type), R(desc));} | ||
| 5125 | #else | ||
| 5126 | void invpcid(const Reg64& type, const Mem128& desc) {AppendInstr(I_INVPCID, 0x0F3882, E_MANDATORY_PREFIX_66, W(type), R(desc));} | ||
| 5127 | #endif | ||
| 5128 | |||
| 5129 | // XOP | ||
| 5130 | void vfrczpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VFRCZPD, 0x81, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5131 | void vfrczpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VFRCZPD, 0x81, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5132 | void vfrczpd(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_VFRCZPD, 0x81, E_XOP_256 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5133 | void vfrczpd(const YmmReg& dst, const Mem256& src) {AppendInstr(I_VFRCZPD, 0x81, E_XOP_256 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5134 | void vfrczps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VFRCZPS, 0x80, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5135 | void vfrczps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VFRCZPS, 0x80, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5136 | void vfrczps(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_VFRCZPS, 0x80, E_XOP_256 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5137 | void vfrczps(const YmmReg& dst, const Mem256& src) {AppendInstr(I_VFRCZPS, 0x80, E_XOP_256 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5138 | void vfrczsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VFRCZSD, 0x83, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5139 | void vfrczsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_VFRCZSD, 0x83, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5140 | void vfrczss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VFRCZSS, 0x82, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5141 | void vfrczss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_VFRCZSS, 0x82, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5142 | void vpcmov(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPCMOV, 0xA2, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5143 | void vpcmov(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPCMOV, 0xA2, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5144 | void vpcmov(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VPCMOV, 0xA2, E_XOP_128 | E_XOP_M01000 | E_XOP_W1 | E_XOP_P00, W(dst), R(src3), R(src1), R(src2));} | ||
| 5145 | void vpcmov(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VPCMOV, 0xA2, E_XOP_256 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5146 | void vpcmov(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VPCMOV, 0xA2, E_XOP_256 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5147 | void vpcmov(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VPCMOV, 0xA2, E_XOP_256 | E_XOP_M01000 | E_XOP_W1 | E_XOP_P00, W(dst), R(src3), R(src1), R(src2));} | ||
| 5148 | void vpcomb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMB, 0xCC, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5149 | void vpcomb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMB, 0xCC, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5150 | void vpcomd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMD, 0xCE, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5151 | void vpcomd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMD, 0xCE, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5152 | void vpcomq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMQ, 0xCF, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5153 | void vpcomq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMQ, 0xCF, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5154 | //void vpcomub(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMUB, 0x6C, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5155 | //void vpcomub(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMUB, 0x6C, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5156 | //void vpcomud(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMUD, 0x6E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5157 | //void vpcomud(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMUD, 0x6E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5158 | //void vpcomuq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMUQ, 0x6F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5159 | //void vpcomuq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMUQ, 0x6F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5160 | //void vpcomuw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMUW, 0x6D, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5161 | //void vpcomuw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMUW, 0x6D, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5162 | //void vpcomw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMW, 0xCD, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5163 | //void vpcomw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMW, 0xCD, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);} | ||
| 5164 | //void vpermil2pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_128 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));} | ||
| 5165 | //void vpermil2pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_128 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));} | ||
| 5166 | //void vpermil2pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_128 | E_XOP_M00011 | E_XOP_W1 | E_XOP_P01, W(dst), R(src3), R(src1), R(src2));} | ||
| 5167 | //void vpermil2pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_256 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));} | ||
| 5168 | //void vpermil2pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_256 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));} | ||
| 5169 | //void vpermil2pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_256 | E_XOP_M00011 | E_XOP_W1 | E_XOP_P01, W(dst), R(src3), R(src1), R(src2));} | ||
| 5170 | //void vpermil2ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_128 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));} | ||
| 5171 | //void vpermil2ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_128 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));} | ||
| 5172 | //void vpermil2ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_128 | E_XOP_M00011 | E_XOP_W1 | E_XOP_P01, W(dst), R(src3), R(src1), R(src2));} | ||
| 5173 | //void vpermil2ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_256 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));} | ||
| 5174 | //void vpermil2ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_256 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));} | ||
| 5175 | //void vpermil2ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_256 | E_XOP_M00011 | E_XOP_W1 | E_XOP_P01, W(dst), R(src3), R(src1), R(src2));} | ||
| 5176 | void vphaddbd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDBD, 0xC2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5177 | void vphaddbd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDBD, 0xC2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5178 | void vphaddbq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDBQ, 0xC3, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5179 | void vphaddbq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDBQ, 0xC3, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5180 | void vphaddbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDBW, 0xC1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5181 | void vphaddbw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDBW, 0xC1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5182 | void vphadddq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDDQ, 0xCB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5183 | void vphadddq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDDQ, 0xCB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5184 | void vphaddubd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUBD, 0xD2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5185 | void vphaddubd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUBD, 0xD2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5186 | void vphaddubq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUBQ, 0xD3, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5187 | void vphaddubq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUBQ, 0xD3, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5188 | void vphaddubw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUBW, 0xD1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5189 | void vphaddubw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUBW, 0xD1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5190 | //void vphaddudq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUDQ, 0xDB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5191 | //void vphaddudq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUDQ, 0xDB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5192 | void vphadduwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUWD, 0xD6, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5193 | void vphadduwd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUWD, 0xD6, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5194 | void vphadduwq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUWQ, 0xD7, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5195 | void vphadduwq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUWQ, 0xD7, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5196 | void vphaddwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUWD, 0xC6, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5197 | void vphaddwd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUWD, 0xC6, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5198 | void vphaddwq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDWQ, 0xC7, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5199 | void vphaddwq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDWQ, 0xC7, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5200 | void vphsubbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHSUBBW, 0xE1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5201 | void vphsubbw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHSUBBW, 0xE1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5202 | //void vphsubdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHSUBDQ, 0xDB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5203 | //void vphsubdq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHSUBDQ, 0xDB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5204 | void vphsubwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHSUBWD, 0xE2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5205 | void vphsubwd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHSUBWD, 0xE2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));} | ||
| 5206 | void vpmacsdd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSDD, 0x9E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5207 | void vpmacsdd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSDD, 0x9E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5208 | void vpmacsdqh(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSDQH, 0x9F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5209 | void vpmacsdqh(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSDQH, 0x9F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5210 | void vpmacsdql(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSDQL, 0x97, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5211 | void vpmacsdql(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSDQL, 0x97, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5212 | void vpmacssdd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSDD, 0x8E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5213 | void vpmacssdd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSDD, 0x8E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5214 | void vpmacssdqh(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSDQH, 0x8F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5215 | void vpmacssdqh(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSDQH, 0x8F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5216 | void vpmacssdql(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSDQL, 0x87, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5217 | void vpmacssdql(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSDQL, 0x87, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5218 | void vpmacsswd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSWD, 0x86, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5219 | void vpmacsswd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSWD, 0x86, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5220 | void vpmacssww(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSWW, 0x85, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5221 | void vpmacssww(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSWW, 0x85, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5222 | void vpmacswd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSWD, 0x96, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5223 | void vpmacswd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSWD, 0x96, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5224 | void vpmacsww(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSWW, 0x95, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5225 | void vpmacsww(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSWW, 0x95, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5226 | void vpmadcsswd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMADCSSWD, 0xA6, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5227 | void vpmadcsswd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMADCSSWD, 0xA6, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5228 | void vpmadcswd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMADCSWD, 0xB6, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5229 | void vpmadcswd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMADCSWD, 0xB6, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5230 | void vpperm(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPPERM, 0xA3, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5231 | void vpperm(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPPERM, 0xA3, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));} | ||
| 5232 | void vpperm(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VPPERM, 0xA3, E_XOP_128 | E_XOP_M01000 | E_XOP_W1 | E_XOP_P00, W(dst), R(src3), R(src1), R(src2));} | ||
| 5233 | void vprotb(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPROTB, 0x90, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5234 | void vprotb(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPROTB, 0x90, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5235 | void vprotb(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPROTB, 0x90, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));} | ||
| 5236 | void vprotb(const XmmReg& dst, const XmmReg& src1, const Imm8& count) {AppendInstr(I_VPROTB, 0xC0, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);} | ||
| 5237 | void vprotb(const XmmReg& dst, const Mem128& src1, const Imm8& count) {AppendInstr(I_VPROTB, 0xC0, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);} | ||
| 5238 | void vprotd(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPROTD, 0x92, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5239 | void vprotd(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPROTD, 0x92, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5240 | void vprotd(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPROTD, 0x92, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));} | ||
| 5241 | void vprotd(const XmmReg& dst, const XmmReg& src1, const Imm8& count) {AppendInstr(I_VPROTD, 0xC2, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);} | ||
| 5242 | void vprotd(const XmmReg& dst, const Mem128& src1, const Imm8& count) {AppendInstr(I_VPROTD, 0xC2, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);} | ||
| 5243 | void vprotq(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPROTQ, 0x93, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5244 | void vprotq(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPROTQ, 0x93, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5245 | void vprotq(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPROTQ, 0x93, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));} | ||
| 5246 | void vprotq(const XmmReg& dst, const XmmReg& src1, const Imm8& count) {AppendInstr(I_VPROTQ, 0xC3, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);} | ||
| 5247 | void vprotq(const XmmReg& dst, const Mem128& src1, const Imm8& count) {AppendInstr(I_VPROTQ, 0xC3, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);} | ||
| 5248 | void vprotw(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPROTW, 0x91, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5249 | void vprotw(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPROTW, 0x91, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5250 | void vprotw(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPROTW, 0x91, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));} | ||
| 5251 | void vprotw(const XmmReg& dst, const XmmReg& src1, const Imm8& count) {AppendInstr(I_VPROTW, 0xC1, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);} | ||
| 5252 | void vprotw(const XmmReg& dst, const Mem128& src1, const Imm8& count) {AppendInstr(I_VPROTW, 0xC1, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);} | ||
| 5253 | void vpshab(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHAB, 0x98, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5254 | void vpshab(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHAB, 0x98, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5255 | void vpshab(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHAB, 0x98, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));} | ||
| 5256 | void vpshad(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHAD, 0x9A, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5257 | void vpshad(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHAD, 0x9A, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5258 | void vpshad(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHAD, 0x9A, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));} | ||
| 5259 | void vpshaq(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHAQ, 0x9B, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5260 | void vpshaq(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHAQ, 0x9B, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5261 | void vpshaq(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHAQ, 0x9B, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));} | ||
| 5262 | void vpshaw(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHAW, 0x99, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5263 | void vpshaw(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHAW, 0x99, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5264 | void vpshaw(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHAW, 0x99, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));} | ||
| 5265 | void vpshlb(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHLB, 0x94, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5266 | void vpshlb(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHLB, 0x94, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5267 | void vpshlb(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHLB, 0x94, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));} | ||
| 5268 | void vpshld(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHLD, 0x96, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5269 | void vpshld(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHLD, 0x96, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5270 | void vpshld(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHLD, 0x96, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));} | ||
| 5271 | void vpshlq(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHLQ, 0x97, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5272 | void vpshlq(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHLQ, 0x97, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5273 | void vpshlq(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHLQ, 0x97, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));} | ||
| 5274 | void vpshlw(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHLW, 0x95, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5275 | void vpshlw(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHLW, 0x95, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));} | ||
| 5276 | void vpshlw(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHLW, 0x95, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));} | ||
| 5277 | |||
| 5278 | // FMA4 | ||
| 5279 | void vfmaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMADDPD, 0x69, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5280 | void vfmaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMADDPD, 0x69, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5281 | void vfmaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMADDPD, 0x69, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5282 | void vfmaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMADDPD, 0x69, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5283 | void vfmaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMADDPD, 0x69, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5284 | void vfmaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMADDPD, 0x69, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5285 | void vfmaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMADDPS, 0x68, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5286 | void vfmaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMADDPS, 0x68, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5287 | void vfmaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMADDPS, 0x68, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5288 | void vfmaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMADDPS, 0x68, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5289 | void vfmaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMADDPS, 0x68, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5290 | void vfmaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMADDPS, 0x68, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5291 | void vfmaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSD, 0x6B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5292 | void vfmaddsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSD, 0x6B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5293 | void vfmaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem64& src3) {AppendInstr(I_VFMADDSD, 0x6B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5294 | void vfmaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSS, 0x6A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5295 | void vfmaddss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSS, 0x6A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5296 | void vfmaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem32& src3) {AppendInstr(I_VFMADDSS, 0x6A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5297 | void vfmaddsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5298 | void vfmaddsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5299 | void vfmaddsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5300 | void vfmaddsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5301 | void vfmaddsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5302 | void vfmaddsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5303 | void vfmaddsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5304 | void vfmaddsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5305 | void vfmaddsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5306 | void vfmaddsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5307 | void vfmaddsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5308 | void vfmaddsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5309 | void vfmsubaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5310 | void vfmsubaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5311 | void vfmsubaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5312 | void vfmsubaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5313 | void vfmsubaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5314 | void vfmsubaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5315 | void vfmsubaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5316 | void vfmsubaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5317 | void vfmsubaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5318 | void vfmsubaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5319 | void vfmsubaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5320 | void vfmsubaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5321 | void vfmsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5322 | void vfmsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5323 | void vfmsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5324 | void vfmsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5325 | void vfmsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5326 | void vfmsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5327 | void vfmsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5328 | void vfmsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5329 | void vfmsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5330 | void vfmsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5331 | void vfmsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5332 | void vfmsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5333 | void vfmsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBSD, 0x6F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5334 | void vfmsubsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBSD, 0x6F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5335 | void vfmsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem64& src3) {AppendInstr(I_VFMSUBSD, 0x6F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5336 | void vfmsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBSS, 0x6E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5337 | void vfmsubss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBSS, 0x6E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5338 | void vfmsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem32& src3) {AppendInstr(I_VFMSUBSS, 0x6E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5339 | void vfnmaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDPD, 0x79, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5340 | void vfnmaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDPD, 0x79, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5341 | void vfnmaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFNMADDPD, 0x79, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5342 | void vfnmaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFNMADDPD, 0x79, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5343 | void vfnmaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFNMADDPD, 0x79, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5344 | void vfnmaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFNMADDPD, 0x79, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5345 | void vfnmaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDPS, 0x78, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5346 | void vfnmaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDPS, 0x78, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5347 | void vfnmaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFNMADDPS, 0x78, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5348 | void vfnmaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFNMADDPS, 0x78, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5349 | void vfnmaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFNMADDPS, 0x78, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5350 | void vfnmaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFNMADDPS, 0x78, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5351 | void vfnmaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDSD, 0x7B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5352 | void vfnmaddsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDSD, 0x7B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5353 | void vfnmaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem64& src3) {AppendInstr(I_VFNMADDSD, 0x7B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5354 | void vfnmaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDSS, 0x7A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5355 | void vfnmaddss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDSS, 0x7A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5356 | void vfnmaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem32& src3) {AppendInstr(I_VFNMADDSS, 0x7A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5357 | void vfnmsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5358 | void vfnmsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5359 | void vfnmsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5360 | void vfnmsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5361 | void vfnmsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5362 | void vfnmsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5363 | void vfnmsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5364 | void vfnmsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5365 | void vfnmsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5366 | void vfnmsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5367 | void vfnmsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5368 | void vfnmsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5369 | void vfnmsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBSD, 0x7F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5370 | void vfnmsubsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBSD, 0x7F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5371 | void vfnmsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem64& src3) {AppendInstr(I_VFNMSUBSD, 0x7F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5372 | void vfnmsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBSS, 0x7E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5373 | void vfnmsubss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBSS, 0x7E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));} | ||
| 5374 | void vfnmsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem32& src3) {AppendInstr(I_VFNMSUBSS, 0x7E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));} | ||
| 5375 | |||
| 5376 | // AVX2 | ||
| 5377 | void vbroadcastss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VBROADCASTSS, 0x18, E_VEX_128_66_0F38_W0, W(dst), R(src));} | ||
| 5378 | ✗ | void vbroadcastss(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VBROADCASTSS, 0x18, E_VEX_256_66_0F38_W0, W(dst), R(src));} | |
| 5379 | void vbroadcastsd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VBROADCASTSD, 0x19, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 5380 | void vbroadcasti128(const YmmReg& dst, const Mem128& src) {AppendInstr(I_VBROADCASTI128, 0x5A, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 5381 | ✗ | void vextracti128(const XmmReg& dst, const YmmReg& src, const Imm8& offset) {AppendInstr(I_VEXTRACTI128, 0x39, E_VEX_256_66_0F3A_W0, R(src), W(dst), offset);} | |
| 5382 | void vextracti128(const Mem128& dst, const YmmReg& src, const Imm8& offset) {AppendInstr(I_VEXTRACTI128, 0x39, E_VEX_256_66_0F3A_W0, R(src), W(dst), offset);} | ||
| 5383 | void vgatherdps(const XmmReg& dst, const Mem32vxd& src, const XmmReg& mask) {AppendInstr(I_VGATHERDPS, 0x92, E_VEX_128_66_0F38_W0, RW(dst), R(src), R(mask));} | ||
| 5384 | void vgatherdps(const YmmReg& dst, const Mem32vyd& src, const YmmReg& mask) {AppendInstr(I_VGATHERDPS, 0x92, E_VEX_256_66_0F38_W0, RW(dst), R(src), R(mask));} | ||
| 5385 | void vgatherqps(const XmmReg& dst, const Mem64vxd& src, const XmmReg& mask) {AppendInstr(I_VGATHERQPS, 0x93, E_VEX_128_66_0F38_W0, RW(dst), R(src), R(mask));} | ||
| 5386 | void vgatherqps(const XmmReg& dst, const Mem64vyd& src, const XmmReg& mask) {AppendInstr(I_VGATHERQPS, 0x93, E_VEX_256_66_0F38_W0, RW(dst), R(src), R(mask));} | ||
| 5387 | void vgatherdpd(const XmmReg& dst, const Mem32vxq& src, const XmmReg& mask) {AppendInstr(I_VGATHERDPD, 0x92, E_VEX_128_66_0F38_W1, RW(dst), R(src), R(mask));} | ||
| 5388 | void vgatherdpd(const YmmReg& dst, const Mem32vxq& src, const YmmReg& mask) {AppendInstr(I_VGATHERDPD, 0x92, E_VEX_256_66_0F38_W1, RW(dst), R(src), R(mask));} | ||
| 5389 | void vgatherqpd(const XmmReg& dst, const Mem64vxq& src, const XmmReg& mask) {AppendInstr(I_VGATHERQPD, 0x93, E_VEX_128_66_0F38_W1, RW(dst), R(src), R(mask));} | ||
| 5390 | void vgatherqpd(const YmmReg& dst, const Mem64vyq& src, const YmmReg& mask) {AppendInstr(I_VGATHERQPD, 0x93, E_VEX_256_66_0F38_W1, RW(dst), R(src), R(mask));} | ||
| 5391 | void vinserti128(const YmmReg& dst, const YmmReg& src1, const XmmReg& src2, const Imm8& offset) {AppendInstr(I_VINSERTI128, 0x38, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), offset);} | ||
| 5392 | void vinserti128(const YmmReg& dst, const YmmReg& src1, const Mem128& src2, const Imm8& offset) {AppendInstr(I_VINSERTI128, 0x38, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), offset);} | ||
| 5393 | void vmovntdqa(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVNTDQA, 0x2A, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5394 | void vmpsadbw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& i) {AppendInstr(I_MPSADBW, 0x42, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src2), R(src1), i);} | ||
| 5395 | void vmpsadbw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& i) {AppendInstr(I_MPSADBW, 0x42, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src2), R(src1), i);} | ||
| 5396 | void vpabsb(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_PABSB, 0x1C, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5397 | void vpabsb(const YmmReg& dst, const Mem256& src) {AppendInstr(I_PABSB, 0x1C, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5398 | void vpabsw(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_PABSW, 0x1D, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5399 | void vpabsw(const YmmReg& dst, const Mem256& src) {AppendInstr(I_PABSW, 0x1D, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5400 | void vpabsd(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_PABSD, 0x1E, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5401 | void vpabsd(const YmmReg& dst, const Mem256& src) {AppendInstr(I_PABSD, 0x1E, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5402 | void vpacksswb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PACKSSWB, 0x63, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5403 | void vpacksswb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PACKSSWB, 0x63, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5404 | void vpackssdw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PACKSSDW, 0x6B, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5405 | void vpackssdw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PACKSSDW, 0x6B, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5406 | void vpackuswb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PACKUSWB, 0x67, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5407 | void vpackuswb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PACKUSWB, 0x67, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5408 | void vpackusdw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PACKUSDW, 0x2B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5409 | void vpackusdw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PACKUSDW, 0x2B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5410 | void vpaddb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDB, 0xFC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5411 | void vpaddb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDB, 0xFC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5412 | void vpaddw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDW, 0xFD, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5413 | void vpaddw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDW, 0xFD, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5414 | void vpaddd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDD, 0xFE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5415 | ✗ | void vpaddd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDD, 0xFE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | |
| 5416 | void vpaddq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDQ, 0xD4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5417 | void vpaddq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDQ, 0xD4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5418 | void vpaddsb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDSB, 0xEC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5419 | void vpaddsb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDSB, 0xEC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5420 | void vpaddsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDSW, 0xED, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5421 | void vpaddsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDSW, 0xED, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5422 | void vpaddusb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDUSB, 0xDC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5423 | void vpaddusb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDUSB, 0xDC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5424 | void vpaddusw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDUSW, 0xDD, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5425 | void vpaddusw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDUSW, 0xDD, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5426 | void vpalignr(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& i) {AppendInstr(I_PALIGNR, 0x0F, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);} | ||
| 5427 | void vpalignr(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& i) {AppendInstr(I_PALIGNR, 0x0F, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);} | ||
| 5428 | void vpand(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PAND, 0xDB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5429 | void vpand(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PAND, 0xDB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5430 | void vpandn(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PANDN, 0xDF, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5431 | void vpandn(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PANDN, 0xDF, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5432 | void vpavgb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PAVGB, 0xE0, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5433 | void vpavgb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PAVGB, 0xE0, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5434 | void vpavgw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PAVGW, 0xE3, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5435 | void vpavgw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PAVGW, 0xE3, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5436 | void vpblendvb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& mask) {AppendInstr(I_PBLENDVB, 0x4C, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), R(mask));} | ||
| 5437 | void vpblendvb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& mask) {AppendInstr(I_PBLENDVB, 0x4C, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), R(mask));} | ||
| 5438 | void vpblendw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask) {AppendInstr(I_PBLENDW, 0x0E, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 5439 | void vpblendw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask) {AppendInstr(I_PBLENDW, 0x0E, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);} | ||
| 5440 | void vpblendd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_PBLENDD, 0x02, E_VEX_128_66_0F3A_W0, W(dst), R(src2), R(src1), mask);} | ||
| 5441 | void vpblendd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_PBLENDD, 0x02, E_VEX_128_66_0F3A_W0, W(dst), R(src2), R(src1), mask);} | ||
| 5442 | void vpblendd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask) {AppendInstr(I_PBLENDD, 0x02, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), mask);} | ||
| 5443 | void vpblendd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask) {AppendInstr(I_PBLENDD, 0x02, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), mask);} | ||
| 5444 | void vpbroadcastb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTB, 0x78, E_VEX_128_66_0F38_W0, W(dst), R(src));} | ||
| 5445 | void vpbroadcastb(const XmmReg& dst, const Mem8& src) {AppendInstr(I_VPBROADCASTB, 0x78, E_VEX_128_66_0F38_W0, W(dst), R(src));} | ||
| 5446 | void vpbroadcastb(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTB, 0x78, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 5447 | void vpbroadcastb(const YmmReg& dst, const Mem8& src) {AppendInstr(I_VPBROADCASTB, 0x78, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 5448 | void vpbroadcastw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTW, 0x79, E_VEX_128_66_0F38_W0, W(dst), R(src));} | ||
| 5449 | void vpbroadcastw(const XmmReg& dst, const Mem16& src) {AppendInstr(I_VPBROADCASTW, 0x79, E_VEX_128_66_0F38_W0, W(dst), R(src));} | ||
| 5450 | void vpbroadcastw(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTW, 0x79, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 5451 | void vpbroadcastw(const YmmReg& dst, const Mem16& src) {AppendInstr(I_VPBROADCASTW, 0x79, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 5452 | void vpbroadcastd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTD, 0x58, E_VEX_128_66_0F38_W0, W(dst), R(src));} | ||
| 5453 | void vpbroadcastd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_VPBROADCASTD, 0x58, E_VEX_128_66_0F38_W0, W(dst), R(src));} | ||
| 5454 | void vpbroadcastd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTD, 0x58, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 5455 | void vpbroadcastd(const YmmReg& dst, const Mem32& src) {AppendInstr(I_VPBROADCASTD, 0x58, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 5456 | void vpbroadcastq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTQ, 0x59, E_VEX_128_66_0F38_W0, W(dst), R(src));} | ||
| 5457 | void vpbroadcastq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_VPBROADCASTQ, 0x59, E_VEX_128_66_0F38_W0, W(dst), R(src));} | ||
| 5458 | void vpbroadcastq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTQ, 0x59, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 5459 | void vpbroadcastq(const YmmReg& dst, const Mem64& src) {AppendInstr(I_VPBROADCASTQ, 0x59, E_VEX_256_66_0F38_W0, W(dst), R(src));} | ||
| 5460 | void vpcmpeqb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPEQB, 0x74, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5461 | void vpcmpeqb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPEQB, 0x74, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5462 | void vpcmpeqw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPEQW, 0x75, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5463 | void vpcmpeqw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPEQW, 0x75, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5464 | void vpcmpeqd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPEQD, 0x76, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5465 | void vpcmpeqd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPEQD, 0x76, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5466 | void vpcmpeqq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPEQQ, 0x29, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5467 | void vpcmpeqq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPEQQ, 0x29, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5468 | void vpcmpgtb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPGTB, 0x64, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5469 | void vpcmpgtb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPGTB, 0x64, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5470 | void vpcmpgtw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPGTW, 0x65, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5471 | void vpcmpgtw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPGTW, 0x65, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5472 | void vpcmpgtd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPGTD, 0x66, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5473 | void vpcmpgtd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPGTD, 0x66, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5474 | void vpcmpgtq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPGTQ, 0x37, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5475 | void vpcmpgtq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPGTQ, 0x37, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5476 | void vpermd(const YmmReg& dst, const YmmReg& offsets, const YmmReg& src) {AppendInstr(I_VPERMD, 0x36, E_VEX_256_66_0F38_W0, W(dst), R(src), R(offsets));} | ||
| 5477 | void vpermd(const YmmReg& dst, const YmmReg& offsets, const Mem256& src) {AppendInstr(I_VPERMD, 0x36, E_VEX_256_66_0F38_W0, W(dst), R(src), R(offsets));} | ||
| 5478 | void vpermq(const YmmReg& dst, const YmmReg& src, const Imm8& control) {AppendInstr(I_VPERMQ, 0x00, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(src), control);} | ||
| 5479 | void vpermq(const YmmReg& dst, const Mem256& src, const Imm8& control) {AppendInstr(I_VPERMQ, 0x00, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(src), control);} | ||
| 5480 | void vpermps(const YmmReg& dst, const YmmReg& offsets, const YmmReg& src) {AppendInstr(I_VPERMPS, 0x16, E_VEX_256_66_0F38_W0, W(dst), R(src), R(offsets));} | ||
| 5481 | void vpermps(const YmmReg& dst, const YmmReg& offsets, const Mem256& src) {AppendInstr(I_VPERMPS, 0x16, E_VEX_256_66_0F38_W0, W(dst), R(src), R(offsets));} | ||
| 5482 | void vpermpd(const YmmReg& dst, const YmmReg& src, const Imm8& control) {AppendInstr(I_VPERMPD, 0x01, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(src), control);} | ||
| 5483 | void vpermpd(const YmmReg& dst, const Mem256& src, const Imm8& control) {AppendInstr(I_VPERMPD, 0x01, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(src), control);} | ||
| 5484 | void vperm2i128(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& control) {AppendInstr(I_VPERM2I128, 0x46, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), control);} | ||
| 5485 | void vperm2i128(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& control) {AppendInstr(I_VPERM2I128, 0x46, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), control);} | ||
| 5486 | void vpgatherdd(const XmmReg& dst, const Mem32vxd& src, const XmmReg& mask) {AppendInstr(I_VPGATHERDD, 0x90, E_VEX_128_66_0F38_W0, RW(dst), R(src), R(mask));} | ||
| 5487 | void vpgatherdd(const YmmReg& dst, const Mem32vyd& src, const YmmReg& mask) {AppendInstr(I_VPGATHERDD, 0x90, E_VEX_256_66_0F38_W0, RW(dst), R(src), R(mask));} | ||
| 5488 | void vpgatherqd(const XmmReg& dst, const Mem64vxd& src, const XmmReg& mask) {AppendInstr(I_VPGATHERQD, 0x91, E_VEX_128_66_0F38_W0, RW(dst), R(src), R(mask));} | ||
| 5489 | void vpgatherqd(const XmmReg& dst, const Mem64vyd& src, const XmmReg& mask) {AppendInstr(I_VPGATHERQD, 0x91, E_VEX_256_66_0F38_W0, RW(dst), R(src), R(mask));} | ||
| 5490 | void vpgatherdq(const XmmReg& dst, const Mem32vxq& src, const XmmReg& mask) {AppendInstr(I_VPGATHERDQ, 0x90, E_VEX_128_66_0F38_W1, RW(dst), R(src), R(mask));} | ||
| 5491 | void vpgatherdq(const YmmReg& dst, const Mem32vxq& src, const YmmReg& mask) {AppendInstr(I_VPGATHERDQ, 0x90, E_VEX_256_66_0F38_W1, RW(dst), R(src), R(mask));} | ||
| 5492 | void vpgatherqq(const XmmReg& dst, const Mem64vxq& src, const XmmReg& mask) {AppendInstr(I_VPGATHERQQ, 0x91, E_VEX_128_66_0F38_W1, RW(dst), R(src), R(mask));} | ||
| 5493 | void vpgatherqq(const YmmReg& dst, const Mem64vyq& src, const YmmReg& mask) {AppendInstr(I_VPGATHERQQ, 0x91, E_VEX_256_66_0F38_W1, RW(dst), R(src), R(mask));} | ||
| 5494 | void vphaddw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PHADDW, 0x01, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5495 | void vphaddw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PHADDW, 0x01, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5496 | void vphaddd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PHADDD, 0x02, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5497 | void vphaddd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PHADDD, 0x02, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5498 | void vphaddsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PHADDSW, 0x03, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5499 | void vphaddsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PHADDSW, 0x03, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5500 | void vphsubw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PHSUBW, 0x05, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5501 | void vphsubw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PHSUBW, 0x05, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5502 | void vphsubd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PHSUBD, 0x06, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5503 | void vphsubd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PHSUBD, 0x06, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5504 | void vphsubsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PHSUBSW, 0x07, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5505 | void vphsubsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PHSUBSW, 0x07, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5506 | void vpmaddwd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMADDWD, 0xF5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5507 | void vpmaddwd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMADDWD, 0xF5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5508 | void vpmaddubsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMADDUBSW,0x04, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5509 | void vpmaddubsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMADDUBSW,0x04, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5510 | void vpmaskmovd(const XmmReg& dst, const XmmReg& mask, const Mem128& src) {AppendInstr(I_VMASKMOVD, 0x8C, E_VEX_128_66_0F38_W0, W(dst), R(src), R(mask));} | ||
| 5511 | void vpmaskmovd(const YmmReg& dst, const YmmReg& mask, const Mem256& src) {AppendInstr(I_VMASKMOVD, 0x8C, E_VEX_256_66_0F38_W0, W(dst), R(src), R(mask));} | ||
| 5512 | void vpmaskmovq(const XmmReg& dst, const XmmReg& mask, const Mem128& src) {AppendInstr(I_VMASKMOVQ, 0x8C, E_VEX_128_66_0F38_W1, W(dst), R(src), R(mask));} | ||
| 5513 | void vpmaskmovq(const YmmReg& dst, const YmmReg& mask, const Mem256& src) {AppendInstr(I_VMASKMOVQ, 0x8C, E_VEX_256_66_0F38_W1, W(dst), R(src), R(mask));} | ||
| 5514 | void vpmaskmovd(const Mem128& dst, const XmmReg& mask, const XmmReg& src) {AppendInstr(I_VMASKMOVD, 0x8E, E_VEX_128_66_0F38_W0, R(src), W(dst), R(mask));} | ||
| 5515 | void vpmaskmovd(const Mem256& dst, const YmmReg& mask, const YmmReg& src) {AppendInstr(I_VMASKMOVD, 0x8E, E_VEX_256_66_0F38_W0, R(src), W(dst), R(mask));} | ||
| 5516 | void vpmaskmovq(const Mem128& dst, const XmmReg& mask, const XmmReg& src) {AppendInstr(I_VMASKMOVQ, 0x8E, E_VEX_128_66_0F38_W1, R(src), W(dst), R(mask));} | ||
| 5517 | void vpmaskmovq(const Mem256& dst, const YmmReg& mask, const YmmReg& src) {AppendInstr(I_VMASKMOVQ, 0x8E, E_VEX_256_66_0F38_W1, R(src), W(dst), R(mask));} | ||
| 5518 | void vpmaxsb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMAXSB, 0x3C, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5519 | void vpmaxsb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMAXSB, 0x3C, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5520 | void vpmaxsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMAXSW, 0xEE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5521 | void vpmaxsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMAXSW, 0xEE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5522 | void vpmaxsd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMAXSD, 0x3D, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5523 | void vpmaxsd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMAXSD, 0x3D, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5524 | void vpmaxub(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMAXUB, 0xDE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5525 | void vpmaxub(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMAXUB, 0xDE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5526 | void vpmaxuw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMAXUW, 0x3E, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5527 | void vpmaxuw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMAXUW, 0x3E, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5528 | void vpmaxud(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMAXUD, 0x3F, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5529 | void vpmaxud(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMAXUD, 0x3F, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5530 | void vpminsb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMINSB, 0x38, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5531 | void vpminsb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMINSB, 0x38, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5532 | void vpminsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMINSW, 0xEA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5533 | void vpminsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMINSW, 0xEA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5534 | void vpminsd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMINSD, 0x39, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5535 | void vpminsd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMINSD, 0x39, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5536 | void vpminub(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMINUB, 0xDA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5537 | void vpminub(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMINUB, 0xDA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5538 | void vpminuw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMINUW, 0x3A, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5539 | void vpminuw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMINUW, 0x3A, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5540 | void vpminud(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMINUD, 0x3B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5541 | void vpminud(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMINUD, 0x3B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5542 | void vpmovmskb(const Reg32& dst, const YmmReg& src) {AppendInstr(I_PMOVMSKB, 0xD7, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 5543 | #ifdef JITASM64 | ||
| 5544 | void vpmovmskb(const Reg64& dst, const YmmReg& src) {AppendInstr(I_PMOVMSKB, 0xD7, E_VEX_256_66_0F_WIG, W(dst), R(src));} | ||
| 5545 | #endif | ||
| 5546 | void vpmovsxbw(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBW, 0x20, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5547 | void vpmovsxbw(const YmmReg& dst, const Mem128& src) {AppendInstr(I_PMOVSXBW, 0x20, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5548 | void vpmovsxbd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBD, 0x21, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5549 | void vpmovsxbd(const YmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXBD, 0x21, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5550 | void vpmovsxbq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBQ, 0x22, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5551 | void vpmovsxbq(const YmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVSXBQ, 0x22, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5552 | void vpmovsxwd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXWD, 0x23, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5553 | void vpmovsxwd(const YmmReg& dst, const Mem128& src) {AppendInstr(I_PMOVSXWD, 0x23, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5554 | void vpmovsxwq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXWQ, 0x24, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5555 | void vpmovsxwq(const YmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXWQ, 0x24, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5556 | void vpmovsxdq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXDQ, 0x25, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5557 | void vpmovsxdq(const YmmReg& dst, const Mem128& src) {AppendInstr(I_PMOVSXDQ, 0x25, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5558 | ✗ | void vpmovzxbw(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBW, 0x30, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | |
| 5559 | void vpmovzxbw(const YmmReg& dst, const Mem128& src) {AppendInstr(I_PMOVZXBW, 0x30, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5560 | ✗ | void vpmovzxbd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBD, 0x31, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | |
| 5561 | void vpmovzxbd(const YmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXBD, 0x31, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5562 | void vpmovzxbq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBQ, 0x32, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5563 | void vpmovzxbq(const YmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVZXBQ, 0x32, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5564 | ✗ | void vpmovzxwd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXWD, 0x33, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | |
| 5565 | void vpmovzxwd(const YmmReg& dst, const Mem128& src) {AppendInstr(I_PMOVZXWD, 0x33, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5566 | void vpmovzxwq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXWQ, 0x34, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5567 | void vpmovzxwq(const YmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXWQ, 0x34, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5568 | void vpmovzxdq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXDQ, 0x35, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5569 | void vpmovzxdq(const YmmReg& dst, const Mem128& src) {AppendInstr(I_PMOVZXDQ, 0x35, E_VEX_256_66_0F38_WIG, W(dst), R(src));} | ||
| 5570 | void vpmulhuw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULHUW, 0xE4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5571 | void vpmulhuw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULHUW, 0xE4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5572 | void vpmulhrsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULHRSW, 0x0B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5573 | void vpmulhrsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULHRSW, 0x0B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5574 | void vpmulhw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULHW, 0xE5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5575 | void vpmulhw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULHW, 0xE5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5576 | void vpmullw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULLW, 0xD5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5577 | void vpmullw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULLW, 0xD5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5578 | void vpmulld(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULLD, 0x40, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5579 | void vpmulld(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULLD, 0x40, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5580 | void vpmuludq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULUDQ, 0xF4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5581 | void vpmuludq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULUDQ, 0xF4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5582 | void vpmuldq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULDQ, 0x28, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5583 | void vpmuldq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULDQ, 0x28, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5584 | void vpor(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_POR, 0xEB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5585 | void vpor(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_POR, 0xEB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5586 | void vpsadbw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSADBW, 0xF6, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5587 | void vpsadbw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSADBW, 0xF6, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5588 | void vpshufb(const YmmReg& dst, const YmmReg& src, const YmmReg& order) {AppendInstr(I_PSHUFB, 0x00, E_VEX_256_66_0F38_WIG, W(dst), R(order), R(src));} | ||
| 5589 | void vpshufb(const YmmReg& dst, const YmmReg& src, const Mem256& order) {AppendInstr(I_PSHUFB, 0x00, E_VEX_256_66_0F38_WIG, W(dst), R(order), R(src));} | ||
| 5590 | void vpshufd(const YmmReg& dst, const YmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFD, 0x70, E_VEX_256_66_0F_WIG, W(dst), R(src), order);} | ||
| 5591 | void vpshufd(const YmmReg& dst, const Mem256& src, const Imm8& order) {AppendInstr(I_PSHUFD, 0x70, E_VEX_256_66_0F_WIG, W(dst), R(src), order);} | ||
| 5592 | void vpshufhw(const YmmReg& dst, const YmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFHW, 0x70, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src), order);} | ||
| 5593 | void vpshufhw(const YmmReg& dst, const Mem256& src, const Imm8& order) {AppendInstr(I_PSHUFHW, 0x70, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src), order);} | ||
| 5594 | void vpshuflw(const YmmReg& dst, const YmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFLW, 0x70, E_VEX_256 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src), order);} | ||
| 5595 | void vpshuflw(const YmmReg& dst, const Mem256& src, const Imm8& order) {AppendInstr(I_PSHUFLW, 0x70, E_VEX_256 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src), order);} | ||
| 5596 | void vpsignb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSIGNB, 0x08, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5597 | void vpsignb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSIGNB, 0x08, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5598 | void vpsignw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSIGNW, 0x09, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5599 | void vpsignw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSIGNW, 0x09, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5600 | void vpsignd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSIGND, 0x0A, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5601 | void vpsignd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSIGND, 0x0A, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));} | ||
| 5602 | void vpsllw(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSLLW, 0xF1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5603 | void vpsllw(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSLLW, 0xF1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5604 | void vpsllw(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSLLW, 0x71, E_VEX_256_66_0F_WIG, Imm8(6), R(src), W(dst), count);} | ||
| 5605 | void vpslld(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSLLD, 0xF2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5606 | void vpslld(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSLLD, 0xF2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5607 | ✗ | void vpslld(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSLLD, 0x72, E_VEX_256_66_0F_WIG, Imm8(6), R(src), W(dst), count);} | |
| 5608 | void vpsllq(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSLLQ, 0xF3, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5609 | void vpsllq(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSLLQ, 0xF3, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5610 | void vpsllq(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSLLQ, 0x73, E_VEX_256_66_0F_WIG, Imm8(6), R(src), W(dst), count);} | ||
| 5611 | void vpslldq(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSLLDQ, 0x73, E_VEX_256_66_0F_WIG, Imm8(7), R(src), W(dst), count);} | ||
| 5612 | void vpsllvd(const XmmReg& dst, const XmmReg& count, const XmmReg& src) {AppendInstr(I_VPSLLVD, 0x47, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));} | ||
| 5613 | void vpsllvd(const XmmReg& dst, const XmmReg& count, const Mem128& src) {AppendInstr(I_VPSLLVD, 0x47, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));} | ||
| 5614 | void vpsllvd(const YmmReg& dst, const YmmReg& count, const YmmReg& src) {AppendInstr(I_VPSLLVD, 0x47, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));} | ||
| 5615 | void vpsllvd(const YmmReg& dst, const YmmReg& count, const Mem256& src) {AppendInstr(I_VPSLLVD, 0x47, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));} | ||
| 5616 | void vpsllvq(const XmmReg& dst, const XmmReg& count, const XmmReg& src) {AppendInstr(I_VPSLLVQ, 0x47, E_VEX_128_66_0F38_W1, W(dst), R(src), R(count));} | ||
| 5617 | void vpsllvq(const XmmReg& dst, const XmmReg& count, const Mem128& src) {AppendInstr(I_VPSLLVQ, 0x47, E_VEX_128_66_0F38_W1, W(dst), R(src), R(count));} | ||
| 5618 | void vpsllvq(const YmmReg& dst, const YmmReg& count, const YmmReg& src) {AppendInstr(I_VPSLLVQ, 0x47, E_VEX_256_66_0F38_W1, W(dst), R(src), R(count));} | ||
| 5619 | void vpsllvq(const YmmReg& dst, const YmmReg& count, const Mem256& src) {AppendInstr(I_VPSLLVQ, 0x47, E_VEX_256_66_0F38_W1, W(dst), R(src), R(count));} | ||
| 5620 | void vpsraw(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSRAW, 0xE1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5621 | void vpsraw(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSRAW, 0xE1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5622 | void vpsraw(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSRAW, 0x71, E_VEX_256_66_0F_WIG, Imm8(4), R(src), W(dst), count);} | ||
| 5623 | void vpsrad(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSRAD, 0xE2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5624 | void vpsrad(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSRAD, 0xE2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5625 | void vpsrad(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSRAD, 0x72, E_VEX_256_66_0F_WIG, Imm8(4), R(src), W(dst), count);} | ||
| 5626 | void vpsravd(const XmmReg& dst, const XmmReg& count, const XmmReg& src) {AppendInstr(I_VPSRAVD, 0x46, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));} | ||
| 5627 | void vpsravd(const XmmReg& dst, const XmmReg& count, const Mem128& src) {AppendInstr(I_VPSRAVD, 0x46, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));} | ||
| 5628 | void vpsravd(const YmmReg& dst, const YmmReg& count, const YmmReg& src) {AppendInstr(I_VPSRAVD, 0x46, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));} | ||
| 5629 | void vpsravd(const YmmReg& dst, const YmmReg& count, const Mem256& src) {AppendInstr(I_VPSRAVD, 0x46, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));} | ||
| 5630 | void vpsrlw(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSRLW, 0xD1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5631 | void vpsrlw(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSRLW, 0xD1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5632 | void vpsrlw(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSRLW, 0x71, E_VEX_256_66_0F_WIG, Imm8(2), R(src), W(dst), count);} | ||
| 5633 | void vpsrld(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSRLD, 0xD2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5634 | void vpsrld(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSRLD, 0xD2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5635 | ✗ | void vpsrld(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSRLD, 0x72, E_VEX_256_66_0F_WIG, Imm8(2), R(src), W(dst), count);} | |
| 5636 | void vpsrlq(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSRLQ, 0xD3, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5637 | void vpsrlq(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSRLQ, 0xD3, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));} | ||
| 5638 | void vpsrlq(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSRLQ, 0x73, E_VEX_256_66_0F_WIG, Imm8(2), R(src), W(dst), count);} | ||
| 5639 | void vpsrldq(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSRLDQ, 0x73, E_VEX_256_66_0F_WIG, Imm8(3), R(src), W(dst), count);} | ||
| 5640 | void vpsrlvd(const XmmReg& dst, const XmmReg& count, const XmmReg& src) {AppendInstr(I_VPSRLVD, 0x45, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));} | ||
| 5641 | void vpsrlvd(const XmmReg& dst, const XmmReg& count, const Mem128& src) {AppendInstr(I_VPSRLVD, 0x45, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));} | ||
| 5642 | void vpsrlvd(const YmmReg& dst, const YmmReg& count, const YmmReg& src) {AppendInstr(I_VPSRLVD, 0x45, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));} | ||
| 5643 | void vpsrlvd(const YmmReg& dst, const YmmReg& count, const Mem256& src) {AppendInstr(I_VPSRLVD, 0x45, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));} | ||
| 5644 | void vpsrlvq(const XmmReg& dst, const XmmReg& count, const XmmReg& src) {AppendInstr(I_VPSRLVQ, 0x45, E_VEX_128_66_0F38_W1, W(dst), R(src), R(count));} | ||
| 5645 | void vpsrlvq(const XmmReg& dst, const XmmReg& count, const Mem128& src) {AppendInstr(I_VPSRLVQ, 0x45, E_VEX_128_66_0F38_W1, W(dst), R(src), R(count));} | ||
| 5646 | void vpsrlvq(const YmmReg& dst, const YmmReg& count, const YmmReg& src) {AppendInstr(I_VPSRLVQ, 0x45, E_VEX_256_66_0F38_W1, W(dst), R(src), R(count));} | ||
| 5647 | void vpsrlvq(const YmmReg& dst, const YmmReg& count, const Mem256& src) {AppendInstr(I_VPSRLVQ, 0x45, E_VEX_256_66_0F38_W1, W(dst), R(src), R(count));} | ||
| 5648 | void vpsubb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBB, 0xF8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5649 | void vpsubb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBB, 0xF8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5650 | void vpsubw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBW, 0xF9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5651 | void vpsubw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBW, 0xF9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5652 | void vpsubd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBD, 0xFA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5653 | ✗ | void vpsubd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBD, 0xFA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | |
| 5654 | void vpsubq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBQ, 0xFB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5655 | void vpsubq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBQ, 0xFB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5656 | void vpsubsb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBSB, 0xE8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5657 | void vpsubsb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBSB, 0xE8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5658 | void vpsubsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBSW, 0xE9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5659 | void vpsubsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBSW, 0xE9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5660 | void vpsubusb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBUSB, 0xD8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5661 | void vpsubusb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBUSB, 0xD8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5662 | void vpsubusw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBUSW, 0xD9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5663 | void vpsubusw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBUSW, 0xD9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5664 | void vpunpckhbw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKHBW, 0x68, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5665 | void vpunpckhbw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKHBW, 0x68, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5666 | void vpunpckhwd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKHWD, 0x69, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5667 | void vpunpckhwd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKHWD, 0x69, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5668 | void vpunpckhdq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKHDQ, 0x6A, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5669 | void vpunpckhdq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKHDQ, 0x6A, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5670 | void vpunpckhqdq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKHQDQ, 0x6D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5671 | void vpunpckhqdq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKHQDQ, 0x6D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5672 | void vpunpcklbw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKLBW, 0x60, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5673 | void vpunpcklbw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKLBW, 0x60, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5674 | void vpunpcklwd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKLWD, 0x61, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5675 | void vpunpcklwd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKLWD, 0x61, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5676 | void vpunpckldq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKLDQ, 0x62, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5677 | void vpunpckldq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKLDQ, 0x62, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5678 | void vpunpcklqdq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKLQDQ, 0x6C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5679 | void vpunpcklqdq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKLQDQ, 0x6C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5680 | ✗ | void vpxor(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PXOR, 0xEF, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | |
| 5681 | void vpxor(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PXOR, 0xEF, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));} | ||
| 5682 | |||
| 5683 | |||
| 5684 | struct ControlState | ||
| 5685 | { | ||
| 5686 | size_t label1; | ||
| 5687 | size_t label2; | ||
| 5688 | }; | ||
| 5689 | ControlState ctrl_state_; | ||
| 5690 | std::deque<ControlState> ctrl_state_stack_; | ||
| 5691 | |||
| 5692 | // Repeat, Until | ||
| 5693 | void Repeat() | ||
| 5694 | { | ||
| 5695 | ctrl_state_stack_.push_back(ctrl_state_); | ||
| 5696 | ctrl_state_.label1 = NewLabelID(""); // begin | ||
| 5697 | ctrl_state_.label2 = 0; | ||
| 5698 | |||
| 5699 | L(ctrl_state_.label1); | ||
| 5700 | } | ||
| 5701 | template<class Ty> | ||
| 5702 | void Until(const Ty& expr) | ||
| 5703 | { | ||
| 5704 | size_t label = NewLabelID(""); | ||
| 5705 | expr(*this, ctrl_state_.label1, label); | ||
| 5706 | L(label); | ||
| 5707 | |||
| 5708 | ctrl_state_ = *ctrl_state_stack_.rbegin(); | ||
| 5709 | ctrl_state_stack_.pop_back(); | ||
| 5710 | } | ||
| 5711 | |||
| 5712 | // While, EndW | ||
| 5713 | template<class Ty> | ||
| 5714 | void While(const Ty& expr) | ||
| 5715 | { | ||
| 5716 | ctrl_state_stack_.push_back(ctrl_state_); | ||
| 5717 | ctrl_state_.label1 = NewLabelID(""); // begin | ||
| 5718 | ctrl_state_.label2 = NewLabelID(""); // end | ||
| 5719 | |||
| 5720 | size_t label = NewLabelID(""); | ||
| 5721 | L(ctrl_state_.label1); | ||
| 5722 | expr(*this, label, ctrl_state_.label2); | ||
| 5723 | L(label); | ||
| 5724 | } | ||
| 5725 | void EndW() | ||
| 5726 | { | ||
| 5727 | AppendJmp(ctrl_state_.label1); | ||
| 5728 | L(ctrl_state_.label2); | ||
| 5729 | |||
| 5730 | ctrl_state_ = *ctrl_state_stack_.rbegin(); | ||
| 5731 | ctrl_state_stack_.pop_back(); | ||
| 5732 | } | ||
| 5733 | |||
| 5734 | // If, ElseIf, Else, EndIf | ||
| 5735 | template<class Ty> | ||
| 5736 | void If(const Ty& expr) | ||
| 5737 | { | ||
| 5738 | ctrl_state_stack_.push_back(ctrl_state_); | ||
| 5739 | ctrl_state_.label1 = NewLabelID(""); // else | ||
| 5740 | ctrl_state_.label2 = NewLabelID(""); // end | ||
| 5741 | |||
| 5742 | size_t label = NewLabelID(""); | ||
| 5743 | expr(*this, label, ctrl_state_.label1); | ||
| 5744 | L(label); | ||
| 5745 | } | ||
| 5746 | template<class Ty> | ||
| 5747 | void ElseIf(const Ty& expr) | ||
| 5748 | { | ||
| 5749 | Else(); | ||
| 5750 | |||
| 5751 | size_t label = NewLabelID(""); | ||
| 5752 | expr(*this, label, ctrl_state_.label1); | ||
| 5753 | L(label); | ||
| 5754 | } | ||
| 5755 | void Else() | ||
| 5756 | { | ||
| 5757 | AppendJmp(ctrl_state_.label2); | ||
| 5758 | L(ctrl_state_.label1); | ||
| 5759 | ctrl_state_.label1 = NewLabelID(""); | ||
| 5760 | } | ||
| 5761 | void EndIf() | ||
| 5762 | { | ||
| 5763 | L(ctrl_state_.label1); | ||
| 5764 | L(ctrl_state_.label2); | ||
| 5765 | |||
| 5766 | ctrl_state_ = *ctrl_state_stack_.rbegin(); | ||
| 5767 | ctrl_state_stack_.pop_back(); | ||
| 5768 | } | ||
| 5769 | }; | ||
| 5770 | |||
| 5771 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::al = Reg8(AL); | ||
| 5772 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::cl = Reg8(CL); | ||
| 5773 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::dl = Reg8(DL); | ||
| 5774 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::bl = Reg8(BL); | ||
| 5775 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::ah = Reg8(AH); | ||
| 5776 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::ch = Reg8(CH); | ||
| 5777 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::dh = Reg8(DH); | ||
| 5778 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::bh = Reg8(BH); | ||
| 5779 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::ax = Reg16(AX); | ||
| 5780 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::cx = Reg16(CX); | ||
| 5781 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::dx = Reg16(DX); | ||
| 5782 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::bx = Reg16(BX); | ||
| 5783 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::sp = Reg16(SP); | ||
| 5784 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::bp = Reg16(BP); | ||
| 5785 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::si = Reg16(SI); | ||
| 5786 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::di = Reg16(DI); | ||
| 5787 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::eax = Reg32(EAX); | ||
| 5788 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::ecx = Reg32(ECX); | ||
| 5789 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::edx = Reg32(EDX); | ||
| 5790 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::ebx = Reg32(EBX); | ||
| 5791 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::esp = Reg32(ESP); | ||
| 5792 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::ebp = Reg32(EBP); | ||
| 5793 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::esi = Reg32(ESI); | ||
| 5794 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::edi = Reg32(EDI); | ||
| 5795 | FpuReg_st0 JITASM_ATTRIBUTE_WEAK Frontend::st0; | ||
| 5796 | FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st1 = FpuReg(ST1); | ||
| 5797 | FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st2 = FpuReg(ST2); | ||
| 5798 | FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st3 = FpuReg(ST3); | ||
| 5799 | FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st4 = FpuReg(ST4); | ||
| 5800 | FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st5 = FpuReg(ST5); | ||
| 5801 | FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st6 = FpuReg(ST6); | ||
| 5802 | FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st7 = FpuReg(ST7); | ||
| 5803 | MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm0 = MmxReg(MM0); | ||
| 5804 | MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm1 = MmxReg(MM1); | ||
| 5805 | MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm2 = MmxReg(MM2); | ||
| 5806 | MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm3 = MmxReg(MM3); | ||
| 5807 | MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm4 = MmxReg(MM4); | ||
| 5808 | MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm5 = MmxReg(MM5); | ||
| 5809 | MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm6 = MmxReg(MM6); | ||
| 5810 | MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm7 = MmxReg(MM7); | ||
| 5811 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm0 = XmmReg(XMM0); | ||
| 5812 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm1 = XmmReg(XMM1); | ||
| 5813 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm2 = XmmReg(XMM2); | ||
| 5814 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm3 = XmmReg(XMM3); | ||
| 5815 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm4 = XmmReg(XMM4); | ||
| 5816 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm5 = XmmReg(XMM5); | ||
| 5817 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm6 = XmmReg(XMM6); | ||
| 5818 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm7 = XmmReg(XMM7); | ||
| 5819 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm0 = YmmReg(YMM0); | ||
| 5820 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm1 = YmmReg(YMM1); | ||
| 5821 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm2 = YmmReg(YMM2); | ||
| 5822 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm3 = YmmReg(YMM3); | ||
| 5823 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm4 = YmmReg(YMM4); | ||
| 5824 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm5 = YmmReg(YMM5); | ||
| 5825 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm6 = YmmReg(YMM6); | ||
| 5826 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm7 = YmmReg(YMM7); | ||
| 5827 | #ifdef JITASM64 | ||
| 5828 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r8b = Reg8(R8B); | ||
| 5829 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r9b = Reg8(R9B); | ||
| 5830 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r10b = Reg8(R10B); | ||
| 5831 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r11b = Reg8(R11B); | ||
| 5832 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r12b = Reg8(R12B); | ||
| 5833 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r13b = Reg8(R13B); | ||
| 5834 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r14b = Reg8(R14B); | ||
| 5835 | Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r15b = Reg8(R15B); | ||
| 5836 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r8w = Reg16(R8W); | ||
| 5837 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r9w = Reg16(R9W); | ||
| 5838 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r10w = Reg16(R10W); | ||
| 5839 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r11w = Reg16(R11W); | ||
| 5840 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r12w = Reg16(R12W); | ||
| 5841 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r13w = Reg16(R13W); | ||
| 5842 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r14w = Reg16(R14W); | ||
| 5843 | Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r15w = Reg16(R15W); | ||
| 5844 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r8d = Reg32(R8D); | ||
| 5845 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r9d = Reg32(R9D); | ||
| 5846 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r10d = Reg32(R10D); | ||
| 5847 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r11d = Reg32(R11D); | ||
| 5848 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r12d = Reg32(R12D); | ||
| 5849 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r13d = Reg32(R13D); | ||
| 5850 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r14d = Reg32(R14D); | ||
| 5851 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r15d = Reg32(R15D); | ||
| 5852 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rax = Reg64(RAX); | ||
| 5853 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rcx = Reg64(RCX); | ||
| 5854 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rdx = Reg64(RDX); | ||
| 5855 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rbx = Reg64(RBX); | ||
| 5856 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rsp = Reg64(RSP); | ||
| 5857 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rbp = Reg64(RBP); | ||
| 5858 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rsi = Reg64(RSI); | ||
| 5859 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rdi = Reg64(RDI); | ||
| 5860 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r8 = Reg64(R8); | ||
| 5861 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r9 = Reg64(R9); | ||
| 5862 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r10 = Reg64(R10); | ||
| 5863 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r11 = Reg64(R11); | ||
| 5864 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r12 = Reg64(R12); | ||
| 5865 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r13 = Reg64(R13); | ||
| 5866 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r14 = Reg64(R14); | ||
| 5867 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r15 = Reg64(R15); | ||
| 5868 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm8 = XmmReg(XMM8); | ||
| 5869 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm9 = XmmReg(XMM9); | ||
| 5870 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm10 = XmmReg(XMM10); | ||
| 5871 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm11 = XmmReg(XMM11); | ||
| 5872 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm12 = XmmReg(XMM12); | ||
| 5873 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm13 = XmmReg(XMM13); | ||
| 5874 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm14 = XmmReg(XMM14); | ||
| 5875 | XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm15 = XmmReg(XMM15); | ||
| 5876 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm8 = YmmReg(YMM8); | ||
| 5877 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm9 = YmmReg(YMM9); | ||
| 5878 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm10 = YmmReg(YMM10); | ||
| 5879 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm11 = YmmReg(YMM11); | ||
| 5880 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm12 = YmmReg(YMM12); | ||
| 5881 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm13 = YmmReg(YMM13); | ||
| 5882 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm14 = YmmReg(YMM14); | ||
| 5883 | YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm15 = YmmReg(YMM15); | ||
| 5884 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zax = Reg64(RAX); | ||
| 5885 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zcx = Reg64(RCX); | ||
| 5886 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zdx = Reg64(RDX); | ||
| 5887 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zbx = Reg64(RBX); | ||
| 5888 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zsp = Reg64(RSP); | ||
| 5889 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zbp = Reg64(RBP); | ||
| 5890 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zsi = Reg64(RSI); | ||
| 5891 | Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zdi = Reg64(RDI); | ||
| 5892 | #else | ||
| 5893 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zax = Reg32(EAX); | ||
| 5894 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zcx = Reg32(ECX); | ||
| 5895 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zdx = Reg32(EDX); | ||
| 5896 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zbx = Reg32(EBX); | ||
| 5897 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zsp = Reg32(ESP); | ||
| 5898 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zbp = Reg32(EBP); | ||
| 5899 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zsi = Reg32(ESI); | ||
| 5900 | Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zdi = Reg32(EDI); | ||
| 5901 | #endif | ||
| 5902 | |||
| 5903 | |||
| 5904 | namespace compiler | ||
| 5905 | { | ||
| 5906 | struct BitVector : std::vector<uint32> | ||
| 5907 | { | ||
| 5908 | ✗ | size_t size_bit() const { return size() * 32; } | |
| 5909 | |||
| 5910 | ✗ | bool get_bit(size_t idx) const | |
| 5911 | { | ||
| 5912 | ✗ | const size_t i = idx / 32; | |
| 5913 | ✗ | return i < size() && (at(i) & (1 << (idx % 32))) != 0; | |
| 5914 | } | ||
| 5915 | |||
| 5916 | ✗ | void set_bit(size_t idx, bool b) | |
| 5917 | { | ||
| 5918 | ✗ | const size_t i = idx / 32; | |
| 5919 | ✗ | const uint32 mask = (1 << (idx % 32)); | |
| 5920 | ✗ | if (i >= size()) resize(i + 1); | |
| 5921 | ✗ | if (b) at(i) |= mask; | |
| 5922 | ✗ | else at(i) &= ~mask; | |
| 5923 | ✗ | } | |
| 5924 | |||
| 5925 | ✗ | bool is_equal(const BitVector& rhs) const | |
| 5926 | { | ||
| 5927 | ✗ | const size_t min_size = size() < rhs.size() ? size() : rhs.size(); | |
| 5928 | ✗ | for (size_t i = 0; i < min_size; ++i) { | |
| 5929 | ✗ | if (at(i) != rhs[i]) return false; | |
| 5930 | } | ||
| 5931 | |||
| 5932 | ✗ | const BitVector& larger = size() < rhs.size() ? rhs : *this; | |
| 5933 | ✗ | for (size_t i = min_size; i < larger.size(); ++i) { | |
| 5934 | ✗ | if (larger[i] != 0) return false; | |
| 5935 | } | ||
| 5936 | |||
| 5937 | ✗ | return true; | |
| 5938 | } | ||
| 5939 | |||
| 5940 | ✗ | size_t count_bit() const | |
| 5941 | { | ||
| 5942 | ✗ | size_t count = 0; | |
| 5943 | ✗ | for (size_t i = 0; i < size(); ++i) { | |
| 5944 | ✗ | count += detail::Count1Bits(at(i)); | |
| 5945 | } | ||
| 5946 | ✗ | return count; | |
| 5947 | } | ||
| 5948 | |||
| 5949 | ✗ | void get_bit_indexes(std::vector<size_t>& indexes) const | |
| 5950 | { | ||
| 5951 | ✗ | indexes.clear(); | |
| 5952 | ✗ | for (size_t i = 0; i < size(); ++i) { | |
| 5953 | ✗ | uint32 m = at(i); | |
| 5954 | ✗ | while (m != 0) { | |
| 5955 | ✗ | uint32 index = detail::bit_scan_forward(m); | |
| 5956 | ✗ | indexes.push_back(static_cast<uint32>(i * 32) + index); | |
| 5957 | ✗ | m &= ~(1 << index); | |
| 5958 | } | ||
| 5959 | } | ||
| 5960 | ✗ | } | |
| 5961 | |||
| 5962 | template<class Fn> | ||
| 5963 | ✗ | void query_bit_indexes(Fn& fn) const | |
| 5964 | { | ||
| 5965 | ✗ | for (size_t i = 0; i < size(); ++i) { | |
| 5966 | ✗ | uint32 m = at(i); | |
| 5967 | ✗ | while (m != 0) { | |
| 5968 | ✗ | uint32 index = detail::bit_scan_forward(m); | |
| 5969 | ✗ | fn(i * 32 + index); | |
| 5970 | ✗ | m &= ~(1 << index); | |
| 5971 | } | ||
| 5972 | } | ||
| 5973 | ✗ | } | |
| 5974 | |||
| 5975 | ✗ | void set_union(const BitVector& rhs) | |
| 5976 | { | ||
| 5977 | ✗ | if (size() < rhs.size()) resize(rhs.size()); | |
| 5978 | ✗ | for (size_t i = 0; i < rhs.size(); ++i) { | |
| 5979 | ✗ | at(i) |= rhs[i]; | |
| 5980 | } | ||
| 5981 | ✗ | } | |
| 5982 | |||
| 5983 | ✗ | void set_subtract(const BitVector& rhs) | |
| 5984 | { | ||
| 5985 | ✗ | const size_t min_size = size() < rhs.size() ? size() : rhs.size(); | |
| 5986 | ✗ | for (size_t i = 0; i < min_size; ++i) { | |
| 5987 | ✗ | at(i) &= ~rhs[i]; | |
| 5988 | } | ||
| 5989 | ✗ | } | |
| 5990 | }; | ||
| 5991 | |||
| 5992 | template<class T, size_t N> | ||
| 5993 | class FixedArray | ||
| 5994 | { | ||
| 5995 | private: | ||
| 5996 | T data_[N]; | ||
| 5997 | size_t size_; | ||
| 5998 | |||
| 5999 | public: | ||
| 6000 | ✗ | FixedArray() : size_(0) {} | |
| 6001 | ✗ | bool empty() const {return size_ == 0;} | |
| 6002 | ✗ | size_t size() const {return size_;} | |
| 6003 | void clear() {size_ = 0;} | ||
| 6004 | |||
| 6005 | ✗ | void push_back(const T& v) {data_[size_++] = v;} | |
| 6006 | ✗ | void pop_back() {--size_;} | |
| 6007 | |||
| 6008 | ✗ | const T& operator[](size_t i) const {return data_[i];} | |
| 6009 | ✗ | T& operator[](size_t i) {return data_[i];} | |
| 6010 | |||
| 6011 | const T& back() const {return data_[size_ - 1];} | ||
| 6012 | ✗ | T& back() {return data_[size_ - 1];} | |
| 6013 | }; | ||
| 6014 | |||
| 6015 | /// Register family | ||
| 6016 | ✗ | inline size_t GetRegFamily(RegType type) | |
| 6017 | { | ||
| 6018 | ✗ | switch (type) { | |
| 6019 | ✗ | case R_TYPE_GP: return 0; | |
| 6020 | ✗ | case R_TYPE_MMX: return 1; | |
| 6021 | ✗ | case R_TYPE_XMM: return 2; | |
| 6022 | ✗ | case R_TYPE_YMM: return 2; | |
| 6023 | ✗ | case R_TYPE_SYMBOLIC_GP: return 0; | |
| 6024 | ✗ | case R_TYPE_SYMBOLIC_MMX: return 1; | |
| 6025 | ✗ | case R_TYPE_SYMBOLIC_XMM: return 2; | |
| 6026 | ✗ | case R_TYPE_SYMBOLIC_YMM: return 2; | |
| 6027 | ✗ | case R_TYPE_FPU: | |
| 6028 | default: | ||
| 6029 | ✗ | JITASM_ASSERT(0); | |
| 6030 | return 0x7FFFFFFF; | ||
| 6031 | } | ||
| 6032 | } | ||
| 6033 | |||
| 6034 | inline std::string GetRegName(RegType type, size_t reg_idx) | ||
| 6035 | { | ||
| 6036 | #ifdef JITASM64 | ||
| 6037 | const static std::string s_gp_reg_name[] = {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}; | ||
| 6038 | #else | ||
| 6039 | const static std::string s_gp_reg_name[] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"}; | ||
| 6040 | #endif | ||
| 6041 | std::string name; | ||
| 6042 | if (type == R_TYPE_GP) {return s_gp_reg_name[reg_idx];} | ||
| 6043 | else if (type == R_TYPE_MMX) {name.assign("mm");} | ||
| 6044 | else if (type == R_TYPE_XMM) {name.assign("xmm");} | ||
| 6045 | else if (type == R_TYPE_YMM) {name.assign("ymm");} | ||
| 6046 | else if (type == R_TYPE_SYMBOLIC_GP) {name.assign("gpsym"); reg_idx -= NUM_OF_PHYSICAL_REG;} | ||
| 6047 | else if (type == R_TYPE_SYMBOLIC_MMX) {name.assign("mmsym"); reg_idx -= NUM_OF_PHYSICAL_REG;} | ||
| 6048 | else if (type == R_TYPE_SYMBOLIC_XMM) {name.assign("xmmsym"); reg_idx -= NUM_OF_PHYSICAL_REG;} | ||
| 6049 | else if (type == R_TYPE_SYMBOLIC_YMM) {name.assign("ymmsym"); reg_idx -= NUM_OF_PHYSICAL_REG;} | ||
| 6050 | detail::append_num(name, reg_idx); | ||
| 6051 | return name; | ||
| 6052 | } | ||
| 6053 | |||
| 6054 | /// Variable attribute | ||
| 6055 | struct VarAttribute | ||
| 6056 | { | ||
| 6057 | unsigned size : 7; // OpdSize | ||
| 6058 | unsigned spill : 1; // bool | ||
| 6059 | Addr stack_slot; | ||
| 6060 | ✗ | VarAttribute() : size(0), spill(0/*false*/), stack_slot(RegID::Invalid(), 0) {} | |
| 6061 | }; | ||
| 6062 | |||
| 6063 | /// Variable manager | ||
| 6064 | class VariableManager | ||
| 6065 | { | ||
| 6066 | private: | ||
| 6067 | std::vector<VarAttribute> attributes_[3]; // GP, MMX, XMM/YMM | ||
| 6068 | |||
| 6069 | public: | ||
| 6070 | ✗ | std::vector<VarAttribute>& GetAttributes(size_t reg_family) {return attributes_[reg_family];} | |
| 6071 | ✗ | const std::vector<VarAttribute>& GetAttributes(size_t reg_family) const {return attributes_[reg_family];} | |
| 6072 | |||
| 6073 | /// Get variable size | ||
| 6074 | ✗ | OpdSize GetVarSize(size_t reg_family, int var) const | |
| 6075 | { | ||
| 6076 | ✗ | return static_cast<OpdSize>(attributes_[reg_family][var].size); | |
| 6077 | } | ||
| 6078 | |||
| 6079 | /// Update variable size | ||
| 6080 | ✗ | void UpdateVarSize(RegType reg_type, int var, OpdSize size) | |
| 6081 | { | ||
| 6082 | ✗ | const size_t reg_family = GetRegFamily(reg_type); | |
| 6083 | ✗ | if (static_cast<size_t>(var) >= attributes_[reg_family].size()) { | |
| 6084 | ✗ | attributes_[reg_family].resize(var + 1); | |
| 6085 | } | ||
| 6086 | |||
| 6087 | ✗ | if (attributes_[reg_family][var].size < static_cast<unsigned>(size)) { | |
| 6088 | ✗ | attributes_[reg_family][var].size = static_cast<unsigned>(size); | |
| 6089 | } | ||
| 6090 | ✗ | } | |
| 6091 | |||
| 6092 | /// Get stack slot for spill register | ||
| 6093 | ✗ | Addr GetSpillSlot(size_t reg_family, int var) const | |
| 6094 | { | ||
| 6095 | ✗ | return attributes_[reg_family][var].stack_slot; | |
| 6096 | } | ||
| 6097 | |||
| 6098 | /// Set stack slot for spill register | ||
| 6099 | ✗ | void SetSpillSlot(RegType reg_type, int var, const Addr& stack_slot) | |
| 6100 | { | ||
| 6101 | ✗ | const size_t reg_family = GetRegFamily(reg_type); | |
| 6102 | ✗ | if (static_cast<size_t>(var) >= attributes_[reg_family].size()) { | |
| 6103 | ✗ | attributes_[reg_family].resize(var + 1); | |
| 6104 | } | ||
| 6105 | ✗ | attributes_[reg_family][var].stack_slot = stack_slot; | |
| 6106 | ✗ | } | |
| 6107 | |||
| 6108 | /// Allocate stack of spill slots | ||
| 6109 | ✗ | void AllocSpillSlots(detail::StackManager& stack_manager) | |
| 6110 | { | ||
| 6111 | // YMM | ||
| 6112 | ✗ | for (size_t i = 0; i < attributes_[2].size(); ++i) { | |
| 6113 | ✗ | if (attributes_[2][i].spill && attributes_[2][i].size == O_SIZE_256 && attributes_[2][i].stack_slot.reg_.IsInvalid()) { | |
| 6114 | ✗ | attributes_[2][i].stack_slot = stack_manager.Alloc(256 / 8, 32); // 32 bytes aligned! 16->32 171108 | |
| 6115 | } | ||
| 6116 | } | ||
| 6117 | |||
| 6118 | // XMM | ||
| 6119 | ✗ | for (size_t i = 0; i < attributes_[2].size(); ++i) { | |
| 6120 | ✗ | if (attributes_[2][i].spill && attributes_[2][i].size == O_SIZE_128 && attributes_[2][i].stack_slot.reg_.IsInvalid()) { | |
| 6121 | ✗ | attributes_[2][i].stack_slot = stack_manager.Alloc(128 / 8, 16); | |
| 6122 | } | ||
| 6123 | } | ||
| 6124 | |||
| 6125 | // MMX | ||
| 6126 | ✗ | for (size_t i = 0; i < attributes_[1].size(); ++i) { | |
| 6127 | ✗ | if (attributes_[1][i].spill && attributes_[1][i].stack_slot.reg_.IsInvalid()) { | |
| 6128 | ✗ | attributes_[1][i].stack_slot = stack_manager.Alloc(64 / 8, 8); | |
| 6129 | } | ||
| 6130 | } | ||
| 6131 | |||
| 6132 | // GP | ||
| 6133 | ✗ | for (size_t i = 0; i < attributes_[0].size(); ++i) { | |
| 6134 | ✗ | if (attributes_[0][i].spill && attributes_[0][i].stack_slot.reg_.IsInvalid()) { | |
| 6135 | #ifdef JITASM64 | ||
| 6136 | ✗ | attributes_[0][i].stack_slot = stack_manager.Alloc(64 / 8, 8); | |
| 6137 | #else | ||
| 6138 | attributes_[0][i].stack_slot = stack_manager.Alloc(32 / 8, 4); | ||
| 6139 | #endif | ||
| 6140 | } | ||
| 6141 | } | ||
| 6142 | ✗ | } | |
| 6143 | }; | ||
| 6144 | |||
| 6145 | /// Register use point | ||
| 6146 | struct RegUsePoint | ||
| 6147 | { | ||
| 6148 | size_t instr_idx; ///< Instruction index offset from basic block start point | ||
| 6149 | OpdType type; ///< Operand type | ||
| 6150 | uint32 reg_assignable; ///< Register assignment constraint | ||
| 6151 | |||
| 6152 | ✗ | RegUsePoint(size_t idx, OpdType t, uint32 assignable) : instr_idx(idx), type(t), reg_assignable(assignable) {} | |
| 6153 | |||
| 6154 | ✗ | bool operator<(const RegUsePoint& rhs) const { | |
| 6155 | ✗ | if (instr_idx == rhs.instr_idx) { | |
| 6156 | // R < RW < W | ||
| 6157 | ✗ | const int lhs_type = (type & O_TYPE_READ ? -1 : 0) + (type & O_TYPE_WRITE ? 1 : 0); | |
| 6158 | ✗ | const int rhs_type = (rhs.type & O_TYPE_READ ? -1 : 0) + (rhs.type & O_TYPE_WRITE ? 1 : 0); | |
| 6159 | ✗ | return lhs_type < rhs_type; | |
| 6160 | } | ||
| 6161 | ✗ | return instr_idx < rhs.instr_idx; | |
| 6162 | } | ||
| 6163 | }; | ||
| 6164 | |||
| 6165 | /// Variable lifetime | ||
| 6166 | struct Lifetime | ||
| 6167 | { | ||
| 6168 | typedef detail::Range< std::vector<RegUsePoint> > RegUsePointRange; | ||
| 6169 | typedef detail::ConstRange< std::vector<RegUsePoint> > ConstRegUsePointRange; | ||
| 6170 | |||
| 6171 | struct Interval | ||
| 6172 | { | ||
| 6173 | size_t instr_idx_offset; ///< Instruction index offset from basic block start point | ||
| 6174 | BitVector liveness; ///< The set of live variables | ||
| 6175 | BitVector use; ///< The set of used variables in this interval | ||
| 6176 | BitVector spill; ///< The set of spilled variables | ||
| 6177 | std::vector<uint32> reg_assignables; ///< The constraints of register allocation | ||
| 6178 | std::vector<int> assignment_table; ///< Register assignment table | ||
| 6179 | |||
| 6180 | Interval(size_t instr_idx, const std::vector<uint32>& assignables) : instr_idx_offset(instr_idx), reg_assignables(assignables) {} | ||
| 6181 | ✗ | Interval(size_t instr_idx, const BitVector& l, const BitVector& s, const std::vector<uint32>& assignables) : instr_idx_offset(instr_idx), liveness(l), spill(s), reg_assignables(assignables) {} | |
| 6182 | |||
| 6183 | ✗ | void UpdateUse(size_t var, RegUsePointRange& range, const Interval *next_interval) | |
| 6184 | { | ||
| 6185 | // step range | ||
| 6186 | ✗ | while (!range.empty() && range.first->instr_idx < instr_idx_offset) {++range.first;} | |
| 6187 | |||
| 6188 | // check if variables used in this interval | ||
| 6189 | ✗ | const bool used = !range.empty() && (!next_interval || range.first->instr_idx < next_interval->instr_idx_offset); | |
| 6190 | ✗ | use.set_bit(var, used); | |
| 6191 | ✗ | } | |
| 6192 | |||
| 6193 | void Dump(bool dump_assigned_reg) const | ||
| 6194 | { | ||
| 6195 | std::vector<char> liveness_str; | ||
| 6196 | for (size_t v = 0; v < liveness.size_bit(); ++v) { | ||
| 6197 | if (liveness.get_bit(v)) { | ||
| 6198 | const bool used = use.get_bit(v); | ||
| 6199 | char c; | ||
| 6200 | if (spill.get_bit(v)) { | ||
| 6201 | c = used ? 'S' : 's'; | ||
| 6202 | } else if (dump_assigned_reg) { | ||
| 6203 | int reg = assignment_table[v]; | ||
| 6204 | c = static_cast<char>(reg < 0xA ? '0' + reg : 'A' + reg); | ||
| 6205 | } else { | ||
| 6206 | c = used ? 'R' : 'r'; | ||
| 6207 | } | ||
| 6208 | liveness_str.push_back(c); | ||
| 6209 | } else { | ||
| 6210 | liveness_str.push_back('.'); | ||
| 6211 | } | ||
| 6212 | } | ||
| 6213 | liveness_str.push_back('\0'); | ||
| 6214 | JITASM_TRACE("[%03d] %s\n", instr_idx_offset, &liveness_str[0]); | ||
| 6215 | } | ||
| 6216 | }; | ||
| 6217 | |||
| 6218 | // 0 ~ NUM_OF_PHYSICAL_REG-1 : Physical register | ||
| 6219 | // NUM_OF_PHYSICAL_REG ~ : Symbolic register | ||
| 6220 | std::vector< std::vector<RegUsePoint> > use_points; | ||
| 6221 | BitVector gen; ///< The set of variables used before any assignment | ||
| 6222 | BitVector kill; ///< The set of variables assigned a value before any use | ||
| 6223 | BitVector live_in; ///< The set of live variables at the start of this block | ||
| 6224 | BitVector live_out; ///< The set of live variables at the end of this block | ||
| 6225 | bool dirty_live_out; ///< The dirty flag of live_out | ||
| 6226 | std::vector<Interval> intervals; ///< Lifetime intervals | ||
| 6227 | |||
| 6228 | static const int SpillCost_Read = 2; | ||
| 6229 | static const int SpillCost_Write = 3; | ||
| 6230 | |||
| 6231 | ✗ | Lifetime() : use_points(NUM_OF_PHYSICAL_REG), dirty_live_out(true) {} | |
| 6232 | |||
| 6233 | /// Add register use point | ||
| 6234 | ✗ | void AddUsePoint(size_t instr_idx, const RegID& reg, OpdType opd_type, OpdSize opd_size, uint32 reg_assignable) | |
| 6235 | { | ||
| 6236 | ✗ | if (use_points.size() <= static_cast<size_t>(reg.id)) { | |
| 6237 | ✗ | use_points.resize(reg.id + 1); | |
| 6238 | } | ||
| 6239 | |||
| 6240 | // add read attribute when writing to 8/16bit register because it is partial write | ||
| 6241 | ✗ | if ((opd_type & O_TYPE_WRITE) && (opd_size == O_SIZE_8 || opd_size == O_SIZE_16)) { | |
| 6242 | ✗ | opd_type = static_cast<OpdType>(static_cast<int>(opd_type) | O_TYPE_READ); | |
| 6243 | } | ||
| 6244 | |||
| 6245 | ✗ | RegUsePoint use_point(instr_idx, opd_type, reg_assignable); | |
| 6246 | ✗ | std::vector<RegUsePoint>::reverse_iterator it = use_points[reg.id].rbegin(); | |
| 6247 | ✗ | while (it != use_points[reg.id].rend() && use_point < *it) {++it;} | |
| 6248 | ✗ | use_points[reg.id].insert(it.base(), use_point); | |
| 6249 | ✗ | } | |
| 6250 | |||
| 6251 | ✗ | void GetSpillCost(int freq, std::vector<int>& spill_cost) const | |
| 6252 | { | ||
| 6253 | ✗ | if (spill_cost.size() < use_points.size()) { | |
| 6254 | ✗ | spill_cost.resize(use_points.size()); // expand | |
| 6255 | } | ||
| 6256 | ✗ | for(size_t i = 0; i < use_points.size(); ++i) { | |
| 6257 | ✗ | int cost = 0; | |
| 6258 | ✗ | for (std::vector<RegUsePoint>::const_iterator it = use_points[i].begin(); it != use_points[i].end(); ++it) { | |
| 6259 | ✗ | if (it->type & O_TYPE_READ) cost += SpillCost_Read; | |
| 6260 | ✗ | if (it->type & O_TYPE_WRITE) cost += SpillCost_Write; | |
| 6261 | } | ||
| 6262 | ✗ | spill_cost[i] += cost * freq; | |
| 6263 | } | ||
| 6264 | ✗ | } | |
| 6265 | |||
| 6266 | ✗ | void BuildIntervals() | |
| 6267 | { | ||
| 6268 | // initialize use_points ranges | ||
| 6269 | ✗ | std::vector<RegUsePointRange> use_points_ranges; | |
| 6270 | ✗ | use_points_ranges.reserve(use_points.size()); | |
| 6271 | ✗ | for (size_t i = 0; i < use_points.size(); ++i) { | |
| 6272 | ✗ | use_points_ranges.push_back(RegUsePointRange(use_points[i])); | |
| 6273 | } | ||
| 6274 | |||
| 6275 | // build interval | ||
| 6276 | ✗ | BitVector *last_liveness = NULL; | |
| 6277 | ✗ | std::vector<uint32> reg_assignables; | |
| 6278 | ✗ | bool last_reg_constraints = false; | |
| 6279 | ✗ | bool last_stack_vars = false; | |
| 6280 | ✗ | const size_t num_of_variables = live_in.size_bit() < use_points.size() ? use_points.size() : live_in.size_bit(); | |
| 6281 | ✗ | size_t instr_idx = 0; | |
| 6282 | size_t end_count; | ||
| 6283 | do { | ||
| 6284 | ✗ | BitVector liveness = live_in; | |
| 6285 | ✗ | BitVector stack_vars; | |
| 6286 | ✗ | end_count = 0; | |
| 6287 | ✗ | reg_assignables.clear(); | |
| 6288 | ✗ | size_t min_instr_idx = (size_t)-1; | |
| 6289 | ✗ | for (size_t i = 0; i < use_points_ranges.size(); ++i) { | |
| 6290 | ✗ | if (use_points_ranges[i].empty()) { | |
| 6291 | ✗ | liveness.set_bit(i, live_out.get_bit(i)); | |
| 6292 | ✗ | ++end_count; | |
| 6293 | } else { | ||
| 6294 | ✗ | if (use_points_ranges[i].first->instr_idx < min_instr_idx) { | |
| 6295 | ✗ | min_instr_idx = use_points_ranges[i].first->instr_idx; | |
| 6296 | } | ||
| 6297 | |||
| 6298 | ✗ | if (use_points_ranges[i].first->instr_idx == instr_idx) { | |
| 6299 | ✗ | for (; !use_points_ranges[i].empty() && use_points_ranges[i].first->instr_idx == instr_idx; ++use_points_ranges[i].first) { | |
| 6300 | // Check the constraints of register allocation | ||
| 6301 | ✗ | if (use_points_ranges[i].first->reg_assignable != 0xFFFFFFFF) { | |
| 6302 | ✗ | reg_assignables.resize(num_of_variables, 0xFFFFFFFF); | |
| 6303 | ✗ | reg_assignables[i] &= use_points_ranges[i].first->reg_assignable; | |
| 6304 | } | ||
| 6305 | |||
| 6306 | // Check the stack variable | ||
| 6307 | ✗ | if (use_points_ranges[i].first->type & O_TYPE_MEM) { | |
| 6308 | ✗ | stack_vars.set_bit(i, true); | |
| 6309 | } | ||
| 6310 | } | ||
| 6311 | ✗ | liveness.set_bit(i, true); | |
| 6312 | ✗ | } else if (use_points_ranges[i].first->type & O_TYPE_READ) { | |
| 6313 | ✗ | liveness.set_bit(i, true); | |
| 6314 | ✗ | } else if (use_points_ranges[i].first->type & O_TYPE_WRITE) { | |
| 6315 | ✗ | liveness.set_bit(i, false); | |
| 6316 | } else { | ||
| 6317 | ✗ | JITASM_ASSERT(0); | |
| 6318 | } | ||
| 6319 | } | ||
| 6320 | } | ||
| 6321 | |||
| 6322 | // Split interval in the following case: | ||
| 6323 | // - The liveness is changed. | ||
| 6324 | // - Current or last instruction has any constraints of register allocation. | ||
| 6325 | // - Last instruction is I_COMPILER_DECLARE_STACK_ARG | ||
| 6326 | ✗ | if (!reg_assignables.empty() || last_reg_constraints || last_stack_vars || !last_liveness || !last_liveness->is_equal(liveness)) { | |
| 6327 | ✗ | intervals.push_back(Interval(instr_idx, liveness, stack_vars, reg_assignables)); | |
| 6328 | ✗ | last_liveness = &intervals.back().liveness; | |
| 6329 | } | ||
| 6330 | |||
| 6331 | ✗ | last_reg_constraints = !reg_assignables.empty(); | |
| 6332 | ✗ | last_stack_vars = !stack_vars.empty(); | |
| 6333 | ✗ | instr_idx = min_instr_idx == instr_idx ? instr_idx + 1 : min_instr_idx; | |
| 6334 | ✗ | } while (end_count < use_points_ranges.size()); | |
| 6335 | |||
| 6336 | // check use | ||
| 6337 | ✗ | for (size_t v = 0; v < use_points.size(); ++v) { | |
| 6338 | ✗ | RegUsePointRange range(use_points[v]); | |
| 6339 | ✗ | for (size_t i = 0; i < intervals.size(); ++i) { | |
| 6340 | ✗ | const Interval *next_interval = i + 1 < intervals.size() ? &intervals[i + 1] : NULL; | |
| 6341 | ✗ | intervals[i].UpdateUse(v, range, next_interval); | |
| 6342 | } | ||
| 6343 | } | ||
| 6344 | ✗ | } | |
| 6345 | |||
| 6346 | /// Split interval | ||
| 6347 | ✗ | void SplitInterval(size_t instr_idx, size_t interval_idx) | |
| 6348 | { | ||
| 6349 | ✗ | std::vector<Interval>::iterator it = intervals.insert(intervals.begin() + interval_idx + 1, intervals[interval_idx]); | |
| 6350 | ✗ | it->instr_idx_offset = instr_idx; | |
| 6351 | |||
| 6352 | // update use | ||
| 6353 | ✗ | for (size_t v = 0; v < use_points.size(); ++v) { | |
| 6354 | ✗ | RegUsePointRange range(use_points[v]); | |
| 6355 | ✗ | for (size_t i = interval_idx; i < interval_idx + 2; ++i) { | |
| 6356 | ✗ | const Interval *next_interval = i + 1 < intervals.size() ? &intervals[i + 1] : NULL; | |
| 6357 | ✗ | intervals[i].UpdateUse(v, range, next_interval); | |
| 6358 | } | ||
| 6359 | } | ||
| 6360 | ✗ | } | |
| 6361 | |||
| 6362 | struct LessCost { | ||
| 6363 | const std::vector<int> *cost_; | ||
| 6364 | ✗ | LessCost(const std::vector<int> *cost) : cost_(cost) {} | |
| 6365 | ✗ | int get_cost(size_t i) const {return i < cost_->size() ? cost_->at(i) : 0;} | |
| 6366 | ✗ | bool operator()(size_t lhs, size_t rhs) const {return get_cost(lhs) < get_cost(rhs);} | |
| 6367 | }; | ||
| 6368 | |||
| 6369 | /// Spill identification | ||
| 6370 | ✗ | void SpillIdentification(uint32 available_reg_count, const std::vector<int>& total_spill_cost, int freq, const Interval *last_interval, std::vector<VarAttribute>& var_attrs) | |
| 6371 | { | ||
| 6372 | // initialize use_points ranges | ||
| 6373 | ✗ | std::vector<RegUsePointRange> interval_use_points; | |
| 6374 | ✗ | interval_use_points.reserve(use_points.size()); | |
| 6375 | ✗ | for (size_t i = 0; i < use_points.size(); ++i) { | |
| 6376 | ✗ | interval_use_points.push_back(RegUsePointRange(use_points[i])); | |
| 6377 | } | ||
| 6378 | |||
| 6379 | ✗ | std::vector<size_t> live_vars; | |
| 6380 | ✗ | std::vector<int> cur_spill_cost; | |
| 6381 | ✗ | for (size_t interval_idx = 0; interval_idx < intervals.size(); ++interval_idx) { | |
| 6382 | ✗ | const Interval *prior_interval = interval_idx > 0 ? &intervals[interval_idx - 1] : last_interval; | |
| 6383 | ✗ | Interval *cur_interval = &intervals[interval_idx]; | |
| 6384 | |||
| 6385 | ✗ | if (cur_interval->liveness.count_bit() > available_reg_count) { | |
| 6386 | ✗ | cur_interval->liveness.get_bit_indexes(live_vars); | |
| 6387 | |||
| 6388 | ✗ | const size_t max_var = live_vars.back(); | |
| 6389 | ✗ | if (var_attrs.size() < max_var + 1) { | |
| 6390 | ✗ | var_attrs.resize(max_var + 1); // expand var_attrs | |
| 6391 | } | ||
| 6392 | |||
| 6393 | ✗ | cur_spill_cost.resize(max_var + 1); | |
| 6394 | ✗ | for (size_t i = 0; i < live_vars.size(); ++i) { | |
| 6395 | ✗ | const size_t var = live_vars[i]; | |
| 6396 | |||
| 6397 | // step interval_use_points | ||
| 6398 | ✗ | if (var < interval_use_points.size()) { | |
| 6399 | ✗ | while (!interval_use_points[var].empty() && interval_use_points[var].first->instr_idx < cur_interval->instr_idx_offset) {++interval_use_points[var].first;} | |
| 6400 | } | ||
| 6401 | |||
| 6402 | // calculate spill cost of this interval | ||
| 6403 | ✗ | if (cur_interval->use.get_bit(var) && (interval_use_points[var].first->type & O_TYPE_MEM)) { | |
| 6404 | // special low spill cost if this variable on stack (function arguemnt) | ||
| 6405 | ✗ | cur_spill_cost[var] = -1; | |
| 6406 | ✗ | } else if (cur_interval->use.get_bit(var) && interval_use_points[var].first->instr_idx == cur_interval->instr_idx_offset) { | |
| 6407 | // special high spill cost if this variable is used at first instruction of this interval | ||
| 6408 | // because it must not be spilled. | ||
| 6409 | ✗ | cur_spill_cost[var] = 0x7FFFFFFF; | |
| 6410 | } else { | ||
| 6411 | ✗ | cur_spill_cost[var] = total_spill_cost[var]; | |
| 6412 | ✗ | if (prior_interval && !prior_interval->spill.get_bit(var)) { | |
| 6413 | ✗ | cur_spill_cost[var] += (SpillCost_Read + SpillCost_Write) * freq; | |
| 6414 | } | ||
| 6415 | } | ||
| 6416 | } | ||
| 6417 | |||
| 6418 | // Spill from the smallest cost | ||
| 6419 | ✗ | std::sort(live_vars.begin(), live_vars.end(), LessCost(&cur_spill_cost)); | |
| 6420 | |||
| 6421 | // Mark spilled variable. | ||
| 6422 | // Split interval if spilled variable is used in this interval. | ||
| 6423 | // Find first instruction index using the spilled variable. | ||
| 6424 | ✗ | size_t split_interval_instr = (size_t)-1; | |
| 6425 | ✗ | for (size_t i = 0; i < live_vars.size(); ++i) { | |
| 6426 | ✗ | const size_t var = live_vars[i]; | |
| 6427 | ✗ | const bool stack_var = (cur_spill_cost[var] < 0); // It may be function argument on stack | |
| 6428 | ✗ | const bool spill = (i + available_reg_count < live_vars.size() || stack_var); | |
| 6429 | ✗ | cur_interval->spill.set_bit(var, spill); | |
| 6430 | ✗ | if (spill) { | |
| 6431 | ✗ | var_attrs[var].spill = 1; | |
| 6432 | } | ||
| 6433 | ✗ | if (stack_var) { | |
| 6434 | // Split at next of using stack variable | ||
| 6435 | ✗ | if (interval_use_points[var].first->instr_idx + 1 < split_interval_instr) { | |
| 6436 | ✗ | split_interval_instr = interval_use_points[var].first->instr_idx + 1; | |
| 6437 | } | ||
| 6438 | ✗ | } else if (spill && cur_interval->use.get_bit(var)) { | |
| 6439 | // Split if spilled variable is used in this interval. | ||
| 6440 | ✗ | if (interval_use_points[var].first->instr_idx < split_interval_instr) { | |
| 6441 | ✗ | split_interval_instr = interval_use_points[var].first->instr_idx; | |
| 6442 | } | ||
| 6443 | } | ||
| 6444 | } | ||
| 6445 | |||
| 6446 | ✗ | if (split_interval_instr != (size_t)-1) { | |
| 6447 | ✗ | SplitInterval(split_interval_instr, interval_idx); | |
| 6448 | } | ||
| 6449 | } | ||
| 6450 | } | ||
| 6451 | ✗ | } | |
| 6452 | |||
| 6453 | struct LessAssignOrder { | ||
| 6454 | Interval *interval; | ||
| 6455 | const Interval *prior_interval; | ||
| 6456 | ✗ | LessAssignOrder(Interval *cur, const Interval *prior) : interval(cur), prior_interval(prior) {} | |
| 6457 | ✗ | bool has_constraints(size_t v) const {return v < interval->reg_assignables.size() ? interval->reg_assignables[v] != 0xFFFFFFFF : false;} | |
| 6458 | ✗ | uint32 num_of_assignable(size_t v) const {return v < interval->reg_assignables.size() ? detail::Count1Bits(interval->reg_assignables[v]) : 32;} | |
| 6459 | ✗ | bool operator()(size_t lhs, size_t rhs) const { | |
| 6460 | // is there any register constraints or not | ||
| 6461 | ✗ | const bool lhs_has_constraints = has_constraints(lhs); | |
| 6462 | ✗ | const bool rhs_has_constraints = has_constraints(rhs); | |
| 6463 | ✗ | if (lhs_has_constraints != rhs_has_constraints) { | |
| 6464 | ✗ | return lhs_has_constraints; | |
| 6465 | } | ||
| 6466 | |||
| 6467 | ✗ | if (lhs_has_constraints) { | |
| 6468 | // is the register which has constraints used in this interval or not | ||
| 6469 | ✗ | const bool lhs_used = interval->use.get_bit(lhs); | |
| 6470 | ✗ | const bool rhs_used = interval->use.get_bit(rhs); | |
| 6471 | ✗ | if (lhs_used != rhs_used) { | |
| 6472 | ✗ | return lhs_used; | |
| 6473 | } | ||
| 6474 | |||
| 6475 | // compare number of assignable registers | ||
| 6476 | ✗ | const uint32 lhs_num_of_assignable = num_of_assignable(lhs); | |
| 6477 | ✗ | const uint32 rhs_num_of_assignable = num_of_assignable(rhs); | |
| 6478 | ✗ | if (lhs_num_of_assignable != rhs_num_of_assignable) { | |
| 6479 | ✗ | return lhs_num_of_assignable < rhs_num_of_assignable; | |
| 6480 | } | ||
| 6481 | } | ||
| 6482 | |||
| 6483 | // physical register or symbolic register | ||
| 6484 | ✗ | const int lhs_sym_reg = (lhs < NUM_OF_PHYSICAL_REG ? 0 : 1); | |
| 6485 | ✗ | const int rhs_sym_reg = (rhs < NUM_OF_PHYSICAL_REG ? 0 : 1); | |
| 6486 | ✗ | if (lhs_sym_reg != rhs_sym_reg) { | |
| 6487 | ✗ | return lhs_sym_reg < rhs_sym_reg; | |
| 6488 | } | ||
| 6489 | |||
| 6490 | ✗ | if (prior_interval) { | |
| 6491 | // is the variable assigned register in prior interval or not | ||
| 6492 | ✗ | const bool lhs_prior_reg = !prior_interval->spill.get_bit(lhs) && prior_interval->liveness.get_bit(lhs); | |
| 6493 | ✗ | const bool rhs_prior_reg = !prior_interval->spill.get_bit(rhs) && prior_interval->liveness.get_bit(rhs); | |
| 6494 | ✗ | if (lhs_prior_reg != rhs_prior_reg) { | |
| 6495 | ✗ | return lhs_prior_reg; | |
| 6496 | } | ||
| 6497 | } | ||
| 6498 | |||
| 6499 | // compare register id | ||
| 6500 | ✗ | return lhs < rhs; | |
| 6501 | } | ||
| 6502 | }; | ||
| 6503 | |||
| 6504 | /// Assign register in basic block | ||
| 6505 | /** | ||
| 6506 | * \param[in] available_reg Available physical register mask | ||
| 6507 | * \param[in] last_interval Last Interval as the hint of assignment | ||
| 6508 | * \return Used physical register mask | ||
| 6509 | */ | ||
| 6510 | ✗ | uint32 AssignRegister(uint32 available_reg, const Interval *last_interval) | |
| 6511 | { | ||
| 6512 | ✗ | uint32 used_reg = 0; | |
| 6513 | ✗ | std::vector<size_t> live_vars; | |
| 6514 | ✗ | for (size_t interval_idx = 0; interval_idx < intervals.size(); ++interval_idx) { | |
| 6515 | ✗ | const Interval *prior_interval = interval_idx > 0 ? &intervals[interval_idx - 1] : last_interval; | |
| 6516 | ✗ | Interval *cur_interval = &intervals[interval_idx]; | |
| 6517 | |||
| 6518 | // enum variables to assign register | ||
| 6519 | ✗ | live_vars.clear(); | |
| 6520 | ✗ | for (size_t i = 0; i < cur_interval->liveness.size(); ++i) { | |
| 6521 | ✗ | uint32 s = i < cur_interval->spill.size() ? cur_interval->spill[i] : 0; | |
| 6522 | ✗ | uint32 l = cur_interval->liveness[i] & ~s; | |
| 6523 | ✗ | while (l != 0) { | |
| 6524 | ✗ | uint32 index = detail::bit_scan_forward(l); | |
| 6525 | ✗ | live_vars.push_back(static_cast<uint32>(i * 32) + index); | |
| 6526 | ✗ | l &= ~(1 << index); | |
| 6527 | } | ||
| 6528 | } | ||
| 6529 | |||
| 6530 | ✗ | if (!live_vars.empty()) { | |
| 6531 | ✗ | cur_interval->assignment_table.resize(live_vars.back() + 1, -1); | |
| 6532 | |||
| 6533 | // sort into assignment order | ||
| 6534 | ✗ | std::sort(live_vars.begin(), live_vars.end(), LessAssignOrder(cur_interval, prior_interval)); | |
| 6535 | } | ||
| 6536 | |||
| 6537 | // Assign register | ||
| 6538 | ✗ | uint32 cur_avail = available_reg; | |
| 6539 | ✗ | const size_t num_of_live_vars = live_vars.size(); | |
| 6540 | ✗ | for (size_t i = 0; i < live_vars.size(); ++i) { | |
| 6541 | ✗ | const size_t var = live_vars[i]; | |
| 6542 | ✗ | const bool first_try = (i < num_of_live_vars); // Try to assign for the first time | |
| 6543 | ✗ | const uint32 reg_assignable = first_try && var < cur_interval->reg_assignables.size() ? cur_interval->reg_assignables[var] : 0xFFFFFFFF; // Ignore constraint if it is retried | |
| 6544 | ✗ | JITASM_ASSERT((cur_avail & reg_assignable) != 0); | |
| 6545 | ✗ | int assigned_reg = -1; | |
| 6546 | ✗ | if (var < NUM_OF_PHYSICAL_REG && first_try) { | |
| 6547 | // Physical register | ||
| 6548 | ✗ | if (cur_avail & reg_assignable & (1 << var)) { | |
| 6549 | ✗ | assigned_reg = static_cast<int>(var); | |
| 6550 | ✗ | } else if (((1 << var) & available_reg) && !cur_interval->use.get_bit(var)) { | |
| 6551 | // Try to assign another physical register if it is not used in this interval. But assign later. | ||
| 6552 | ✗ | live_vars.push_back(var); | |
| 6553 | ✗ | } else if (reg_assignable != 0xFFFFFFFF && (cur_avail & reg_assignable) && cur_interval->use.get_bit(var)) { | |
| 6554 | // This physical register violates the register constraint. | ||
| 6555 | // Assign another physical register which satisfy the constraint. | ||
| 6556 | ✗ | assigned_reg = detail::bit_scan_forward(cur_avail & reg_assignable); | |
| 6557 | } else { | ||
| 6558 | // This may be out of assignment register (ESP, EBP and so on...) | ||
| 6559 | ✗ | JITASM_ASSERT(((1 << var) & available_reg) == 0); // false assignment!? | |
| 6560 | ✗ | assigned_reg = static_cast<int>(var); | |
| 6561 | } | ||
| 6562 | } else { | ||
| 6563 | // Symbolic register or retried physical register | ||
| 6564 | ✗ | const int last_assigned = prior_interval && var < prior_interval->assignment_table.size() ? prior_interval->assignment_table[var] : -1; | |
| 6565 | ✗ | if (last_assigned != -1 && (cur_avail & reg_assignable & (1 << last_assigned))) { | |
| 6566 | // select last assigned register | ||
| 6567 | ✗ | assigned_reg = last_assigned; | |
| 6568 | ✗ | } else if (cur_avail & reg_assignable) { | |
| 6569 | ✗ | assigned_reg = detail::bit_scan_forward(cur_avail & reg_assignable); | |
| 6570 | ✗ | } else if (reg_assignable != 0xFFFFFFFF && !cur_interval->use.get_bit(var)) { | |
| 6571 | // Try to assign register ignoring constraint if it is not used in this interval. But assign later. | ||
| 6572 | ✗ | live_vars.push_back(var); | |
| 6573 | } else { | ||
| 6574 | ✗ | JITASM_ASSERT(0); | |
| 6575 | } | ||
| 6576 | } | ||
| 6577 | |||
| 6578 | ✗ | if (assigned_reg >= 0) { | |
| 6579 | ✗ | cur_interval->assignment_table[var] = assigned_reg; | |
| 6580 | ✗ | cur_avail &= ~(1 << assigned_reg); | |
| 6581 | } | ||
| 6582 | } | ||
| 6583 | |||
| 6584 | ✗ | used_reg |= ~cur_avail & available_reg; | |
| 6585 | } | ||
| 6586 | |||
| 6587 | ✗ | return used_reg; | |
| 6588 | ✗ | } | |
| 6589 | |||
| 6590 | void DumpIntervals(size_t block_id, bool dump_assigned_reg) const | ||
| 6591 | { | ||
| 6592 | avoid_unused_warn(block_id); | ||
| 6593 | JITASM_TRACE("---- Block%d ----\n", block_id); | ||
| 6594 | for (size_t i = 0; i < intervals.size(); ++i) { | ||
| 6595 | intervals[i].Dump(dump_assigned_reg); | ||
| 6596 | } | ||
| 6597 | } | ||
| 6598 | }; | ||
| 6599 | |||
| 6600 | /// Basic block | ||
| 6601 | struct BasicBlock | ||
| 6602 | { | ||
| 6603 | BasicBlock *successor[2]; | ||
| 6604 | std::vector<BasicBlock *> predecessor; | ||
| 6605 | size_t instr_begin; ///< Begin instruction index of the basic block (inclusive) | ||
| 6606 | size_t instr_end; ///< End instruction index of the basic block (exclusive) | ||
| 6607 | size_t depth; ///< Depth-first order of Control flow | ||
| 6608 | BasicBlock *dfs_parent; ///< Depth-first search tree parent | ||
| 6609 | BasicBlock *immediate_dominator; ///< Immediate dominator | ||
| 6610 | size_t loop_depth; ///< Loop nesting depth | ||
| 6611 | Lifetime lifetime[3]; ///< Variable lifetime (0: GP, 1: MMX, 2: XMM/YMM) | ||
| 6612 | |||
| 6613 | ✗ | BasicBlock(size_t instr_begin_, size_t instr_end_, BasicBlock *successor0 = NULL, BasicBlock *successor1 = NULL) : instr_begin(instr_begin_), instr_end(instr_end_), depth((size_t)-1), dfs_parent(NULL), immediate_dominator(NULL), loop_depth(0) { | |
| 6614 | ✗ | successor[0] = successor0; | |
| 6615 | ✗ | successor[1] = successor1; | |
| 6616 | ✗ | } | |
| 6617 | |||
| 6618 | bool operator<(const BasicBlock& rhs) const { return instr_begin < rhs.instr_begin; } | ||
| 6619 | |||
| 6620 | /// Remove predecessor | ||
| 6621 | ✗ | void RemovePredecessor(BasicBlock *block) { | |
| 6622 | ✗ | std::vector<BasicBlock *>::iterator it = std::find(predecessor.begin(), predecessor.end(), block); | |
| 6623 | ✗ | if (it != predecessor.end()) { | |
| 6624 | ✗ | predecessor.erase(it); | |
| 6625 | } | ||
| 6626 | ✗ | } | |
| 6627 | |||
| 6628 | /// Replace predecessor | ||
| 6629 | ✗ | bool ReplacePredecessor(BasicBlock *old_pred, BasicBlock *new_pred) { | |
| 6630 | ✗ | std::vector<BasicBlock *>::iterator it = std::find(predecessor.begin(), predecessor.end(), old_pred); | |
| 6631 | ✗ | if (it != predecessor.end()) { | |
| 6632 | ✗ | *it = new_pred; | |
| 6633 | ✗ | return true; | |
| 6634 | } | ||
| 6635 | ✗ | return false; | |
| 6636 | } | ||
| 6637 | |||
| 6638 | /// Check if the specified block is dominator of this block | ||
| 6639 | ✗ | bool IsDominated(BasicBlock *block) const { | |
| 6640 | ✗ | if (block == this) {return true;} | |
| 6641 | ✗ | return immediate_dominator ? immediate_dominator->IsDominated(block) : false; | |
| 6642 | } | ||
| 6643 | |||
| 6644 | /// Get estimated frequency of basic block | ||
| 6645 | ✗ | int GetFrequency() const { | |
| 6646 | const static int freq[] = {1, 100, 10000, 40000, 160000, 640000}; | ||
| 6647 | ✗ | return freq[loop_depth < sizeof(freq) / sizeof(int) ? loop_depth : sizeof(freq) / sizeof(int) - 1]; | |
| 6648 | } | ||
| 6649 | |||
| 6650 | /// Get variable lifetime | ||
| 6651 | ✗ | Lifetime& GetLifetime(RegType type) {return lifetime[GetRegFamily(type)];} | |
| 6652 | /// Get variable lifetime | ||
| 6653 | const Lifetime& GetLifetime(RegType type) const {return lifetime[GetRegFamily(type)];} | ||
| 6654 | |||
| 6655 | struct less | ||
| 6656 | { | ||
| 6657 | bool operator()(BasicBlock *lhs, BasicBlock *rhs) { return lhs->instr_begin < rhs->instr_begin; } | ||
| 6658 | bool operator()(BasicBlock *lhs, size_t rhs) { return lhs->instr_begin < rhs; } | ||
| 6659 | ✗ | bool operator()(size_t lhs, BasicBlock *rhs) { return lhs < rhs->instr_begin; } | |
| 6660 | }; | ||
| 6661 | }; | ||
| 6662 | |||
| 6663 | /** | ||
| 6664 | * The Lengauer-Tarjan algorithm | ||
| 6665 | */ | ||
| 6666 | class DominatorFinder | ||
| 6667 | { | ||
| 6668 | private: | ||
| 6669 | std::vector<size_t> sdom_; // semidominator | ||
| 6670 | std::vector<size_t> ancestor_; | ||
| 6671 | std::vector<size_t> best_; | ||
| 6672 | |||
| 6673 | ✗ | void Link(size_t v, size_t w) | |
| 6674 | { | ||
| 6675 | ✗ | ancestor_[w] = v; | |
| 6676 | ✗ | } | |
| 6677 | |||
| 6678 | ✗ | size_t Eval(size_t v) | |
| 6679 | { | ||
| 6680 | ✗ | if (ancestor_[v] == 0) return v; | |
| 6681 | ✗ | Compress(v); | |
| 6682 | ✗ | return best_[v]; | |
| 6683 | } | ||
| 6684 | |||
| 6685 | ✗ | void Compress(size_t v) | |
| 6686 | { | ||
| 6687 | ✗ | size_t a = ancestor_[v]; | |
| 6688 | ✗ | if (ancestor_[a] == 0) | |
| 6689 | ✗ | return; | |
| 6690 | |||
| 6691 | ✗ | Compress(a); | |
| 6692 | |||
| 6693 | ✗ | if (sdom_[best_[v]] > sdom_[best_[a]]) | |
| 6694 | ✗ | best_[v] = best_[a]; | |
| 6695 | |||
| 6696 | ✗ | ancestor_[v] = ancestor_[a]; | |
| 6697 | } | ||
| 6698 | |||
| 6699 | public: | ||
| 6700 | ✗ | void operator()(std::deque<BasicBlock *>& depth_first_blocks) | |
| 6701 | { | ||
| 6702 | ✗ | const size_t num_of_nodes = depth_first_blocks.size(); | |
| 6703 | ✗ | if (num_of_nodes == 0) return; | |
| 6704 | |||
| 6705 | // initialize | ||
| 6706 | ✗ | sdom_.resize(num_of_nodes); // semidominator | |
| 6707 | ✗ | ancestor_.clear(); | |
| 6708 | ✗ | ancestor_.resize(num_of_nodes); | |
| 6709 | ✗ | best_.resize(num_of_nodes); | |
| 6710 | ✗ | std::vector< std::vector<size_t> > bucket(num_of_nodes); | |
| 6711 | ✗ | std::vector<size_t> dom(num_of_nodes); | |
| 6712 | ✗ | for (size_t i = 0; i < num_of_nodes; ++i) { | |
| 6713 | ✗ | sdom_[i] = i; | |
| 6714 | ✗ | best_[i] = i; | |
| 6715 | } | ||
| 6716 | |||
| 6717 | ✗ | for (size_t w = num_of_nodes - 1; w > 0; --w) { | |
| 6718 | ✗ | BasicBlock *wb = depth_first_blocks[w]; | |
| 6719 | ✗ | size_t p = wb->dfs_parent->depth; | |
| 6720 | |||
| 6721 | // Compute the semidominator | ||
| 6722 | ✗ | for (std::vector<BasicBlock *>::iterator v = wb->predecessor.begin(); v != wb->predecessor.end(); ++v) { | |
| 6723 | ✗ | if ((*v)->depth != (size_t)-1) { // skip out of DFS tree | |
| 6724 | ✗ | size_t u = Eval((*v)->depth); | |
| 6725 | ✗ | if (sdom_[u] < sdom_[w]) | |
| 6726 | ✗ | sdom_[w] = sdom_[u]; | |
| 6727 | } | ||
| 6728 | } | ||
| 6729 | ✗ | bucket[sdom_[w]].push_back(w); | |
| 6730 | ✗ | Link(p, w); | |
| 6731 | |||
| 6732 | // Implicity compute immediate dominator | ||
| 6733 | ✗ | for (std::vector<size_t>::iterator v = bucket[p].begin(); v != bucket[p].end(); ++v) { | |
| 6734 | ✗ | size_t u = Eval(*v); | |
| 6735 | ✗ | dom[*v] = sdom_[u] < sdom_[*v] ? u : p; | |
| 6736 | } | ||
| 6737 | ✗ | bucket[p].clear(); | |
| 6738 | } | ||
| 6739 | |||
| 6740 | // Explicity compute immediate dominator | ||
| 6741 | ✗ | for (size_t w = 1; w < num_of_nodes; ++w) { | |
| 6742 | ✗ | if (dom[w] != sdom_[w]) | |
| 6743 | ✗ | dom[w] = dom[dom[w]]; | |
| 6744 | ✗ | depth_first_blocks[w]->immediate_dominator = depth_first_blocks[dom[w]]; | |
| 6745 | } | ||
| 6746 | ✗ | depth_first_blocks[0]->immediate_dominator = NULL; | |
| 6747 | ✗ | } | |
| 6748 | }; | ||
| 6749 | |||
| 6750 | /// Control flow graph | ||
| 6751 | class ControlFlowGraph | ||
| 6752 | { | ||
| 6753 | public: | ||
| 6754 | typedef std::deque<BasicBlock *> BlockList; | ||
| 6755 | |||
| 6756 | private: | ||
| 6757 | BlockList blocks_; | ||
| 6758 | BlockList depth_first_blocks_; | ||
| 6759 | |||
| 6760 | ✗ | void MakeDepthFirstBlocks(BasicBlock *block) | |
| 6761 | { | ||
| 6762 | ✗ | block->depth = 0; // mark "visited" | |
| 6763 | ✗ | for (size_t i = 0; i < 2; ++i) { | |
| 6764 | ✗ | BasicBlock *s = block->successor[i]; | |
| 6765 | ✗ | if (s && s->depth != 0) { | |
| 6766 | ✗ | s->dfs_parent = block; | |
| 6767 | ✗ | MakeDepthFirstBlocks(s); | |
| 6768 | } | ||
| 6769 | } | ||
| 6770 | ✗ | depth_first_blocks_.push_front(block); | |
| 6771 | ✗ | } | |
| 6772 | |||
| 6773 | struct sort_backedge { | ||
| 6774 | ✗ | bool operator()(const std::pair<size_t, size_t>& lhs, const std::pair<size_t, size_t>& rhs) const { | |
| 6775 | ✗ | if (lhs.second < rhs.second) return true; // smaller depth loop header first | |
| 6776 | ✗ | if (lhs.second == rhs.second) return lhs.first > rhs.first; // larger depth of end of loop first if same loop header | |
| 6777 | ✗ | return false; | |
| 6778 | } | ||
| 6779 | }; | ||
| 6780 | |||
| 6781 | ✗ | void DetectLoops() | |
| 6782 | { | ||
| 6783 | // Make dominator tree | ||
| 6784 | ✗ | DominatorFinder dom_finder; | |
| 6785 | ✗ | dom_finder(depth_first_blocks_); | |
| 6786 | |||
| 6787 | // Identify backedges | ||
| 6788 | ✗ | std::vector< std::pair<size_t, size_t> > backedges; | |
| 6789 | ✗ | for (size_t i = 0; i < depth_first_blocks_.size(); ++i) { | |
| 6790 | ✗ | BasicBlock *block = depth_first_blocks_[i]; | |
| 6791 | ✗ | for (size_t j = 0; j < 2; ++j) { | |
| 6792 | ✗ | if (block->successor[j] && block->depth >= block->successor[j]->depth) { // retreating edge | |
| 6793 | ✗ | if (block->IsDominated(block->successor[j])) { | |
| 6794 | ✗ | backedges.push_back(std::make_pair(block->depth, block->successor[j]->depth)); | |
| 6795 | } | ||
| 6796 | } | ||
| 6797 | } | ||
| 6798 | } | ||
| 6799 | |||
| 6800 | // Merge loops with the same loop header | ||
| 6801 | ✗ | std::sort(backedges.begin(), backedges.end(), sort_backedge()); | |
| 6802 | ✗ | if (backedges.size() >= 2) { | |
| 6803 | ✗ | std::vector< std::pair<size_t, size_t> >::iterator it = backedges.begin() + 1; | |
| 6804 | ✗ | while (it != backedges.end()) { | |
| 6805 | ✗ | if (detail::prior(it)->second == it->second) { | |
| 6806 | // erase backedge of smaller loop | ||
| 6807 | ✗ | it = backedges.erase(it); | |
| 6808 | } else { | ||
| 6809 | ++it; | ||
| 6810 | } | ||
| 6811 | } | ||
| 6812 | } | ||
| 6813 | |||
| 6814 | // Set loop depth | ||
| 6815 | ✗ | for (std::vector< std::pair<size_t, size_t> >::iterator it = backedges.begin(); it != backedges.end(); ++it) { | |
| 6816 | ✗ | for (size_t i = it->second; i <= it->first; ++i) { | |
| 6817 | ✗ | depth_first_blocks_[i]->loop_depth++; | |
| 6818 | } | ||
| 6819 | } | ||
| 6820 | ✗ | } | |
| 6821 | |||
| 6822 | ✗ | BlockList::iterator initialize(size_t num_of_instructions) { | |
| 6823 | ✗ | clear(); | |
| 6824 | ✗ | blocks_.resize(num_of_instructions > 0 ? 2 : 1); | |
| 6825 | ✗ | BasicBlock *enter_block = new BasicBlock(0, num_of_instructions); | |
| 6826 | ✗ | blocks_[0] = enter_block; | |
| 6827 | ✗ | if (num_of_instructions > 0) { | |
| 6828 | // exit block | ||
| 6829 | ✗ | BasicBlock *exit_block = new BasicBlock(num_of_instructions, num_of_instructions); | |
| 6830 | ✗ | blocks_[1] = exit_block; | |
| 6831 | ✗ | enter_block->successor[0] = exit_block; | |
| 6832 | ✗ | exit_block->predecessor.push_back(enter_block); | |
| 6833 | } | ||
| 6834 | ✗ | return blocks_.begin(); | |
| 6835 | } | ||
| 6836 | |||
| 6837 | /// Split basic block | ||
| 6838 | ✗ | BlockList::iterator split(BlockList::iterator target_block_it, size_t instr_idx) { | |
| 6839 | ✗ | BasicBlock *target_block = *target_block_it; | |
| 6840 | ✗ | if (target_block->instr_begin == instr_idx) | |
| 6841 | ✗ | return target_block_it; | |
| 6842 | |||
| 6843 | ✗ | BasicBlock *new_block = new BasicBlock(instr_idx, target_block->instr_end); | |
| 6844 | ✗ | new_block->successor[0] = target_block->successor[0]; | |
| 6845 | ✗ | new_block->successor[1] = target_block->successor[1]; | |
| 6846 | ✗ | new_block->predecessor.push_back(target_block); | |
| 6847 | ✗ | target_block->successor[0] = new_block; | |
| 6848 | ✗ | target_block->successor[1] = NULL; | |
| 6849 | ✗ | target_block->instr_end = instr_idx; | |
| 6850 | |||
| 6851 | // replace predecessor of successors | ||
| 6852 | ✗ | if (new_block->successor[0]) new_block->successor[0]->ReplacePredecessor(target_block, new_block); | |
| 6853 | ✗ | if (new_block->successor[1]) new_block->successor[1]->ReplacePredecessor(target_block, new_block); | |
| 6854 | |||
| 6855 | ✗ | return blocks_.insert(detail::next(target_block_it), new_block); | |
| 6856 | } | ||
| 6857 | |||
| 6858 | public: | ||
| 6859 | ✗ | ~ControlFlowGraph() | |
| 6860 | { | ||
| 6861 | ✗ | clear(); | |
| 6862 | ✗ | } | |
| 6863 | |||
| 6864 | ✗ | BlockList::iterator get_block(size_t instr_idx) { | |
| 6865 | ✗ | BlockList::iterator it = std::upper_bound(blocks_.begin(), blocks_.end(), instr_idx, BasicBlock::less()); | |
| 6866 | ✗ | return it != blocks_.begin() ? --it : blocks_.end(); | |
| 6867 | } | ||
| 6868 | |||
| 6869 | ✗ | BlockList::iterator get_exit_block() { | |
| 6870 | ✗ | return detail::prior(blocks_.end()); | |
| 6871 | } | ||
| 6872 | |||
| 6873 | ✗ | size_t size() { return blocks_.size(); } | |
| 6874 | |||
| 6875 | ✗ | void clear() | |
| 6876 | { | ||
| 6877 | ✗ | for (BlockList::iterator it = blocks_.begin(); it != blocks_.end(); ++it) { | |
| 6878 | ✗ | delete *it; | |
| 6879 | } | ||
| 6880 | ✗ | blocks_.clear(); | |
| 6881 | ✗ | depth_first_blocks_.clear(); | |
| 6882 | ✗ | } | |
| 6883 | |||
| 6884 | ✗ | BlockList::iterator begin() { return blocks_.begin(); } | |
| 6885 | ✗ | BlockList::iterator end() { return blocks_.end(); } | |
| 6886 | ✗ | BlockList::const_iterator begin() const { return blocks_.begin(); } | |
| 6887 | ✗ | BlockList::const_iterator end() const { return blocks_.end(); } | |
| 6888 | ✗ | BlockList::iterator dfs_begin() { return depth_first_blocks_.begin(); } | |
| 6889 | ✗ | BlockList::iterator dfs_end() { return depth_first_blocks_.end(); } | |
| 6890 | |||
| 6891 | void DumpDot() const | ||
| 6892 | { | ||
| 6893 | JITASM_TRACE("digraph CFG {\n"); | ||
| 6894 | JITASM_TRACE("\tnode[shape=box];\n"); | ||
| 6895 | for (BlockList::const_iterator it = blocks_.begin(); it != blocks_.end(); ++it) { | ||
| 6896 | BasicBlock *block = *it; | ||
| 6897 | std::string live_in = "live in:"; | ||
| 6898 | std::string live_out = "live out:"; | ||
| 6899 | for (size_t reg_family = 0; reg_family < 3; ++reg_family) { | ||
| 6900 | for (size_t i = 0; i < block->lifetime[reg_family].live_in.size_bit(); ++i) { | ||
| 6901 | if (block->lifetime[reg_family].live_in.get_bit(i)) { | ||
| 6902 | live_in.append(" "); | ||
| 6903 | live_in.append(GetRegName(static_cast<RegType>(reg_family + (i < NUM_OF_PHYSICAL_REG ? R_TYPE_GP : R_TYPE_SYMBOLIC_GP)), i)); | ||
| 6904 | } | ||
| 6905 | } | ||
| 6906 | for (size_t i = 0; i < block->lifetime[reg_family].live_out.size_bit(); ++i) { | ||
| 6907 | if (block->lifetime[reg_family].live_out.get_bit(i)) { | ||
| 6908 | live_out.append(" "); | ||
| 6909 | live_out.append(GetRegName(static_cast<RegType>(reg_family + (i < NUM_OF_PHYSICAL_REG ? R_TYPE_GP : R_TYPE_SYMBOLIC_GP)), i)); | ||
| 6910 | } | ||
| 6911 | } | ||
| 6912 | } | ||
| 6913 | JITASM_TRACE("\tnode%d[label=\"Block%d\\ninstruction %d - %d\\nloop depth %d\\n%s\\n%s\"];\n", block->instr_begin, block->depth, block->instr_begin, block->instr_end - 1, block->loop_depth, live_in.c_str(), live_out.c_str()); | ||
| 6914 | int constraint = 0; avoid_unused_warn(constraint); | ||
| 6915 | if (block->successor[0]) JITASM_TRACE("\t\"node%d\" -> \"node%d\" [constraint=%s];\n", block->instr_begin, block->successor[0]->instr_begin, constraint == 0 ? "true" : "false"); | ||
| 6916 | if (block->successor[1]) JITASM_TRACE("\t\"node%d\" -> \"node%d\" [constraint=%s];\n", block->instr_begin, block->successor[1]->instr_begin, constraint == 0 ? "true" : "false"); | ||
| 6917 | //if (block->dfs_parent) JITASM_TRACE("\t\"node%d\" -> \"node%d\" [color=\"#ff0000\"];\n", block->instr_begin, block->dfs_parent->instr_begin); | ||
| 6918 | //if (block->immediate_dominator) JITASM_TRACE("\t\"node%d\" -> \"node%d\" [constraint=false, color=\"#0000ff\"];\n", block->instr_begin, block->immediate_dominator->instr_begin); | ||
| 6919 | //for (size_t i = 0; i < block->predecessor.size(); ++i) { | ||
| 6920 | // JITASM_TRACE("\t\"node%d\" -> \"node%d\" [constraint=false, color=\"#808080\"];\n", block->instr_begin, block->predecessor[i]->instr_begin); | ||
| 6921 | //} | ||
| 6922 | } | ||
| 6923 | JITASM_TRACE("}\n"); | ||
| 6924 | } | ||
| 6925 | |||
| 6926 | /// Build control flow graph from instruction list | ||
| 6927 | ✗ | void Build(const Frontend& f) | |
| 6928 | { | ||
| 6929 | ✗ | initialize(f.instrs_.size()); | |
| 6930 | ✗ | size_t block_idx = 0; | |
| 6931 | ✗ | for (size_t instr_idx = 0; instr_idx < f.instrs_.size(); ++instr_idx) { | |
| 6932 | ✗ | InstrID instr_id = f.instrs_[instr_idx].GetID(); | |
| 6933 | ✗ | if (Frontend::IsJump(instr_id) || instr_id == I_RET || instr_id == I_IRET) { | |
| 6934 | ✗ | while (blocks_[block_idx]->instr_end <= instr_idx) { | |
| 6935 | ✗ | ++block_idx; | |
| 6936 | } | ||
| 6937 | ✗ | BasicBlock *cur_block = blocks_[block_idx]; | |
| 6938 | ✗ | JITASM_ASSERT(block_idx == std::distance(blocks_.begin(), get_block(instr_idx))); | |
| 6939 | |||
| 6940 | // Jump instruction always terminate basic block | ||
| 6941 | ✗ | if (instr_idx + 1 < cur_block->instr_end) { | |
| 6942 | // Split basic block | ||
| 6943 | ✗ | split(blocks_.begin() + block_idx, instr_idx + 1); | |
| 6944 | } | ||
| 6945 | |||
| 6946 | // Set successors of current block | ||
| 6947 | ✗ | if (instr_id == I_RET || instr_id == I_IRET) { | |
| 6948 | ✗ | if (cur_block->successor[0]) | |
| 6949 | ✗ | cur_block->successor[0]->RemovePredecessor(cur_block); | |
| 6950 | ✗ | cur_block->successor[0] = *get_exit_block(); | |
| 6951 | ✗ | (*get_exit_block())->predecessor.push_back(cur_block); | |
| 6952 | } else { | ||
| 6953 | ✗ | const size_t jump_to = f.GetJumpTo(f.instrs_[instr_idx]); // jump target instruction index | |
| 6954 | ✗ | BasicBlock *jump_target = *split(get_block(jump_to), jump_to); | |
| 6955 | |||
| 6956 | // Update cur_block if split cur_block | ||
| 6957 | ✗ | if (jump_target->instr_begin <= instr_idx && instr_idx < jump_target->instr_end) { | |
| 6958 | ✗ | cur_block = jump_target; | |
| 6959 | } | ||
| 6960 | |||
| 6961 | ✗ | if (instr_id == I_JMP) { | |
| 6962 | ✗ | if (cur_block->successor[0]) | |
| 6963 | ✗ | cur_block->successor[0]->RemovePredecessor(cur_block); | |
| 6964 | ✗ | cur_block->successor[0] = jump_target; | |
| 6965 | ✗ | jump_target->predecessor.push_back(cur_block); | |
| 6966 | } else { | ||
| 6967 | ✗ | JITASM_ASSERT(instr_id == I_JCC || instr_id == I_LOOP); | |
| 6968 | ✗ | if (cur_block->successor[1]) | |
| 6969 | ✗ | cur_block->successor[1]->RemovePredecessor(cur_block); | |
| 6970 | ✗ | cur_block->successor[1] = jump_target; | |
| 6971 | ✗ | jump_target->predecessor.push_back(cur_block); | |
| 6972 | } | ||
| 6973 | } | ||
| 6974 | } | ||
| 6975 | } | ||
| 6976 | |||
| 6977 | // Make depth first orderd list | ||
| 6978 | ✗ | MakeDepthFirstBlocks(*get_block(0)); | |
| 6979 | |||
| 6980 | // Numbering depth | ||
| 6981 | ✗ | for (size_t i = 0; i < depth_first_blocks_.size(); ++i) { | |
| 6982 | ✗ | depth_first_blocks_[i]->depth = i; | |
| 6983 | } | ||
| 6984 | |||
| 6985 | // Detect loops | ||
| 6986 | ✗ | DetectLoops(); | |
| 6987 | ✗ | } | |
| 6988 | |||
| 6989 | /// Build dummy control flow graph which has enter and exit blocks. | ||
| 6990 | ✗ | void BuildDummy(const Frontend& f) | |
| 6991 | { | ||
| 6992 | ✗ | BasicBlock *enter_block = *initialize(f.instrs_.size()); | |
| 6993 | ✗ | BasicBlock *exit_block = enter_block->successor[0]; | |
| 6994 | |||
| 6995 | ✗ | enter_block->depth = 0; | |
| 6996 | ✗ | depth_first_blocks_.push_back(enter_block); | |
| 6997 | ✗ | if (exit_block) { | |
| 6998 | ✗ | exit_block->depth = 1; | |
| 6999 | ✗ | exit_block->dfs_parent = enter_block; | |
| 7000 | ✗ | exit_block->immediate_dominator = enter_block; | |
| 7001 | ✗ | depth_first_blocks_.push_back(exit_block); | |
| 7002 | } | ||
| 7003 | ✗ | } | |
| 7004 | }; | ||
| 7005 | |||
| 7006 | /// Prepare compile | ||
| 7007 | /** | ||
| 7008 | * - Re-number symbolic register ID. | ||
| 7009 | * - Check if register allocation is needed or not. | ||
| 7010 | * - Look over physical register use. | ||
| 7011 | * | ||
| 7012 | * \param[in,out] instrs Instruction list | ||
| 7013 | * \param[out] modified_physical_reg Modified physical register mask | ||
| 7014 | * \param[out] need_reg_alloc Register allocation is needed or not | ||
| 7015 | * \return There is any compile process if it is true. | ||
| 7016 | */ | ||
| 7017 | ✗ | inline bool PrepareCompile(Frontend::InstrList& instrs, uint32 (&modified_physical_reg)[3], bool (&need_reg_alloc)[3]) | |
| 7018 | { | ||
| 7019 | struct RegIDMap { | ||
| 7020 | int next_id_; | ||
| 7021 | std::map<int, int> id_map_; | ||
| 7022 | ✗ | RegIDMap() : next_id_(NUM_OF_PHYSICAL_REG) {} | |
| 7023 | ✗ | int GetNormalizedID(int id) { | |
| 7024 | ✗ | std::map<int, int>::iterator it = id_map_.find(id); | |
| 7025 | ✗ | if (it != id_map_.end()) {return it->second;} | |
| 7026 | ✗ | int new_id = next_id_++; | |
| 7027 | ✗ | id_map_.insert(std::pair<int, int>(id, new_id)); | |
| 7028 | ✗ | return new_id; | |
| 7029 | } | ||
| 7030 | }; | ||
| 7031 | ✗ | RegIDMap reg_id_map[3]; // GP, MMX, XMM/YMM | |
| 7032 | ✗ | modified_physical_reg[0] = modified_physical_reg[1] = modified_physical_reg[2] = 0; | |
| 7033 | ✗ | need_reg_alloc[0] = need_reg_alloc[1] = need_reg_alloc[2] = false; | |
| 7034 | ✗ | bool compile_process = false; | |
| 7035 | |||
| 7036 | ✗ | for (Frontend::InstrList::iterator it = instrs.begin(); it != instrs.end(); ++it) { | |
| 7037 | ✗ | const InstrID instr_id = it->GetID(); | |
| 7038 | ✗ | if (instr_id == I_COMPILER_DECLARE_REG_ARG || instr_id == I_COMPILER_DECLARE_STACK_ARG || instr_id == I_COMPILER_DECLARE_RESULT_REG || instr_id == I_COMPILER_PROLOG || instr_id == I_COMPILER_EPILOG) { | |
| 7039 | ✗ | compile_process = true; | |
| 7040 | } | ||
| 7041 | |||
| 7042 | ✗ | for (size_t i = 0; i < Instr::MAX_OPERAND_COUNT; ++i) { | |
| 7043 | ✗ | detail::Opd& opd = it->GetOpd(i); | |
| 7044 | ✗ | if (opd.IsReg() && !opd.IsFpuReg()) { | |
| 7045 | ✗ | const RegID& reg = opd.GetReg(); | |
| 7046 | ✗ | const size_t reg_family = GetRegFamily(reg.GetType()); | |
| 7047 | ✗ | if (reg.IsSymbolic()) { | |
| 7048 | ✗ | opd.reg_.id = reg_id_map[reg_family].GetNormalizedID(reg.id); | |
| 7049 | } else { | ||
| 7050 | ✗ | if (opd.IsWrite()) { | |
| 7051 | // This physical register is modified | ||
| 7052 | ✗ | modified_physical_reg[reg_family] |= (1 << reg.id); | |
| 7053 | } | ||
| 7054 | |||
| 7055 | ✗ | if ((opd.reg_assignable_ & (1 << reg.id)) == 0) { | |
| 7056 | // Specified physical register does not fit the instruction. | ||
| 7057 | // Let's try to assign optimal physical register by register allocation. | ||
| 7058 | ✗ | need_reg_alloc[reg_family] = true; | |
| 7059 | } | ||
| 7060 | } | ||
| 7061 | ✗ | } else if (opd.IsMem()) { | |
| 7062 | ✗ | const RegID& base = opd.GetBase(); | |
| 7063 | ✗ | if (base.IsSymbolic()) { | |
| 7064 | ✗ | opd.base_.id = reg_id_map[0].GetNormalizedID(base.id); | |
| 7065 | } | ||
| 7066 | |||
| 7067 | ✗ | const RegID& index = opd.GetIndex(); | |
| 7068 | ✗ | if (index.IsSymbolic()) { | |
| 7069 | ✗ | opd.index_.id = reg_id_map[GetRegFamily(index.GetType())].GetNormalizedID(index.id); | |
| 7070 | } | ||
| 7071 | } | ||
| 7072 | } | ||
| 7073 | } | ||
| 7074 | |||
| 7075 | ✗ | for (size_t i = 0; i < 3; ++i) { | |
| 7076 | ✗ | if (!need_reg_alloc[i] && reg_id_map[i].next_id_ > NUM_OF_PHYSICAL_REG) { | |
| 7077 | ✗ | need_reg_alloc[i] = true; | |
| 7078 | } | ||
| 7079 | } | ||
| 7080 | |||
| 7081 | ✗ | return compile_process || need_reg_alloc[0] || need_reg_alloc[1] || need_reg_alloc[2]; | |
| 7082 | ✗ | } | |
| 7083 | |||
| 7084 | /// Check the instruction if it break register dependence | ||
| 7085 | ✗ | inline bool IsBreakDependenceInstr(const Instr& instr) | |
| 7086 | { | ||
| 7087 | // Instructions | ||
| 7088 | // SUB, SBB, XOR, PXOR, XORPS, XORPD, PANDN, PSUBxx, PCMPxx | ||
| 7089 | ✗ | const InstrID id = instr.GetID(); | |
| 7090 | ✗ | if (id == I_SUB || id == I_SBB || id == I_XOR || id == I_PXOR || id == I_XORPS || id == I_XORPD || id == I_PANDN || | |
| 7091 | ✗ | id == I_PSUBB || id == I_PSUBW || id == I_PSUBD || id == I_PSUBQ || id == I_PSUBSB || id == I_PSUBSW || id == I_PSUBUSB || id == I_PSUBUSW || | |
| 7092 | ✗ | id == I_PCMPEQB || id == I_PCMPEQW || id == I_PCMPEQD || id == I_PCMPEQQ || id == I_PCMPGTB || id == I_PCMPGTW || id == I_PCMPGTD || id == I_PCMPGTQ) { | |
| 7093 | // source and destination operands are the same register. | ||
| 7094 | // 8bit or 16bit register cannot break dependence. | ||
| 7095 | ✗ | const detail::Opd& opd0 = instr.GetOpd(0); | |
| 7096 | ✗ | const detail::Opd& opd1 = instr.GetOpd(1); | |
| 7097 | ✗ | const OpdSize opdsize = opd0.GetSize(); | |
| 7098 | ✗ | if (opd0 == opd1 && opd0.IsReg() && opdsize != O_SIZE_8 && opdsize != O_SIZE_16) { | |
| 7099 | ✗ | return true; | |
| 7100 | } | ||
| 7101 | } | ||
| 7102 | ✗ | return false; | |
| 7103 | } | ||
| 7104 | |||
| 7105 | /// Live Variable Analysis | ||
| 7106 | ✗ | inline void LiveVariableAnalysis(const Frontend& f, ControlFlowGraph& cfg, VariableManager& var_manager) | |
| 7107 | { | ||
| 7108 | ✗ | std::vector<BasicBlock *> update_target; | |
| 7109 | ✗ | update_target.reserve(cfg.size()); | |
| 7110 | |||
| 7111 | ✗ | for (ControlFlowGraph::BlockList::iterator it = cfg.begin(); it != cfg.end(); ++it) { | |
| 7112 | ✗ | BasicBlock *block = *it; | |
| 7113 | // Scanning instructions of basic block and make register lifetime table | ||
| 7114 | ✗ | for (size_t i = block->instr_begin; i != block->instr_end; ++i) { | |
| 7115 | ✗ | const size_t instr_offset = i - block->instr_begin; | |
| 7116 | ✗ | const Instr& instr = f.instrs_[i]; | |
| 7117 | ✗ | if (instr.GetID() == I_COMPILER_DECLARE_REG_ARG) { | |
| 7118 | // Declare function argument on register | ||
| 7119 | ✗ | const detail::Opd& opd0 = instr.GetOpd(0); | |
| 7120 | ✗ | const RegID& reg = opd0.GetReg(); | |
| 7121 | // Avoid passing operand size 8 or 16 to AddUsePoint | ||
| 7122 | // because they are treated as partial access register and cause miss assignment of register. | ||
| 7123 | ✗ | OpdSize opd_size = opd0.GetSize(); | |
| 7124 | ✗ | if (opd_size == O_SIZE_8 || opd_size == O_SIZE_16) { | |
| 7125 | ✗ | opd_size = O_SIZE_32; | |
| 7126 | } | ||
| 7127 | ✗ | const detail::Opd& opd1 = instr.GetOpd(1); | |
| 7128 | ✗ | block->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, opd0.GetType(), opd_size, opd0.reg_assignable_); | |
| 7129 | ✗ | if (opd1.IsMem()) { | |
| 7130 | ✗ | var_manager.SetSpillSlot(reg.GetType(), reg.id, Addr(opd1.GetBase(), opd1.GetDisp())); | |
| 7131 | } | ||
| 7132 | ✗ | } else if (instr.GetID() == I_COMPILER_DECLARE_STACK_ARG) { | |
| 7133 | // Declare function argument on stack | ||
| 7134 | // The register variable starts "spill" state by O_TYPE_MEM of AddUsePoint | ||
| 7135 | ✗ | const detail::Opd& opd0 = instr.GetOpd(0); // Register variable. | |
| 7136 | ✗ | const RegID& reg = opd0.GetReg(); | |
| 7137 | // Avoid passing operand size 8 or 16 to AddUsePoint | ||
| 7138 | // because they are treated as partial access register and cause miss assignment of register. | ||
| 7139 | ✗ | OpdSize opd_size = opd0.GetSize(); | |
| 7140 | ✗ | if (opd_size == O_SIZE_8 || opd_size == O_SIZE_16) { | |
| 7141 | ✗ | opd_size = O_SIZE_32; | |
| 7142 | } | ||
| 7143 | ✗ | const detail::Opd& opd1 = instr.GetOpd(1); // Argument | |
| 7144 | ✗ | block->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, static_cast<OpdType>(O_TYPE_MEM | O_TYPE_WRITE), opd_size, opd0.reg_assignable_); | |
| 7145 | ✗ | var_manager.SetSpillSlot(reg.GetType(), reg.id, Addr(opd1.GetBase(), opd1.GetDisp())); | |
| 7146 | ✗ | } else if (instr.GetID() == I_COMPILER_DECLARE_RESULT_REG) { | |
| 7147 | // Declare function result on register | ||
| 7148 | ✗ | const detail::Opd& opd0 = instr.GetOpd(0); | |
| 7149 | ✗ | const RegID& reg = opd0.GetReg(); | |
| 7150 | ✗ | block->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, opd0.GetType(), opd0.GetSize(), opd0.reg_assignable_); | |
| 7151 | ✗ | } else if (IsBreakDependenceInstr(instr)) { | |
| 7152 | // Add only 1 use point if the instruction that break register dependence | ||
| 7153 | ✗ | const detail::Opd& opd = instr.GetOpd(0); | |
| 7154 | ✗ | const RegID& reg = opd.GetReg(); | |
| 7155 | ✗ | block->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, static_cast<OpdType>(O_TYPE_REG | O_TYPE_WRITE), opd.GetSize(), opd.reg_assignable_); | |
| 7156 | ✗ | var_manager.UpdateVarSize(reg.GetType(), reg.id, opd.GetSize()); | |
| 7157 | ✗ | } else if (instr.GetID() == I_PUSHAD || instr.GetID() == I_POPAD) { | |
| 7158 | // Add use point of pushad/popad | ||
| 7159 | ✗ | const OpdType type = static_cast<OpdType>(O_TYPE_REG | (instr.GetID() == I_PUSHAD ? O_TYPE_READ : O_TYPE_WRITE)); | |
| 7160 | ✗ | block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EAX), type, O_SIZE_32, 0xFFFFFFFF); | |
| 7161 | ✗ | block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, ECX), type, O_SIZE_32, 0xFFFFFFFF); | |
| 7162 | ✗ | block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EDX), type, O_SIZE_32, 0xFFFFFFFF); | |
| 7163 | ✗ | block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EBX), type, O_SIZE_32, 0xFFFFFFFF); | |
| 7164 | ✗ | block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EBP), type, O_SIZE_32, 0xFFFFFFFF); | |
| 7165 | ✗ | block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, ESI), type, O_SIZE_32, 0xFFFFFFFF); | |
| 7166 | ✗ | block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EDI), type, O_SIZE_32, 0xFFFFFFFF); | |
| 7167 | ✗ | block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, ESP), static_cast<OpdType>(O_TYPE_REG | O_TYPE_READ | O_TYPE_WRITE), O_SIZE_32, 0xFFFFFFFF); | |
| 7168 | ✗ | } else if (instr.GetID() == I_VZEROALL || instr.GetID() == I_VZEROUPPER) { | |
| 7169 | // Add use point of vzeroall/vzeroupper | ||
| 7170 | ✗ | const OpdType type = static_cast<OpdType>(O_TYPE_REG | (instr.GetID() == I_VZEROALL ? O_TYPE_WRITE : O_TYPE_READ | O_TYPE_WRITE)); | |
| 7171 | ✗ | for (int j = 0; j < NUM_OF_PHYSICAL_REG; ++j) { | |
| 7172 | ✗ | block->GetLifetime(R_TYPE_YMM).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_YMM, static_cast<PhysicalRegID>(YMM0 + j)), type, O_SIZE_256, 0xFFFFFFFF); | |
| 7173 | } | ||
| 7174 | } else { | ||
| 7175 | // Add each use point of all operands | ||
| 7176 | ✗ | for (size_t j = 0; j < Instr::MAX_OPERAND_COUNT; ++j) { | |
| 7177 | ✗ | const detail::Opd& opd = instr.GetOpd(j); | |
| 7178 | ✗ | if (opd.IsGpReg() || opd.IsMmxReg() || opd.IsXmmReg() || opd.IsYmmReg()) { | |
| 7179 | // Register operand | ||
| 7180 | ✗ | const RegID& reg = opd.GetReg(); | |
| 7181 | ✗ | block->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, opd.GetType(), opd.GetSize(), opd.reg_assignable_); | |
| 7182 | ✗ | var_manager.UpdateVarSize(reg.GetType(), reg.id, opd.GetSize()); | |
| 7183 | ✗ | } else if (opd.IsMem()) { | |
| 7184 | // Memory operand | ||
| 7185 | ✗ | const RegID& base = opd.GetBase(); | |
| 7186 | ✗ | if (!base.IsInvalid()) { | |
| 7187 | ✗ | block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, base, static_cast<OpdType>(O_TYPE_REG | O_TYPE_READ), opd.GetAddressBaseSize(), 0xFFFFFFFF); | |
| 7188 | ✗ | var_manager.UpdateVarSize(R_TYPE_GP, base.id, opd.GetAddressBaseSize()); | |
| 7189 | } | ||
| 7190 | ✗ | const RegID& index = opd.GetIndex(); | |
| 7191 | ✗ | if (!index.IsInvalid()) { | |
| 7192 | ✗ | block->GetLifetime(index.GetType()).AddUsePoint(instr_offset, index, static_cast<OpdType>(O_TYPE_REG | O_TYPE_READ), opd.GetAddressIndexSize(), 0xFFFFFFFF); | |
| 7193 | ✗ | var_manager.UpdateVarSize(index.GetType(), index.id, opd.GetAddressIndexSize()); | |
| 7194 | } | ||
| 7195 | } | ||
| 7196 | } | ||
| 7197 | } | ||
| 7198 | } | ||
| 7199 | |||
| 7200 | // Make GEN and KILL set | ||
| 7201 | ✗ | for (size_t reg_family = 0; reg_family < 3; ++reg_family) { | |
| 7202 | ✗ | Lifetime& lifetime = block->lifetime[reg_family]; | |
| 7203 | ✗ | const size_t num_of_used_reg = lifetime.use_points.size(); | |
| 7204 | ✗ | for (size_t i = 0; i < num_of_used_reg; ++i) { | |
| 7205 | ✗ | if (!lifetime.use_points[i].empty()) { | |
| 7206 | ✗ | OpdType type = lifetime.use_points[i][0].type; | |
| 7207 | ✗ | if (type & O_TYPE_READ) { | |
| 7208 | ✗ | lifetime.gen.set_bit(i, true); // GEN | |
| 7209 | } else { | ||
| 7210 | ✗ | JITASM_ASSERT(type & O_TYPE_WRITE); | |
| 7211 | ✗ | lifetime.kill.set_bit(i, true); // KILL | |
| 7212 | } | ||
| 7213 | } | ||
| 7214 | } | ||
| 7215 | } | ||
| 7216 | |||
| 7217 | ✗ | update_target.push_back(block); | |
| 7218 | } | ||
| 7219 | |||
| 7220 | ✗ | while (!update_target.empty()) { | |
| 7221 | ✗ | BasicBlock *block = update_target.back(); | |
| 7222 | ✗ | update_target.pop_back(); | |
| 7223 | ✗ | for (size_t reg_family = 0; reg_family < 3; ++reg_family) { | |
| 7224 | ✗ | Lifetime& lifetime = block->lifetime[reg_family]; | |
| 7225 | ✗ | if (lifetime.dirty_live_out) { | |
| 7226 | // live_out is the union of the live_in of the successors | ||
| 7227 | ✗ | for (size_t i = 0; i < 2; ++i) { | |
| 7228 | ✗ | if (block->successor[i]) { | |
| 7229 | ✗ | lifetime.live_out.set_union(block->successor[i]->lifetime[reg_family].live_in); | |
| 7230 | } | ||
| 7231 | } | ||
| 7232 | ✗ | lifetime.dirty_live_out = false; | |
| 7233 | |||
| 7234 | // live_in = gen OR (live_out - kill) | ||
| 7235 | ✗ | BitVector new_live_in = lifetime.live_out; | |
| 7236 | ✗ | new_live_in.set_subtract(lifetime.kill); | |
| 7237 | ✗ | new_live_in.set_union(lifetime.gen); | |
| 7238 | |||
| 7239 | ✗ | if (!lifetime.live_in.is_equal(new_live_in)) { | |
| 7240 | ✗ | lifetime.live_in.swap(new_live_in); | |
| 7241 | |||
| 7242 | ✗ | for (size_t i = 0; i < block->predecessor.size(); ++i) { | |
| 7243 | ✗ | block->predecessor[i]->lifetime[reg_family].dirty_live_out = true; | |
| 7244 | ✗ | update_target.push_back(block->predecessor[i]); | |
| 7245 | } | ||
| 7246 | } | ||
| 7247 | ✗ | } | |
| 7248 | } | ||
| 7249 | } | ||
| 7250 | ✗ | } | |
| 7251 | |||
| 7252 | /// Linear scan register allocation | ||
| 7253 | /** | ||
| 7254 | * \param[in,out] cfg Control flow graph and additional information | ||
| 7255 | * \param[in] reg_family Register family | ||
| 7256 | * \param[in] available_reg Available physical register mask | ||
| 7257 | * \param[out] var_attrs Variable attributes | ||
| 7258 | * \return Used physical register mask | ||
| 7259 | */ | ||
| 7260 | ✗ | inline uint32 LinearScanRegisterAlloc(ControlFlowGraph& cfg, size_t reg_family, uint32 available_reg, std::vector<VarAttribute>& var_attrs) | |
| 7261 | { | ||
| 7262 | ✗ | const uint32 available_reg_count = detail::Count1Bits(available_reg); | |
| 7263 | |||
| 7264 | ✗ | std::vector<int> total_spill_cost; | |
| 7265 | ✗ | for (ControlFlowGraph::BlockList::iterator block = cfg.begin(); block != cfg.end(); ++block) { | |
| 7266 | ✗ | (*block)->lifetime[reg_family].BuildIntervals(); | |
| 7267 | ✗ | (*block)->lifetime[reg_family].GetSpillCost((*block)->GetFrequency(), total_spill_cost); | |
| 7268 | } | ||
| 7269 | |||
| 7270 | ✗ | uint32 used_reg = 0; | |
| 7271 | ✗ | const Lifetime::Interval *last_interval = NULL; | |
| 7272 | ✗ | size_t last_loop_depth = 0; | |
| 7273 | ✗ | for (ControlFlowGraph::BlockList::iterator block = cfg.dfs_begin(); block != cfg.dfs_end(); ++block) { | |
| 7274 | ✗ | Lifetime& lifetime = (*block)->lifetime[reg_family]; | |
| 7275 | ✗ | const size_t loop_depth = (*block)->loop_depth; | |
| 7276 | |||
| 7277 | // Spill identification | ||
| 7278 | ✗ | lifetime.SpillIdentification(available_reg_count, total_spill_cost, (*block)->GetFrequency(), last_loop_depth == loop_depth ? last_interval : NULL, var_attrs); | |
| 7279 | |||
| 7280 | // Register assignment | ||
| 7281 | ✗ | used_reg |= lifetime.AssignRegister(available_reg, last_interval); | |
| 7282 | |||
| 7283 | #ifdef JITASM_DEBUG_DUMP | ||
| 7284 | lifetime.DumpIntervals((*block)->depth, true); | ||
| 7285 | #endif | ||
| 7286 | ✗ | if (!lifetime.intervals.empty()) { | |
| 7287 | ✗ | last_interval = &lifetime.intervals.back(); | |
| 7288 | ✗ | last_loop_depth = loop_depth; | |
| 7289 | } | ||
| 7290 | } | ||
| 7291 | |||
| 7292 | ✗ | return used_reg; | |
| 7293 | ✗ | } | |
| 7294 | |||
| 7295 | /// General purpose register operator | ||
| 7296 | struct GpRegOperator | ||
| 7297 | { | ||
| 7298 | Frontend *f_; | ||
| 7299 | const VariableManager *var_manager_; | ||
| 7300 | |||
| 7301 | ✗ | GpRegOperator(Frontend *f, const VariableManager *var_manager) : f_(f), var_manager_(var_manager) {} | |
| 7302 | |||
| 7303 | ✗ | void Move(PhysicalRegID dst_reg, PhysicalRegID src_reg, OpdSize /*size*/) | |
| 7304 | { | ||
| 7305 | ✗ | f_->mov(Reg(dst_reg), Reg(src_reg)); | |
| 7306 | ✗ | } | |
| 7307 | |||
| 7308 | ✗ | void Swap(PhysicalRegID reg1, PhysicalRegID reg2, OpdSize /*size*/) | |
| 7309 | { | ||
| 7310 | ✗ | f_->xchg(Reg(reg1), Reg(reg2)); | |
| 7311 | ✗ | } | |
| 7312 | |||
| 7313 | ✗ | void Load(PhysicalRegID dst_reg, int var) | |
| 7314 | { | ||
| 7315 | ✗ | f_->mov(Reg(dst_reg), f_->ptr[var_manager_->GetSpillSlot(0, var)]); | |
| 7316 | ✗ | } | |
| 7317 | |||
| 7318 | ✗ | void Store(int var, PhysicalRegID src_reg) | |
| 7319 | { | ||
| 7320 | ✗ | f_->mov(f_->ptr[var_manager_->GetSpillSlot(0, var)], Reg(src_reg)); | |
| 7321 | ✗ | } | |
| 7322 | }; | ||
| 7323 | |||
| 7324 | /// MMX register operator | ||
| 7325 | struct MmxRegOperator | ||
| 7326 | { | ||
| 7327 | Frontend *f_; | ||
| 7328 | const VariableManager *var_manager_; | ||
| 7329 | |||
| 7330 | ✗ | MmxRegOperator(Frontend *f, const VariableManager *var_manager) : f_(f), var_manager_(var_manager) {} | |
| 7331 | |||
| 7332 | ✗ | void Move(PhysicalRegID dst_reg, PhysicalRegID src_reg, OpdSize /*size*/) | |
| 7333 | { | ||
| 7334 | ✗ | f_->movq(MmxReg(dst_reg), MmxReg(src_reg)); | |
| 7335 | ✗ | } | |
| 7336 | |||
| 7337 | ✗ | void Swap(PhysicalRegID reg1, PhysicalRegID reg2, OpdSize /*size*/) | |
| 7338 | { | ||
| 7339 | ✗ | f_->pxor(MmxReg(reg1), MmxReg(reg2)); | |
| 7340 | ✗ | f_->pxor(MmxReg(reg2), MmxReg(reg1)); | |
| 7341 | ✗ | f_->pxor(MmxReg(reg1), MmxReg(reg2)); | |
| 7342 | ✗ | } | |
| 7343 | |||
| 7344 | ✗ | void Load(PhysicalRegID dst_reg, int var) | |
| 7345 | { | ||
| 7346 | ✗ | f_->movq(MmxReg(dst_reg), f_->mmword_ptr[var_manager_->GetSpillSlot(1, var)]); | |
| 7347 | ✗ | } | |
| 7348 | |||
| 7349 | ✗ | void Store(int var, PhysicalRegID src_reg) | |
| 7350 | { | ||
| 7351 | ✗ | f_->movq(f_->mmword_ptr[var_manager_->GetSpillSlot(1, var)], MmxReg(src_reg)); | |
| 7352 | ✗ | } | |
| 7353 | }; | ||
| 7354 | |||
| 7355 | /// XMM/YMM register operator | ||
| 7356 | struct XmmRegOperator | ||
| 7357 | { | ||
| 7358 | Frontend *f_; | ||
| 7359 | const VariableManager *var_manager_; | ||
| 7360 | |||
| 7361 | ✗ | XmmRegOperator(Frontend *f, const VariableManager *var_manager) : f_(f), var_manager_(var_manager) {} | |
| 7362 | |||
| 7363 | ✗ | void Move(PhysicalRegID dst_reg, PhysicalRegID src_reg, OpdSize size) | |
| 7364 | { | ||
| 7365 | ✗ | if (size == O_SIZE_128) { | |
| 7366 | ✗ | if (f_->avx_epilog_) // PF AVS+ anti AVX-SSE2 penalty | |
| 7367 | ✗ | f_->vmovaps(XmmReg(dst_reg), XmmReg(src_reg)); | |
| 7368 | else | ||
| 7369 | ✗ | f_->movaps(XmmReg(dst_reg), XmmReg(src_reg)); | |
| 7370 | ✗ | } else if (size == O_SIZE_256) { | |
| 7371 | ✗ | f_->vmovaps(YmmReg(dst_reg), YmmReg(src_reg)); | |
| 7372 | } else { | ||
| 7373 | ✗ | JITASM_ASSERT(0); | |
| 7374 | } | ||
| 7375 | ✗ | } | |
| 7376 | |||
| 7377 | ✗ | void Swap(PhysicalRegID reg1, PhysicalRegID reg2, OpdSize size) | |
| 7378 | { | ||
| 7379 | ✗ | if (size == O_SIZE_128) { | |
| 7380 | ✗ | if (f_->avx_epilog_) { // PF AVS+ anti AVX-SSE2 penalty | |
| 7381 | ✗ | f_->vxorps(XmmReg(reg1), XmmReg(reg1), XmmReg(reg2)); | |
| 7382 | ✗ | f_->vxorps(XmmReg(reg2), XmmReg(reg2), XmmReg(reg1)); | |
| 7383 | ✗ | f_->vxorps(XmmReg(reg1), XmmReg(reg1), XmmReg(reg2)); | |
| 7384 | } else { | ||
| 7385 | ✗ | f_->xorps(XmmReg(reg1), XmmReg(reg2)); | |
| 7386 | ✗ | f_->xorps(XmmReg(reg2), XmmReg(reg1)); | |
| 7387 | ✗ | f_->xorps(XmmReg(reg1), XmmReg(reg2)); | |
| 7388 | } | ||
| 7389 | ✗ | } else if (size == O_SIZE_256) { | |
| 7390 | ✗ | f_->vxorps(YmmReg(reg1), YmmReg(reg1), YmmReg(reg2)); | |
| 7391 | ✗ | f_->vxorps(YmmReg(reg2), YmmReg(reg1), YmmReg(reg2)); | |
| 7392 | ✗ | f_->vxorps(YmmReg(reg1), YmmReg(reg1), YmmReg(reg2)); | |
| 7393 | } else { | ||
| 7394 | ✗ | JITASM_ASSERT(0); | |
| 7395 | } | ||
| 7396 | ✗ | } | |
| 7397 | |||
| 7398 | ✗ | void Load(PhysicalRegID dst_reg, int var) | |
| 7399 | { | ||
| 7400 | ✗ | const OpdSize size = var_manager_->GetVarSize(2, var); | |
| 7401 | ✗ | if (size == O_SIZE_128) { | |
| 7402 | ✗ | if (f_->avx_epilog_) // PF AVS+ anti AVX-SSE2 penalty | |
| 7403 | ✗ | f_->vmovaps(XmmReg(dst_reg), f_->xmmword_ptr[var_manager_->GetSpillSlot(2, var)]); | |
| 7404 | else | ||
| 7405 | ✗ | f_->movaps(XmmReg(dst_reg), f_->xmmword_ptr[var_manager_->GetSpillSlot(2, var)]); | |
| 7406 | ✗ | } else if (size == O_SIZE_256) { | |
| 7407 | ✗ | f_->vmovaps(YmmReg(dst_reg), f_->ymmword_ptr[var_manager_->GetSpillSlot(2, var)]); | |
| 7408 | } else { | ||
| 7409 | ✗ | JITASM_ASSERT(0); | |
| 7410 | } | ||
| 7411 | ✗ | } | |
| 7412 | |||
| 7413 | ✗ | void Store(int var, PhysicalRegID src_reg) | |
| 7414 | { | ||
| 7415 | ✗ | const OpdSize size = var_manager_->GetVarSize(2, var); | |
| 7416 | ✗ | if (size == O_SIZE_128) { | |
| 7417 | ✗ | if (f_->avx_epilog_) // PF AVS+ anti AVX-SSE2 penalty | |
| 7418 | ✗ | f_->vmovaps(f_->xmmword_ptr[var_manager_->GetSpillSlot(2, var)], XmmReg(src_reg)); | |
| 7419 | else | ||
| 7420 | ✗ | f_->movaps(f_->xmmword_ptr[var_manager_->GetSpillSlot(2, var)], XmmReg(src_reg)); | |
| 7421 | ✗ | } else if (size == O_SIZE_256) { | |
| 7422 | ✗ | f_->vmovaps(f_->ymmword_ptr[var_manager_->GetSpillSlot(2, var)], YmmReg(src_reg)); | |
| 7423 | } else { | ||
| 7424 | ✗ | JITASM_ASSERT(0); | |
| 7425 | } | ||
| 7426 | ✗ | } | |
| 7427 | }; | ||
| 7428 | |||
| 7429 | /// Strongly connected components finder | ||
| 7430 | /** | ||
| 7431 | * Tarjan's algorithm | ||
| 7432 | */ | ||
| 7433 | class SCCFinder { | ||
| 7434 | private: | ||
| 7435 | struct Node { | ||
| 7436 | int index; | ||
| 7437 | int lowlink; | ||
| 7438 | ✗ | Node() : index(-1) {} | |
| 7439 | }; | ||
| 7440 | Node nodes_[NUM_OF_PHYSICAL_REG]; | ||
| 7441 | int *successors_; | ||
| 7442 | int index; | ||
| 7443 | FixedArray<int, NUM_OF_PHYSICAL_REG> scc_; | ||
| 7444 | |||
| 7445 | /// Is v in scc_? | ||
| 7446 | ✗ | bool IsInsideSCC(int v) const | |
| 7447 | { | ||
| 7448 | ✗ | for (size_t i = 0; i < scc_.size(); ++i) { | |
| 7449 | ✗ | if (scc_[i] == v) {return true;} | |
| 7450 | } | ||
| 7451 | ✗ | return false; | |
| 7452 | } | ||
| 7453 | |||
| 7454 | ✗ | template<class Fn> void Find(int v, Fn& fn) | |
| 7455 | { | ||
| 7456 | ✗ | nodes_[v].index = index; | |
| 7457 | ✗ | nodes_[v].lowlink = index; | |
| 7458 | ✗ | ++index; | |
| 7459 | ✗ | scc_.push_back(v); | |
| 7460 | ✗ | const int w = successors_[v]; | |
| 7461 | ✗ | if (w != -1) { | |
| 7462 | ✗ | if (nodes_[w].index == -1) { | |
| 7463 | // successor w has not been visited yet | ||
| 7464 | ✗ | Find(w, fn); | |
| 7465 | ✗ | if (nodes_[w].lowlink < nodes_[v].lowlink) { | |
| 7466 | ✗ | nodes_[v].lowlink = nodes_[w].lowlink; | |
| 7467 | } | ||
| 7468 | ✗ | } else if (IsInsideSCC(w)) { | |
| 7469 | // successor w is in scc_ | ||
| 7470 | ✗ | if (nodes_[w].index < nodes_[v].lowlink) { | |
| 7471 | ✗ | nodes_[v].lowlink = nodes_[w].index; | |
| 7472 | } | ||
| 7473 | } | ||
| 7474 | } | ||
| 7475 | ✗ | if (nodes_[v].lowlink == nodes_[v].index && !scc_.empty()) { | |
| 7476 | // v is the root of scc_ | ||
| 7477 | ✗ | size_t i = 0; | |
| 7478 | ✗ | while (scc_[i] != v) {++i;} | |
| 7479 | ✗ | fn(&scc_[i], scc_.size() - i); | |
| 7480 | ✗ | while (i < scc_.size()) {scc_.pop_back();} | |
| 7481 | } | ||
| 7482 | ✗ | } | |
| 7483 | |||
| 7484 | public: | ||
| 7485 | ✗ | SCCFinder(int *successors) : successors_(successors), index(0) {} | |
| 7486 | |||
| 7487 | ✗ | template<class Fn> void operator()(Fn fn) | |
| 7488 | { | ||
| 7489 | ✗ | for (int v = 0; v < NUM_OF_PHYSICAL_REG; ++v) { | |
| 7490 | ✗ | if (successors_[v] != -1 && nodes_[v].index == -1) { | |
| 7491 | ✗ | Find(v, fn); | |
| 7492 | } | ||
| 7493 | } | ||
| 7494 | ✗ | } | |
| 7495 | }; | ||
| 7496 | |||
| 7497 | struct Operations { | ||
| 7498 | int move[NUM_OF_PHYSICAL_REG]; | ||
| 7499 | int load[NUM_OF_PHYSICAL_REG]; | ||
| 7500 | int store[NUM_OF_PHYSICAL_REG]; | ||
| 7501 | OpdSize size[NUM_OF_PHYSICAL_REG]; | ||
| 7502 | std::pair<const Lifetime::Interval *, const Lifetime::Interval *> interval; | ||
| 7503 | const std::vector<VarAttribute> *var_attrs; | ||
| 7504 | |||
| 7505 | ✗ | Operations(const Lifetime::Interval *first, const Lifetime::Interval *second, const std::vector<VarAttribute> *vattrs) : interval(first, second), var_attrs(vattrs) { | |
| 7506 | ✗ | for (size_t i = 0; i < NUM_OF_PHYSICAL_REG; ++i) {move[i] = load[i] = store[i] = -1;} | |
| 7507 | ✗ | } | |
| 7508 | |||
| 7509 | ✗ | void operator()(size_t var) { | |
| 7510 | ✗ | if (interval.second->liveness.get_bit(var)) { | |
| 7511 | ✗ | const bool first_spill = interval.first->spill.get_bit(var); | |
| 7512 | ✗ | const bool second_spill = interval.second->spill.get_bit(var); | |
| 7513 | ✗ | if (!first_spill) { | |
| 7514 | ✗ | const int first_reg = interval.first->assignment_table[var]; | |
| 7515 | ✗ | if (!second_spill) { | |
| 7516 | // register -> register | ||
| 7517 | ✗ | move[first_reg] = interval.second->assignment_table[var]; | |
| 7518 | ✗ | size[first_reg] = static_cast<OpdSize>(var_attrs->at(var).size); | |
| 7519 | } else { | ||
| 7520 | // register -> stack | ||
| 7521 | ✗ | store[first_reg] = static_cast<int>(var); | |
| 7522 | } | ||
| 7523 | } else { | ||
| 7524 | ✗ | if (!second_spill) { | |
| 7525 | // stack -> register | ||
| 7526 | ✗ | load[interval.second->assignment_table[var]] = static_cast<int>(var); | |
| 7527 | } else { | ||
| 7528 | // stack -> stack | ||
| 7529 | // do nothing | ||
| 7530 | } | ||
| 7531 | } | ||
| 7532 | } | ||
| 7533 | ✗ | } | |
| 7534 | }; | ||
| 7535 | |||
| 7536 | |||
| 7537 | template<class RegOp> | ||
| 7538 | struct MoveGenerator { | ||
| 7539 | int *moves_; | ||
| 7540 | OpdSize *sizes_; | ||
| 7541 | RegOp *reg_operator_; | ||
| 7542 | ✗ | MoveGenerator(int *moves, OpdSize *sizes, RegOp *reg_operator) : moves_(moves), sizes_(sizes), reg_operator_(reg_operator) {} | |
| 7543 | ✗ | void operator()(const int *scc, size_t count) { | |
| 7544 | ✗ | if (count > 1) { | |
| 7545 | ✗ | std::vector<std::pair<int, int>> real_moves; // PF 20171210 track real register usage | |
| 7546 | ✗ | for (size_t i = 0; i < count - 1; ++i) { | |
| 7547 | ✗ | const int r = scc[i]; | |
| 7548 | ✗ | JITASM_ASSERT(r != moves_[r] && moves_[r] != -1); // sanity check: cannot move to itself, cannot move to undefined | |
| 7549 | /* | ||
| 7550 | PF 20171210 track real register usage | ||
| 7551 | Old: reg_operator_->Swap(static_cast<PhysicalRegID>(moves_[r]), static_cast<PhysicalRegID>(r), sizes_[r]); | ||
| 7552 | results in wrong code for multiple xchg: does not take into account previous exchanges | ||
| 7553 | xchg edi, ecx | ||
| 7554 | xchg esi, edi | ||
| 7555 | xchg edx, esi | ||
| 7556 | new code: | ||
| 7557 | xchg edi,ecx (-> edi = _ecx, ecx = _edi) | ||
| 7558 | xchg esi,ecx (-> esi = ecx (esi = _edi), ecx = _esi) | ||
| 7559 | xchg edx,ecx (-> edx = ecx (edx = _esi), ecx = _edx) | ||
| 7560 | */ | ||
| 7561 | |||
| 7562 | // When swapping registers, all register exchanges which took role in swap should be renamed | ||
| 7563 | ✗ | int _this1 = moves_[r]; | |
| 7564 | ✗ | int _this2 = r; | |
| 7565 | ✗ | for (size_t j = 0; j < real_moves.size(); j++) { | |
| 7566 | ✗ | int _test_this1 = real_moves[j].first; | |
| 7567 | ✗ | int _test_this2 = real_moves[j].second; | |
| 7568 | ✗ | if (_this1 == _test_this1) | |
| 7569 | ✗ | _this1 = _test_this2; | |
| 7570 | ✗ | else if (_this1 == _test_this2) | |
| 7571 | ✗ | _this1 = _test_this1; | |
| 7572 | ✗ | if (_this2 == _test_this1) | |
| 7573 | ✗ | _this2 = _test_this2; | |
| 7574 | ✗ | else if (_this2 == _test_this2) | |
| 7575 | ✗ | _this2 = _test_this1; | |
| 7576 | } | ||
| 7577 | ✗ | real_moves.push_back(std::make_pair(_this1, _this2)); | |
| 7578 | ✗ | reg_operator_->Swap(static_cast<PhysicalRegID>(_this1), static_cast<PhysicalRegID>(_this2), sizes_[_this2]); | |
| 7579 | |||
| 7580 | JITASM_TRACE("Swap%d %d <-> %d\n", sizes_[r], moves_[r], r); | ||
| 7581 | } | ||
| 7582 | ✗ | } else if (moves_[scc[0]] != scc[0] && moves_[scc[0]] != -1) { | |
| 7583 | ✗ | const int r = scc[0]; | |
| 7584 | ✗ | reg_operator_->Move(static_cast<PhysicalRegID>(moves_[r]), static_cast<PhysicalRegID>(r), sizes_[r]); | |
| 7585 | JITASM_TRACE("Move%d %d -> %d\n", sizes_[r], r, moves_[r]); | ||
| 7586 | } | ||
| 7587 | ✗ | } | |
| 7588 | }; | ||
| 7589 | |||
| 7590 | /// Generate inter-interval instructions | ||
| 7591 | /** | ||
| 7592 | * - Move register | ||
| 7593 | * - Load from stack slot | ||
| 7594 | * - Store to stack slot | ||
| 7595 | */ | ||
| 7596 | template<class RegOp> | ||
| 7597 | ✗ | inline void GenerateInterIntervalInstr(const Lifetime::Interval& first_interval, const Lifetime::Interval& second_interval, const std::vector<VarAttribute>& var_attrs, RegOp reg_operator) | |
| 7598 | { | ||
| 7599 | #ifdef JITASM_DEBUG_DUMP | ||
| 7600 | first_interval.Dump(true); | ||
| 7601 | #endif | ||
| 7602 | |||
| 7603 | ✗ | Operations ops(&first_interval, &second_interval, &var_attrs); | |
| 7604 | ✗ | first_interval.liveness.query_bit_indexes(ops); | |
| 7605 | |||
| 7606 | // Store instructions | ||
| 7607 | ✗ | for (size_t r = 0; r < NUM_OF_PHYSICAL_REG; ++r) { | |
| 7608 | ✗ | if (ops.store[r] != -1) { | |
| 7609 | ✗ | reg_operator.Store(ops.store[r], static_cast<PhysicalRegID>(r)); | |
| 7610 | JITASM_TRACE("Store %d (physical reg %d)\n", ops.store[r], r); | ||
| 7611 | } | ||
| 7612 | } | ||
| 7613 | |||
| 7614 | // Move instructions | ||
| 7615 | ✗ | SCCFinder scc_finder(ops.move); | |
| 7616 | ✗ | scc_finder(MoveGenerator<RegOp>(ops.move, ops.size, ®_operator)); | |
| 7617 | |||
| 7618 | // Load instructions | ||
| 7619 | ✗ | for (size_t r = 0; r < NUM_OF_PHYSICAL_REG; ++r) { | |
| 7620 | ✗ | if (ops.load[r] != -1) { | |
| 7621 | ✗ | reg_operator.Load(static_cast<PhysicalRegID>(r), ops.load[r]); | |
| 7622 | JITASM_TRACE("Load %d (physical reg %d)\n", ops.load[r], r); | ||
| 7623 | } | ||
| 7624 | } | ||
| 7625 | |||
| 7626 | #ifdef JITASM_DEBUG_DUMP | ||
| 7627 | second_interval.Dump(true); | ||
| 7628 | #endif | ||
| 7629 | ✗ | } | |
| 7630 | |||
| 7631 | /// Generate inter-block instructions | ||
| 7632 | ✗ | inline void GenerateInterBlockInstr(const BasicBlock *first_block, const BasicBlock *second_block, Frontend& f, const VariableManager& var_manager) | |
| 7633 | { | ||
| 7634 | ✗ | if (!first_block->lifetime[0].intervals.empty() && !second_block->lifetime[0].intervals.empty()) { | |
| 7635 | JITASM_TRACE("---- General purpose register ----\n"); | ||
| 7636 | ✗ | GenerateInterIntervalInstr(first_block->lifetime[0].intervals.back(), second_block->lifetime[0].intervals.front(), var_manager.GetAttributes(0), GpRegOperator(&f, &var_manager)); | |
| 7637 | } | ||
| 7638 | ✗ | if (!first_block->lifetime[1].intervals.empty() && !second_block->lifetime[1].intervals.empty()) { | |
| 7639 | JITASM_TRACE("---- MMX register ----\n"); | ||
| 7640 | ✗ | GenerateInterIntervalInstr(first_block->lifetime[1].intervals.back(), second_block->lifetime[1].intervals.front(), var_manager.GetAttributes(1), MmxRegOperator(&f, &var_manager)); | |
| 7641 | } | ||
| 7642 | ✗ | if (!first_block->lifetime[2].intervals.empty() && !second_block->lifetime[2].intervals.empty()) { | |
| 7643 | JITASM_TRACE("---- XMM/YMM register ----\n"); | ||
| 7644 | ✗ | GenerateInterIntervalInstr(first_block->lifetime[2].intervals.back(), second_block->lifetime[2].intervals.front(), var_manager.GetAttributes(2), XmmRegOperator(&f, &var_manager)); | |
| 7645 | } | ||
| 7646 | ✗ | } | |
| 7647 | |||
| 7648 | /// Generate prolog instructions | ||
| 7649 | ✗ | inline void GenerateProlog(Frontend& f, const uint32 (&preserved_reg)[3], const Addr& preserved_reg_stack) | |
| 7650 | { | ||
| 7651 | ✗ | avoid_unused_warn(preserved_reg_stack); | |
| 7652 | |||
| 7653 | // Save & Make frame pointer | ||
| 7654 | ✗ | f.push(f.zbp); | |
| 7655 | ✗ | f.mov(f.zbp, f.zsp); | |
| 7656 | |||
| 7657 | ✗ | size_t stack_size = f.stack_manager_.GetSize(); | |
| 7658 | |||
| 7659 | // Save general-purpose registers | ||
| 7660 | ✗ | size_t num_of_preserved_gp_reg = 0; | |
| 7661 | ✗ | for (uint32 reg_mask = preserved_reg[0]; reg_mask != 0; ++num_of_preserved_gp_reg) { | |
| 7662 | ✗ | uint32 reg_id = detail::bit_scan_forward(reg_mask); | |
| 7663 | ✗ | f.push(Reg(static_cast<PhysicalRegID>(reg_id))); | |
| 7664 | ✗ | reg_mask &= ~(1 << reg_id); | |
| 7665 | } | ||
| 7666 | |||
| 7667 | #ifdef JITASM64 | ||
| 7668 | // rsp is 16 bytes aligned in Windows x64 | ||
| 7669 | |||
| 7670 | // Stack base | ||
| 7671 | ✗ | if (stack_size > 0) { | |
| 7672 | // do the same stack_size adjust in epilog | ||
| 7673 | ✗ | if (f.avx_epilog_) { | |
| 7674 | // general purpose registers are saved already, num_of_preserved_gp_reg*8 bytes | ||
| 7675 | // number of general purpose registers: | ||
| 7676 | // even -> rsp 16 byte aligned | ||
| 7677 | // odd -> rsp 8 byte aligned | ||
| 7678 | ✗ | f.mov(f.rbx, f.rsp); | |
| 7679 | // Now rbx becomes the pointer for saving spilled XMM6-15 (x64-compulsory) and | ||
| 7680 | // temporary storage for the local variables (reg, xmm, ymm) | ||
| 7681 | // Because we use vmovaps (aligned store/load) for ymm, 32 byte alignment needed for base | ||
| 7682 | // like and rbx, -32; ffffffffffffffe0H (r64 with imm32: sign extended) | ||
| 7683 | ✗ | f.and_(f.rbx, -32); // align 32 bytes | |
| 7684 | |||
| 7685 | // padding for keep alignment (16 bytes for rsp) | ||
| 7686 | ✗ | if (num_of_preserved_gp_reg & 1) | |
| 7687 | ✗ | stack_size += 16+8; // 8 or 24. Worst case. | |
| 7688 | else | ||
| 7689 | ✗ | stack_size += 16; // 0 or 16 Worst case. | |
| 7690 | ✗ | } else if (num_of_preserved_gp_reg & 1) { | |
| 7691 | // Copy with alignment | ||
| 7692 | ✗ | f.lea(f.rbx, f.ptr[f.rsp - 8]); | |
| 7693 | ✗ | stack_size += 8; // padding for keep alignment | |
| 7694 | } else { | ||
| 7695 | ✗ | f.mov(f.rbx, f.rsp); | |
| 7696 | } | ||
| 7697 | } | ||
| 7698 | #else | ||
| 7699 | if (stack_size > 0) { | ||
| 7700 | // Align stack pointer | ||
| 7701 | if (f.avx_epilog_) | ||
| 7702 | f.and_(f.esp, 0xFFFFFFE0); // 32 byte alignment for aligned local ymm spill register storage | ||
| 7703 | else | ||
| 7704 | f.and_(f.esp, 0xFFFFFFF0); // 16 byte alignment | ||
| 7705 | // in x86 we don't adjust stack_size here, esp is restored by ebp | ||
| 7706 | // Stack base | ||
| 7707 | f.mov(f.ebx, f.esp); | ||
| 7708 | } | ||
| 7709 | #endif | ||
| 7710 | |||
| 7711 | // Move stack pointer | ||
| 7712 | ✗ | if (stack_size > 0) { | |
| 7713 | ✗ | f.sub(f.zsp, static_cast<uint32>(stack_size)); | |
| 7714 | } | ||
| 7715 | |||
| 7716 | #ifdef JITASM64 | ||
| 7717 | // Save xmm registers | ||
| 7718 | ✗ | uint32 xmm_reg_mask = preserved_reg[2]; | |
| 7719 | ✗ | for (size_t i = 0; xmm_reg_mask != 0; ++i) { | |
| 7720 | ✗ | uint32 reg_id = detail::bit_scan_forward(xmm_reg_mask); | |
| 7721 | ✗ | if (f.avx_epilog_) // PF AVS+ anti AVX->SSE2 penalty | |
| 7722 | ✗ | f.vmovaps(f.xmmword_ptr[preserved_reg_stack + 16 * i], XmmReg(static_cast<PhysicalRegID>(reg_id))); | |
| 7723 | else | ||
| 7724 | ✗ | f.movaps(f.xmmword_ptr[preserved_reg_stack + 16 * i], XmmReg(static_cast<PhysicalRegID>(reg_id))); | |
| 7725 | ✗ | xmm_reg_mask &= ~(1 << reg_id); | |
| 7726 | } | ||
| 7727 | #endif | ||
| 7728 | ✗ | } | |
| 7729 | |||
| 7730 | /// Generate epilog instructions | ||
| 7731 | ✗ | inline void GenerateEpilog(Frontend& f, const uint32 (&preserved_reg)[3], const Addr& preserved_reg_stack) | |
| 7732 | { | ||
| 7733 | ✗ | avoid_unused_warn(preserved_reg_stack); | |
| 7734 | |||
| 7735 | ✗ | size_t stack_size = f.stack_manager_.GetSize(); | |
| 7736 | ✗ | const size_t num_of_preserved_gp_reg = detail::Count1Bits(preserved_reg[0]); | |
| 7737 | |||
| 7738 | #ifdef JITASM64 | ||
| 7739 | // Restore xmm registers | ||
| 7740 | // Push the register id and index by saved order | ||
| 7741 | ✗ | FixedArray<uint32, 16> regs; | |
| 7742 | ✗ | for (uint32 reg_mask = preserved_reg[2]; reg_mask != 0; ) { | |
| 7743 | ✗ | uint32 reg_id = detail::bit_scan_forward(reg_mask); | |
| 7744 | ✗ | regs.push_back(reg_id); | |
| 7745 | ✗ | reg_mask &= ~(1 << reg_id); | |
| 7746 | } | ||
| 7747 | |||
| 7748 | // Insert restore instruction by inverse order | ||
| 7749 | ✗ | while (!regs.empty()) { | |
| 7750 | // PF AVS+: generate vmovaps to avoid AVX->SSE2 penalty | ||
| 7751 | ✗ | if (f.avx_epilog_) | |
| 7752 | ✗ | f.vmovaps(XmmReg(static_cast<PhysicalRegID>(regs.back())), f.xmmword_ptr[preserved_reg_stack + 16 * (regs.size() - 1)]); | |
| 7753 | else | ||
| 7754 | ✗ | f.movaps(XmmReg(static_cast<PhysicalRegID>(regs.back())), f.xmmword_ptr[preserved_reg_stack + 16 * (regs.size() - 1)]); | |
| 7755 | ✗ | regs.pop_back(); | |
| 7756 | } | ||
| 7757 | |||
| 7758 | // Move stack pointer | ||
| 7759 | ✗ | if (stack_size > 0) { | |
| 7760 | // same calculation like in prolog | ||
| 7761 | ✗ | if (f.avx_epilog_) { | |
| 7762 | ✗ | if (num_of_preserved_gp_reg & 1) | |
| 7763 | ✗ | stack_size += 16 + 8; // 8 or 24. Worst case. | |
| 7764 | else | ||
| 7765 | ✗ | stack_size += 16; // 0 or 16 Worst case. | |
| 7766 | ✗ | } else if (num_of_preserved_gp_reg & 1) { | |
| 7767 | ✗ | stack_size += 8; // padding for keep alignment | |
| 7768 | } | ||
| 7769 | ✗ | f.add(f.zsp, static_cast<uint32>(stack_size)); | |
| 7770 | } | ||
| 7771 | #else | ||
| 7772 | // Move stack pointer | ||
| 7773 | if (stack_size > 0) { | ||
| 7774 | f.lea(f.zsp, f.ptr[f.zbp - num_of_preserved_gp_reg * 4]); | ||
| 7775 | } | ||
| 7776 | #endif | ||
| 7777 | |||
| 7778 | // Restore general-purpose registers | ||
| 7779 | ✗ | for (uint32 reg_mask = preserved_reg[0]; reg_mask != 0; ) { | |
| 7780 | ✗ | uint32 reg_id = detail::bit_scan_reverse(reg_mask); | |
| 7781 | ✗ | f.pop(Reg(static_cast<PhysicalRegID>(reg_id))); | |
| 7782 | ✗ | reg_mask &= ~(1 << reg_id); | |
| 7783 | } | ||
| 7784 | |||
| 7785 | // Restore frame pointer | ||
| 7786 | ✗ | f.pop(f.zbp); | |
| 7787 | // PF AVS+: avoid AVX->SSE2 penalty | ||
| 7788 | ✗ | if(f.avx_epilog_) | |
| 7789 | ✗ | f.vzeroupper(); | |
| 7790 | ✗ | f.ret(); | |
| 7791 | ✗ | } | |
| 7792 | |||
| 7793 | struct OrderedLabel { | ||
| 7794 | size_t id; | ||
| 7795 | size_t instr_idx; | ||
| 7796 | ✗ | OrderedLabel(size_t id_, size_t instr_idx_) : id(id_), instr_idx(instr_idx_) {} | |
| 7797 | ✗ | bool operator<(const OrderedLabel& rhs) const {return instr_idx < rhs.instr_idx;} | |
| 7798 | }; | ||
| 7799 | |||
| 7800 | /// Rewrite instructions | ||
| 7801 | /** | ||
| 7802 | * - Replace symbolic register to physical register | ||
| 7803 | * - Generate instructions for register move and spill | ||
| 7804 | * - Generate function prolog and epilog | ||
| 7805 | */ | ||
| 7806 | ✗ | inline void RewriteInstructions(Frontend& f, const ControlFlowGraph& cfg, const VariableManager& var_manager, const uint32 (&preserved_reg)[3], const Addr& preserved_reg_stack) | |
| 7807 | { | ||
| 7808 | // Prepare instruction number ordered labels for adjusting label position | ||
| 7809 | ✗ | std::vector<OrderedLabel> orderd_labels; // instruction number order | |
| 7810 | ✗ | orderd_labels.reserve(f.labels_.size()); | |
| 7811 | ✗ | for (size_t i = 0; i < f.labels_.size(); ++i) { | |
| 7812 | ✗ | orderd_labels.push_back(OrderedLabel(i, f.labels_[i].instr_number)); | |
| 7813 | } | ||
| 7814 | ✗ | std::sort(orderd_labels.begin(), orderd_labels.end()); | |
| 7815 | ✗ | std::vector<OrderedLabel>::iterator cur_label = orderd_labels.begin(); | |
| 7816 | |||
| 7817 | // Move original instruction list | ||
| 7818 | // Now the instruction list in Frontend is empty! | ||
| 7819 | ✗ | Frontend::InstrList org_instrs; | |
| 7820 | ✗ | org_instrs.swap(f.instrs_); | |
| 7821 | ✗ | f.instrs_.reserve(org_instrs.size()); | |
| 7822 | |||
| 7823 | ✗ | for (ControlFlowGraph::BlockList::const_iterator it = cfg.begin(); it != cfg.end(); ++it) { | |
| 7824 | ✗ | const BasicBlock *block = *it; | |
| 7825 | JITASM_TRACE("\n==== Block%d ====\n", block->depth); | ||
| 7826 | ✗ | if (block->depth == (size_t)-1) { | |
| 7827 | // Eliminate unreachable code block | ||
| 7828 | JITASM_TRACE("Unreachable block!\n"); | ||
| 7829 | |||
| 7830 | // Invalidate labels in this block | ||
| 7831 | ✗ | while (cur_label != orderd_labels.end() && cur_label->instr_idx < block->instr_end) { | |
| 7832 | ✗ | f.labels_[cur_label->id].instr_number = (size_t)-1; | |
| 7833 | ++cur_label; | ||
| 7834 | } | ||
| 7835 | |||
| 7836 | ✗ | continue; | |
| 7837 | } | ||
| 7838 | |||
| 7839 | // Initialize interval_range | ||
| 7840 | ✗ | detail::ConstRange< std::vector<Lifetime::Interval> > interval_range[3]; | |
| 7841 | ✗ | for (size_t reg_family = 0; reg_family < 3; ++reg_family) { | |
| 7842 | ✗ | interval_range[reg_family].first = block->lifetime[reg_family].intervals.begin(); | |
| 7843 | ✗ | interval_range[reg_family].second = block->lifetime[reg_family].intervals.end(); | |
| 7844 | } | ||
| 7845 | |||
| 7846 | ✗ | const size_t instr_size = block->instr_end - block->instr_begin; | |
| 7847 | ✗ | for (size_t instr_offset = 0; instr_offset < instr_size; ++instr_offset) { | |
| 7848 | ✗ | const size_t org_instr_index = block->instr_begin + instr_offset; | |
| 7849 | |||
| 7850 | // Step each intervals and insert inter-interval instructions | ||
| 7851 | ✗ | if (interval_range[0].size() > 1 && detail::next(interval_range[0].first)->instr_idx_offset == instr_offset) { | |
| 7852 | JITASM_TRACE("---- General purpose register ----\n"); | ||
| 7853 | ✗ | const Lifetime::Interval& first_interval = *interval_range[0].first; | |
| 7854 | ✗ | GenerateInterIntervalInstr(first_interval, *++interval_range[0].first, var_manager.GetAttributes(0), GpRegOperator(&f, &var_manager)); | |
| 7855 | } | ||
| 7856 | ✗ | if (interval_range[1].size() > 1 && detail::next(interval_range[1].first)->instr_idx_offset == instr_offset) { | |
| 7857 | JITASM_TRACE("---- MMX register ----\n"); | ||
| 7858 | ✗ | const Lifetime::Interval& first_interval = *interval_range[1].first; | |
| 7859 | ✗ | GenerateInterIntervalInstr(first_interval, *++interval_range[1].first, var_manager.GetAttributes(1), MmxRegOperator(&f, &var_manager)); | |
| 7860 | } | ||
| 7861 | ✗ | if (interval_range[2].size() > 1 && detail::next(interval_range[2].first)->instr_idx_offset == instr_offset) { | |
| 7862 | JITASM_TRACE("---- XMM/YMM register ----\n"); | ||
| 7863 | ✗ | const Lifetime::Interval& first_interval = *interval_range[2].first; | |
| 7864 | ✗ | GenerateInterIntervalInstr(first_interval, *++interval_range[2].first, var_manager.GetAttributes(2), XmmRegOperator(&f, &var_manager)); | |
| 7865 | } | ||
| 7866 | |||
| 7867 | ✗ | const size_t cur_instr_index = f.instrs_.size(); | |
| 7868 | ✗ | const InstrID instr_id = org_instrs[org_instr_index].GetID(); | |
| 7869 | ✗ | if (instr_id == I_COMPILER_DECLARE_REG_ARG || instr_id == I_COMPILER_DECLARE_STACK_ARG || instr_id == I_COMPILER_DECLARE_RESULT_REG) { | |
| 7870 | // No actual machine code | ||
| 7871 | ✗ | } else if (instr_id == I_COMPILER_PROLOG) { | |
| 7872 | // Generate function prolog | ||
| 7873 | ✗ | GenerateProlog(f, preserved_reg, preserved_reg_stack); | |
| 7874 | ✗ | } else if (instr_id == I_COMPILER_EPILOG) { | |
| 7875 | // Generate function epilog | ||
| 7876 | ✗ | GenerateEpilog(f, preserved_reg, preserved_reg_stack); | |
| 7877 | } else { | ||
| 7878 | // Copy instruction | ||
| 7879 | ✗ | f.instrs_.push_back(org_instrs[org_instr_index]); | |
| 7880 | ✗ | Instr &instr = f.instrs_.back(); | |
| 7881 | |||
| 7882 | // Replace symbolic register to physical register | ||
| 7883 | ✗ | for (size_t i = 0; i < Instr::MAX_OPERAND_COUNT; ++i) { | |
| 7884 | ✗ | detail::Opd& opd = instr.GetOpd(i); | |
| 7885 | ✗ | if (opd.IsReg()) { | |
| 7886 | ✗ | if (opd.reg_.IsSymbolic()) { | |
| 7887 | ✗ | opd.reg_.type = static_cast<RegType>(opd.reg_.type - R_TYPE_SYMBOLIC_GP); | |
| 7888 | ✗ | opd.reg_.id = interval_range[GetRegFamily(opd.reg_.GetType())].first->assignment_table[opd.reg_.id]; | |
| 7889 | } | ||
| 7890 | ✗ | } else if (opd.IsMem()) { | |
| 7891 | ✗ | if (opd.base_.IsSymbolic()) { | |
| 7892 | ✗ | opd.base_.type = R_TYPE_GP; | |
| 7893 | ✗ | opd.base_.id = interval_range[0].first->assignment_table[opd.base_.id]; | |
| 7894 | } | ||
| 7895 | ✗ | if (opd.index_.IsSymbolic()) { | |
| 7896 | ✗ | if (opd.index_.type == R_TYPE_SYMBOLIC_GP) opd.index_.type = R_TYPE_GP; | |
| 7897 | ✗ | else if (opd.index_.type == R_TYPE_SYMBOLIC_XMM) opd.index_.type = R_TYPE_XMM; | |
| 7898 | ✗ | else { JITASM_ASSERT(opd.index_.type == R_TYPE_SYMBOLIC_YMM); opd.index_.type = R_TYPE_YMM; } | |
| 7899 | ✗ | opd.index_.id = interval_range[GetRegFamily(opd.index_.GetType())].first->assignment_table[opd.index_.id]; | |
| 7900 | } | ||
| 7901 | } | ||
| 7902 | } | ||
| 7903 | } | ||
| 7904 | |||
| 7905 | // Adjust label position | ||
| 7906 | ✗ | while (cur_label != orderd_labels.end() && cur_label->instr_idx == org_instr_index) { | |
| 7907 | ✗ | f.labels_[cur_label->id].instr_number += cur_instr_index - org_instr_index; | |
| 7908 | ++cur_label; | ||
| 7909 | } | ||
| 7910 | } | ||
| 7911 | |||
| 7912 | // Generate inter-block instructions | ||
| 7913 | ✗ | JITASM_ASSERT(!(!block->successor[0] && block->successor[1])); | |
| 7914 | ✗ | if (block->successor[0] && !block->successor[1]) { | |
| 7915 | // 1 successor | ||
| 7916 | |||
| 7917 | // Remove last instruction if it is jump | ||
| 7918 | ✗ | Instr jump_instr(I_NOP, 0, 0); | |
| 7919 | ✗ | if (Frontend::IsJump(f.instrs_.back().GetID())) { | |
| 7920 | ✗ | jump_instr = f.instrs_.back(); | |
| 7921 | ✗ | f.instrs_.pop_back(); | |
| 7922 | } | ||
| 7923 | |||
| 7924 | JITASM_TRACE("==== Edge to Block%d\n", block->successor[0]->depth); | ||
| 7925 | ✗ | GenerateInterBlockInstr(block, block->successor[0], f, var_manager); | |
| 7926 | |||
| 7927 | // Add last instruction if it is jump | ||
| 7928 | ✗ | if (Frontend::IsJump(jump_instr.GetID())) { | |
| 7929 | ✗ | f.instrs_.push_back(jump_instr); | |
| 7930 | } | ||
| 7931 | ✗ | } else if (block->successor[0] && block->successor[1]) { | |
| 7932 | // 2 successors | ||
| 7933 | ✗ | JITASM_ASSERT(Frontend::IsJump(f.instrs_.back().GetID()) && f.instrs_.back().GetOpd(0).IsImm()); // the last instruction must be jump | |
| 7934 | ✗ | const size_t jump_instr_idx = f.instrs_.size() - 1; | |
| 7935 | ✗ | const size_t label_successor1 = static_cast<size_t>(f.instrs_.back().GetOpd(0).GetImm()); | |
| 7936 | |||
| 7937 | // Generate inter-block instructions between current block and successor 1 separately | ||
| 7938 | ✗ | Frontend::InstrList temp_instrs; | |
| 7939 | ✗ | temp_instrs.swap(f.instrs_); | |
| 7940 | JITASM_TRACE("==== Edge to Block%d\n", block->successor[1]->depth); | ||
| 7941 | ✗ | GenerateInterBlockInstr(block, block->successor[1], f, var_manager); | |
| 7942 | ✗ | temp_instrs.swap(f.instrs_); | |
| 7943 | |||
| 7944 | // Insert inter-block instructions between current block and successor 0 | ||
| 7945 | JITASM_TRACE("==== Edge to Block%d\n", block->successor[0]->depth); | ||
| 7946 | ✗ | GenerateInterBlockInstr(block, block->successor[0], f, var_manager); | |
| 7947 | |||
| 7948 | ✗ | if (!temp_instrs.empty()) { | |
| 7949 | // Insert inter-block instructions between current block and successor 1 and change jump flow | ||
| 7950 | |||
| 7951 | // Jump to successor0 | ||
| 7952 | ✗ | const size_t label_successor0 = f.NewLabelID(""); | |
| 7953 | ✗ | f.AppendJmp(label_successor0); | |
| 7954 | |||
| 7955 | // Change conditional jump to successor1_edge instead of successor1 | ||
| 7956 | ✗ | const size_t label_successor1_edge = f.NewLabelID(""); | |
| 7957 | ✗ | f.L(label_successor1_edge); | |
| 7958 | ✗ | Frontend::ChangeLabelID(f.instrs_[jump_instr_idx], label_successor1_edge); | |
| 7959 | |||
| 7960 | // Insert instructions | ||
| 7961 | ✗ | f.instrs_.insert(f.instrs_.end(), temp_instrs.begin(), temp_instrs.end()); | |
| 7962 | ✗ | f.AppendJmp(label_successor1); | |
| 7963 | |||
| 7964 | // Label of successor0 block | ||
| 7965 | ✗ | f.L(label_successor0); | |
| 7966 | } | ||
| 7967 | ✗ | } | |
| 7968 | } | ||
| 7969 | ✗ | } | |
| 7970 | |||
| 7971 | /// Compile | ||
| 7972 | ✗ | inline void Compile(Frontend& f) | |
| 7973 | { | ||
| 7974 | #ifdef JITASM64 | ||
| 7975 | // Available registers : rax, rcx, rdx, rsi, rdi, r8 ~ r15, mm0 ~ mm7, xmm0/ymm0 ~ xmm15/ymm15 | ||
| 7976 | ✗ | const uint32 available_reg[3] = {0xFFC7, 0xFF, 0xFFFF}; | |
| 7977 | |||
| 7978 | #ifdef JITASM_WIN | ||
| 7979 | // Win64 preserved registers : rbx, rsi, rdi, r12 ~ r15, xmm6 ~ xmm15 | ||
| 7980 | uint32 preserved_reg[3] = {(1<<RBX)|(1<<RSI)|(1<<RDI)|(1<<R12)|(1<<R13)|(1<<R14)|(1<<R15), 0, 0xFFC0}; | ||
| 7981 | #else | ||
| 7982 | // x64 Linux preserved registers : rbx, r12 ~ r15, xmm6 ~ xmm15 | ||
| 7983 | ✗ | uint32 preserved_reg[3] = {(1<<RBX)|(1<<R12)|(1<<R13)|(1<<R14)|(1<<R15), 0, 0xFFC0}; | |
| 7984 | #endif | ||
| 7985 | #else | ||
| 7986 | // Available registers : eax, ecx, edx, esi, edi, mm0 ~ mm7, xmm0/ymm0 ~ xmm7/ymm7 | ||
| 7987 | const uint32 available_reg[3] = {(1<<EAX)|(1<<ECX)|(1<<EDX)|(1<<ESI)|(1<<EDI), 0xFF, 0xFF}; | ||
| 7988 | |||
| 7989 | // Preserved registers : ebx, esi, edi | ||
| 7990 | uint32 preserved_reg[3] = {(1<<EBX)|(1<<ESI)|(1<<EDI), 0, 0}; | ||
| 7991 | #endif | ||
| 7992 | |||
| 7993 | uint32 used_physical_reg[3]; | ||
| 7994 | bool need_reg_alloc[3]; | ||
| 7995 | ✗ | if (!PrepareCompile(f.instrs_, used_physical_reg, need_reg_alloc)) { | |
| 7996 | // No compile process | ||
| 7997 | ✗ | return; | |
| 7998 | } | ||
| 7999 | |||
| 8000 | ✗ | VariableManager var_manager; | |
| 8001 | ✗ | ControlFlowGraph cfg; | |
| 8002 | |||
| 8003 | ✗ | if (need_reg_alloc[0] || need_reg_alloc[1] || need_reg_alloc[2]) { | |
| 8004 | // Register allocation process | ||
| 8005 | |||
| 8006 | // Build CFG including loop detection | ||
| 8007 | ✗ | cfg.Build(f); | |
| 8008 | |||
| 8009 | // Live variable analysis | ||
| 8010 | ✗ | LiveVariableAnalysis(f, cfg, var_manager); | |
| 8011 | |||
| 8012 | // Linear scan register allocation | ||
| 8013 | ✗ | for (size_t reg_family = 0; reg_family < 3; ++reg_family) { | |
| 8014 | ✗ | if (need_reg_alloc[reg_family]) { | |
| 8015 | ✗ | used_physical_reg[reg_family] = LinearScanRegisterAlloc(cfg, reg_family, available_reg[reg_family], var_manager.GetAttributes(reg_family)); | |
| 8016 | } | ||
| 8017 | } | ||
| 8018 | ✗ | } else { | |
| 8019 | // No register allocation | ||
| 8020 | // Build dummy CFG | ||
| 8021 | ✗ | cfg.BuildDummy(f); | |
| 8022 | } | ||
| 8023 | |||
| 8024 | #ifdef JITASM_DEBUG_DUMP | ||
| 8025 | cfg.DumpDot(); | ||
| 8026 | #endif | ||
| 8027 | |||
| 8028 | // Identify saving registers | ||
| 8029 | ✗ | preserved_reg[0] &= used_physical_reg[0]; | |
| 8030 | ✗ | preserved_reg[1] &= used_physical_reg[1]; | |
| 8031 | ✗ | preserved_reg[2] &= used_physical_reg[2]; | |
| 8032 | |||
| 8033 | // Reserve stack for saving xmm register | ||
| 8034 | ✗ | Addr preserved_reg_stack(RegID::Invalid(), 0); | |
| 8035 | ✗ | if (preserved_reg[2] != 0) { | |
| 8036 | // For saving xmm registers | ||
| 8037 | ✗ | preserved_reg_stack = f.stack_manager_.Alloc(detail::Count1Bits(preserved_reg[2]) * 16, 16); | |
| 8038 | } | ||
| 8039 | |||
| 8040 | // Allocate stack for spill variable | ||
| 8041 | ✗ | var_manager.AllocSpillSlots(f.stack_manager_); | |
| 8042 | |||
| 8043 | // ebx(rbx) does not include in used_physical_reg | ||
| 8044 | // because ebx(rbx) is going to be modified in prolog. | ||
| 8045 | ✗ | if (f.stack_manager_.GetSize() > 0) { | |
| 8046 | ✗ | preserved_reg[0] |= (1 << EBX); | |
| 8047 | } | ||
| 8048 | |||
| 8049 | ✗ | RewriteInstructions(f, cfg, var_manager, preserved_reg, preserved_reg_stack); | |
| 8050 | ✗ | } | |
| 8051 | |||
| 8052 | } // namespace compiler | ||
| 8053 | |||
| 8054 | namespace detail | ||
| 8055 | { | ||
| 8056 | struct CondExpr { | ||
| 8057 | virtual void operator()(Frontend& f, size_t beg, size_t end) const = 0; | ||
| 8058 | virtual ~CondExpr() {} | ||
| 8059 | }; | ||
| 8060 | |||
| 8061 | // && | ||
| 8062 | struct CondExpr_ExprAnd : CondExpr { | ||
| 8063 | const CondExpr& lhs_; | ||
| 8064 | const CondExpr& rhs_; | ||
| 8065 | CondExpr_ExprAnd(const CondExpr& lhs, const CondExpr& rhs) : lhs_(lhs), rhs_(rhs) {} | ||
| 8066 | void operator()(Frontend& f, size_t beg, size_t end) const { | ||
| 8067 | size_t label = f.NewLabelID(""); | ||
| 8068 | lhs_(f, label, end); | ||
| 8069 | f.L(label); | ||
| 8070 | rhs_(f, beg, end); | ||
| 8071 | } | ||
| 8072 | CondExpr_ExprAnd& operator=(const CondExpr_ExprAnd&); | ||
| 8073 | }; | ||
| 8074 | |||
| 8075 | // || | ||
| 8076 | struct CondExpr_ExprOr : CondExpr { | ||
| 8077 | const CondExpr& lhs_; | ||
| 8078 | const CondExpr& rhs_; | ||
| 8079 | CondExpr_ExprOr(const CondExpr& lhs, const CondExpr& rhs) : lhs_(lhs), rhs_(rhs) {} | ||
| 8080 | void operator()(Frontend& f, size_t beg, size_t end) const { | ||
| 8081 | size_t label = f.NewLabelID(""); | ||
| 8082 | lhs_(f, beg, label); | ||
| 8083 | f.L(label); | ||
| 8084 | rhs_(f, beg, end); | ||
| 8085 | } | ||
| 8086 | CondExpr_ExprOr& operator=(const CondExpr_ExprOr&); | ||
| 8087 | }; | ||
| 8088 | |||
| 8089 | // cmp | ||
| 8090 | template<class L, class R, JumpCondition Jcc> | ||
| 8091 | struct CondExpr_Cmp : CondExpr { | ||
| 8092 | L lhs_; | ||
| 8093 | R rhs_; | ||
| 8094 | CondExpr_Cmp(const L& lhs, const R& rhs) : lhs_(lhs), rhs_(rhs) {} | ||
| 8095 | void operator()(Frontend& f, size_t beg, size_t end) const { | ||
| 8096 | f.cmp(lhs_, rhs_); | ||
| 8097 | f.AppendJcc(Jcc, beg); | ||
| 8098 | f.AppendJmp(end); | ||
| 8099 | } | ||
| 8100 | }; | ||
| 8101 | |||
| 8102 | // or | ||
| 8103 | template<class L, class R, JumpCondition Jcc> | ||
| 8104 | struct CondExpr_Or : CondExpr { | ||
| 8105 | L lhs_; | ||
| 8106 | R rhs_; | ||
| 8107 | CondExpr_Or(const L& lhs, const R& rhs) : lhs_(lhs), rhs_(rhs) {} | ||
| 8108 | void operator()(Frontend& f, size_t beg, size_t end) const { | ||
| 8109 | f.or_(lhs_, rhs_); | ||
| 8110 | f.AppendJcc(Jcc, beg); | ||
| 8111 | f.AppendJmp(end); | ||
| 8112 | } | ||
| 8113 | }; | ||
| 8114 | } | ||
| 8115 | |||
| 8116 | // && | ||
| 8117 | inline detail::CondExpr_ExprAnd operator&&(const detail::CondExpr& lhs, const detail::CondExpr& rhs) {return detail::CondExpr_ExprAnd(lhs, rhs);} | ||
| 8118 | // || | ||
| 8119 | inline detail::CondExpr_ExprOr operator||(const detail::CondExpr& lhs, const detail::CondExpr& rhs) {return detail::CondExpr_ExprOr(lhs, rhs);} | ||
| 8120 | |||
| 8121 | // ! | ||
| 8122 | inline detail::CondExpr_Or<Reg8, Reg8, JCC_E> operator!(const Reg8& lhs) {return detail::CondExpr_Or<Reg8, Reg8, JCC_E>(lhs, lhs);} | ||
| 8123 | inline detail::CondExpr_Or<Reg16, Reg16, JCC_E> operator!(const Reg16& lhs) {return detail::CondExpr_Or<Reg16, Reg16, JCC_E>(lhs, lhs);} | ||
| 8124 | inline detail::CondExpr_Or<Reg32, Reg32, JCC_E> operator!(const Reg32& lhs) {return detail::CondExpr_Or<Reg32, Reg32, JCC_E>(lhs, lhs);} | ||
| 8125 | #ifdef JITASM64 | ||
| 8126 | inline detail::CondExpr_Or<Reg64, Reg64, JCC_E> operator!(const Reg64& lhs) {return detail::CondExpr_Or<Reg64, Reg64, JCC_E>(lhs, lhs);} | ||
| 8127 | #endif | ||
| 8128 | inline detail::CondExpr_Cmp<Mem8, Imm8, JCC_E> operator!(const Mem8& lhs) {return detail::CondExpr_Cmp<Mem8, Imm8, JCC_E>(lhs, 0);} | ||
| 8129 | inline detail::CondExpr_Cmp<Mem16, Imm16, JCC_E> operator!(const Mem16& lhs) {return detail::CondExpr_Cmp<Mem16, Imm16, JCC_E>(lhs, 0);} | ||
| 8130 | inline detail::CondExpr_Cmp<Mem32, Imm32, JCC_E> operator!(const Mem32& lhs) {return detail::CondExpr_Cmp<Mem32, Imm32, JCC_E>(lhs, 0);} | ||
| 8131 | #ifdef JITASM64 | ||
| 8132 | inline detail::CondExpr_Cmp<Mem64, Imm32, JCC_E> operator!(const Mem64& lhs) {return detail::CondExpr_Cmp<Mem64, Imm32, JCC_E>(lhs, 0);} | ||
| 8133 | #endif | ||
| 8134 | |||
| 8135 | // < | ||
| 8136 | template<class R> detail::CondExpr_Cmp<Reg8, R, JCC_B> operator<(const Reg8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg8, R, JCC_B>(lhs, rhs);} | ||
| 8137 | template<class R> detail::CondExpr_Cmp<Reg16, R, JCC_B> operator<(const Reg16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg16, R, JCC_B>(lhs, rhs);} | ||
| 8138 | template<class R> detail::CondExpr_Cmp<Reg32, R, JCC_B> operator<(const Reg32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg32, R, JCC_B>(lhs, rhs);} | ||
| 8139 | #ifdef JITASM64 | ||
| 8140 | template<class R> detail::CondExpr_Cmp<Reg64, R, JCC_B> operator<(const Reg64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg64, R, JCC_B>(lhs, rhs);} | ||
| 8141 | #endif | ||
| 8142 | template<class R> detail::CondExpr_Cmp<Mem8, R, JCC_B> operator<(const Mem8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem8, R, JCC_B>(lhs, rhs);} | ||
| 8143 | template<class R> detail::CondExpr_Cmp<Mem16, R, JCC_B> operator<(const Mem16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem16, R, JCC_B>(lhs, rhs);} | ||
| 8144 | template<class R> detail::CondExpr_Cmp<Mem32, R, JCC_B> operator<(const Mem32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem32, R, JCC_B>(lhs, rhs);} | ||
| 8145 | #ifdef JITASM64 | ||
| 8146 | template<class R> detail::CondExpr_Cmp<Mem64, R, JCC_B> operator<(const Mem64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem64, R, JCC_B>(lhs, rhs);} | ||
| 8147 | #endif | ||
| 8148 | |||
| 8149 | // > | ||
| 8150 | template<class R> detail::CondExpr_Cmp<Reg8, R, JCC_A> operator>(const Reg8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg8, R, JCC_A>(lhs, rhs);} | ||
| 8151 | template<class R> detail::CondExpr_Cmp<Reg16, R, JCC_A> operator>(const Reg16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg16, R, JCC_A>(lhs, rhs);} | ||
| 8152 | template<class R> detail::CondExpr_Cmp<Reg32, R, JCC_A> operator>(const Reg32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg32, R, JCC_A>(lhs, rhs);} | ||
| 8153 | #ifdef JITASM64 | ||
| 8154 | template<class R> detail::CondExpr_Cmp<Reg64, R, JCC_A> operator>(const Reg64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg64, R, JCC_A>(lhs, rhs);} | ||
| 8155 | #endif | ||
| 8156 | template<class R> detail::CondExpr_Cmp<Mem8, R, JCC_A> operator>(const Mem8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem8, R, JCC_A>(lhs, rhs);} | ||
| 8157 | template<class R> detail::CondExpr_Cmp<Mem16, R, JCC_A> operator>(const Mem16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem16, R, JCC_A>(lhs, rhs);} | ||
| 8158 | template<class R> detail::CondExpr_Cmp<Mem32, R, JCC_A> operator>(const Mem32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem32, R, JCC_A>(lhs, rhs);} | ||
| 8159 | #ifdef JITASM64 | ||
| 8160 | template<class R> detail::CondExpr_Cmp<Mem64, R, JCC_A> operator>(const Mem64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem64, R, JCC_A>(lhs, rhs);} | ||
| 8161 | #endif | ||
| 8162 | |||
| 8163 | // <= | ||
| 8164 | template<class R> detail::CondExpr_Cmp<Reg8, R, JCC_BE> operator<=(const Reg8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg8, R, JCC_BE>(lhs, rhs);} | ||
| 8165 | template<class R> detail::CondExpr_Cmp<Reg16, R, JCC_BE> operator<=(const Reg16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg16, R, JCC_BE>(lhs, rhs);} | ||
| 8166 | template<class R> detail::CondExpr_Cmp<Reg32, R, JCC_BE> operator<=(const Reg32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg32, R, JCC_BE>(lhs, rhs);} | ||
| 8167 | #ifdef JITASM64 | ||
| 8168 | template<class R> detail::CondExpr_Cmp<Reg64, R, JCC_BE> operator<=(const Reg64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg64, R, JCC_BE>(lhs, rhs);} | ||
| 8169 | #endif | ||
| 8170 | template<class R> detail::CondExpr_Cmp<Mem8, R, JCC_BE> operator<=(const Mem8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem8, R, JCC_BE>(lhs, rhs);} | ||
| 8171 | template<class R> detail::CondExpr_Cmp<Mem16, R, JCC_BE> operator<=(const Mem16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem16, R, JCC_BE>(lhs, rhs);} | ||
| 8172 | template<class R> detail::CondExpr_Cmp<Mem32, R, JCC_BE> operator<=(const Mem32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem32, R, JCC_BE>(lhs, rhs);} | ||
| 8173 | #ifdef JITASM64 | ||
| 8174 | template<class R> detail::CondExpr_Cmp<Mem64, R, JCC_BE> operator<=(const Mem64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem64, R, JCC_BE>(lhs, rhs);} | ||
| 8175 | #endif | ||
| 8176 | |||
| 8177 | // >= | ||
| 8178 | template<class R> detail::CondExpr_Cmp<Reg8, R, JCC_AE> operator>=(const Reg8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg8, R, JCC_AE>(lhs, rhs);} | ||
| 8179 | template<class R> detail::CondExpr_Cmp<Reg16, R, JCC_AE> operator>=(const Reg16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg16, R, JCC_AE>(lhs, rhs);} | ||
| 8180 | template<class R> detail::CondExpr_Cmp<Reg32, R, JCC_AE> operator>=(const Reg32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg32, R, JCC_AE>(lhs, rhs);} | ||
| 8181 | #ifdef JITASM64 | ||
| 8182 | template<class R> detail::CondExpr_Cmp<Reg64, R, JCC_AE> operator>=(const Reg64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg64, R, JCC_AE>(lhs, rhs);} | ||
| 8183 | #endif | ||
| 8184 | template<class R> detail::CondExpr_Cmp<Mem8, R, JCC_AE> operator>=(const Mem8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem8, R, JCC_AE>(lhs, rhs);} | ||
| 8185 | template<class R> detail::CondExpr_Cmp<Mem16, R, JCC_AE> operator>=(const Mem16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem16, R, JCC_AE>(lhs, rhs);} | ||
| 8186 | template<class R> detail::CondExpr_Cmp<Mem32, R, JCC_AE> operator>=(const Mem32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem32, R, JCC_AE>(lhs, rhs);} | ||
| 8187 | #ifdef JITASM64 | ||
| 8188 | template<class R> detail::CondExpr_Cmp<Mem64, R, JCC_AE> operator>=(const Mem64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem64, R, JCC_AE>(lhs, rhs);} | ||
| 8189 | #endif | ||
| 8190 | |||
| 8191 | // == | ||
| 8192 | template<class R> detail::CondExpr_Cmp<Reg8, R, JCC_E> operator==(const Reg8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg8, R, JCC_E>(lhs, rhs);} | ||
| 8193 | template<class R> detail::CondExpr_Cmp<Reg16, R, JCC_E> operator==(const Reg16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg16, R, JCC_E>(lhs, rhs);} | ||
| 8194 | template<class R> detail::CondExpr_Cmp<Reg32, R, JCC_E> operator==(const Reg32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg32, R, JCC_E>(lhs, rhs);} | ||
| 8195 | #ifdef JITASM64 | ||
| 8196 | template<class R> detail::CondExpr_Cmp<Reg64, R, JCC_E> operator==(const Reg64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg64, R, JCC_E>(lhs, rhs);} | ||
| 8197 | #endif | ||
| 8198 | template<class R> detail::CondExpr_Cmp<Mem8, R, JCC_E> operator==(const Mem8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem8, R, JCC_E>(lhs, rhs);} | ||
| 8199 | template<class R> detail::CondExpr_Cmp<Mem16, R, JCC_E> operator==(const Mem16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem16, R, JCC_E>(lhs, rhs);} | ||
| 8200 | template<class R> detail::CondExpr_Cmp<Mem32, R, JCC_E> operator==(const Mem32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem32, R, JCC_E>(lhs, rhs);} | ||
| 8201 | #ifdef JITASM64 | ||
| 8202 | template<class R> detail::CondExpr_Cmp<Mem64, R, JCC_E> operator==(const Mem64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem64, R, JCC_E>(lhs, rhs);} | ||
| 8203 | #endif | ||
| 8204 | |||
| 8205 | // != | ||
| 8206 | template<class R> detail::CondExpr_Cmp<Reg8, R, JCC_NE> operator!=(const Reg8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg8, R, JCC_NE>(lhs, rhs);} | ||
| 8207 | template<class R> detail::CondExpr_Cmp<Reg16, R, JCC_NE> operator!=(const Reg16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg16, R, JCC_NE>(lhs, rhs);} | ||
| 8208 | template<class R> detail::CondExpr_Cmp<Reg32, R, JCC_NE> operator!=(const Reg32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg32, R, JCC_NE>(lhs, rhs);} | ||
| 8209 | #ifdef JITASM64 | ||
| 8210 | template<class R> detail::CondExpr_Cmp<Reg64, R, JCC_NE> operator!=(const Reg64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg64, R, JCC_NE>(lhs, rhs);} | ||
| 8211 | #endif | ||
| 8212 | template<class R> detail::CondExpr_Cmp<Mem8, R, JCC_NE> operator!=(const Mem8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem8, R, JCC_NE>(lhs, rhs);} | ||
| 8213 | template<class R> detail::CondExpr_Cmp<Mem16, R, JCC_NE> operator!=(const Mem16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem16, R, JCC_NE>(lhs, rhs);} | ||
| 8214 | template<class R> detail::CondExpr_Cmp<Mem32, R, JCC_NE> operator!=(const Mem32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem32, R, JCC_NE>(lhs, rhs);} | ||
| 8215 | #ifdef JITASM64 | ||
| 8216 | template<class R> detail::CondExpr_Cmp<Mem64, R, JCC_NE> operator!=(const Mem64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem64, R, JCC_NE>(lhs, rhs);} | ||
| 8217 | #endif | ||
| 8218 | |||
| 8219 | namespace detail { | ||
| 8220 | // Flags for ArgumentTraits | ||
| 8221 | enum { | ||
| 8222 | ARG_IN_REG = (1<<0), ///< Argument is stored in general purpose register. | ||
| 8223 | ARG_IN_STACK = (1<<1), ///< Argument is stored on stack. | ||
| 8224 | ARG_IN_MMX = (1<<2), ///< Argument is stored in mmx register. | ||
| 8225 | ARG_IN_XMM_SP = (1<<3), ///< Argument is stored in xmm register as single precision. | ||
| 8226 | ARG_IN_XMM_DP = (1<<4), ///< Argument is stored in xmm register as double precision. | ||
| 8227 | ARG_IN_XMM_INT = (1<<5), ///< Argument is stored in xmm register as integer. | ||
| 8228 | ARG_TYPE_VALUE = (1<<6), ///< Argument is value which is passed. | ||
| 8229 | ARG_TYPE_PTR = (1<<7) ///< Argument is pointer which is passed to. | ||
| 8230 | }; | ||
| 8231 | |||
| 8232 | /// cdecl argument type traits | ||
| 8233 | template<int N, class T, int Size = sizeof(T)> | ||
| 8234 | struct ArgTraits_cdecl { | ||
| 8235 | enum { | ||
| 8236 | stack_size = (Size + 4 - 1) / 4 * 4, | ||
| 8237 | flag = ARG_IN_STACK | ARG_TYPE_VALUE, | ||
| 8238 | reg_id = INVALID | ||
| 8239 | }; | ||
| 8240 | }; | ||
| 8241 | |||
| 8242 | #if JITASM_MMINTRIN | ||
| 8243 | // specialization for __m64 | ||
| 8244 | template<int N> struct ArgTraits_cdecl<N, __m64, 8> {enum {stack_size = 0, flag = ARG_IN_MMX | ARG_TYPE_VALUE, reg_id = MM0};}; | ||
| 8245 | #endif | ||
| 8246 | |||
| 8247 | #if JITASM_XMMINTRIN | ||
| 8248 | // specialization for __m128 | ||
| 8249 | template<int N> struct ArgTraits_cdecl<N, __m128, 16> {enum {stack_size = 0, flag = ARG_IN_XMM_SP | ARG_TYPE_VALUE, reg_id = XMM0};}; | ||
| 8250 | #endif | ||
| 8251 | |||
| 8252 | #if JITASM_EMMINTRIN | ||
| 8253 | // specialization for __m128d | ||
| 8254 | template<int N> struct ArgTraits_cdecl<N, __m128d, 16> {enum {stack_size = 0, flag = ARG_IN_XMM_DP | ARG_TYPE_VALUE, reg_id = XMM0};}; | ||
| 8255 | |||
| 8256 | // specialization for __m128i | ||
| 8257 | template<int N> struct ArgTraits_cdecl<N, __m128i, 16> {enum {stack_size = 0, flag = ARG_IN_XMM_INT | ARG_TYPE_VALUE, reg_id = XMM0};}; | ||
| 8258 | #endif | ||
| 8259 | |||
| 8260 | |||
| 8261 | /// Microsoft x64 fastcall argument type traits | ||
| 8262 | template<int N, class T, int Size = sizeof(T)> | ||
| 8263 | struct ArgTraits_win64 { | ||
| 8264 | enum { | ||
| 8265 | stack_size = 8, | ||
| 8266 | flag = ARG_IN_STACK | (Size == 1 || Size == 2 || Size == 4 || Size == 8 ? ARG_TYPE_VALUE : ARG_TYPE_PTR), | ||
| 8267 | reg_id = INVALID | ||
| 8268 | }; | ||
| 8269 | }; | ||
| 8270 | |||
| 8271 | /** | ||
| 8272 | * Base class for argument which is stored in general purpose register. | ||
| 8273 | */ | ||
| 8274 | template<int RegID, int Flag> struct ArgTraits_win64_reg { | ||
| 8275 | enum { | ||
| 8276 | stack_size = 8, | ||
| 8277 | flag = Flag, | ||
| 8278 | reg_id = RegID | ||
| 8279 | }; | ||
| 8280 | }; | ||
| 8281 | |||
| 8282 | // specialization for argument pointer stored in register | ||
| 8283 | template<class T, int Size> struct ArgTraits_win64<0, T, Size> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_PTR> {}; | ||
| 8284 | template<class T, int Size> struct ArgTraits_win64<1, T, Size> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_PTR> {}; | ||
| 8285 | template<class T, int Size> struct ArgTraits_win64<2, T, Size> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_PTR> {}; | ||
| 8286 | template<class T, int Size> struct ArgTraits_win64<3, T, Size> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_PTR> {}; | ||
| 8287 | |||
| 8288 | // specialization for 1 byte type | ||
| 8289 | template<class T> struct ArgTraits_win64<0, T, 1> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8290 | template<class T> struct ArgTraits_win64<1, T, 1> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8291 | template<class T> struct ArgTraits_win64<2, T, 1> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8292 | template<class T> struct ArgTraits_win64<3, T, 1> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8293 | |||
| 8294 | // specialization for 2 bytes type | ||
| 8295 | template<class T> struct ArgTraits_win64<0, T, 2> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8296 | template<class T> struct ArgTraits_win64<1, T, 2> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8297 | template<class T> struct ArgTraits_win64<2, T, 2> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8298 | template<class T> struct ArgTraits_win64<3, T, 2> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8299 | |||
| 8300 | // specialization for 4 bytes type | ||
| 8301 | template<class T> struct ArgTraits_win64<0, T, 4> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8302 | template<class T> struct ArgTraits_win64<1, T, 4> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8303 | template<class T> struct ArgTraits_win64<2, T, 4> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8304 | template<class T> struct ArgTraits_win64<3, T, 4> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8305 | |||
| 8306 | // specialization for 8 bytes type | ||
| 8307 | template<class T> struct ArgTraits_win64<0, T, 8> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8308 | template<class T> struct ArgTraits_win64<1, T, 8> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8309 | template<class T> struct ArgTraits_win64<2, T, 8> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8310 | template<class T> struct ArgTraits_win64<3, T, 8> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8311 | |||
| 8312 | #if JITASM_MMINTRIN | ||
| 8313 | // specialization for __m64 | ||
| 8314 | template<> struct ArgTraits_win64<0, __m64, 8> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8315 | template<> struct ArgTraits_win64<1, __m64, 8> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8316 | template<> struct ArgTraits_win64<2, __m64, 8> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8317 | template<> struct ArgTraits_win64<3, __m64, 8> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {}; | ||
| 8318 | #endif | ||
| 8319 | |||
| 8320 | // specialization for float | ||
| 8321 | template<> struct ArgTraits_win64<0, float, 4> : ArgTraits_win64_reg<XMM0, ARG_IN_XMM_SP | ARG_TYPE_VALUE> {}; | ||
| 8322 | template<> struct ArgTraits_win64<1, float, 4> : ArgTraits_win64_reg<XMM1, ARG_IN_XMM_SP | ARG_TYPE_VALUE> {}; | ||
| 8323 | template<> struct ArgTraits_win64<2, float, 4> : ArgTraits_win64_reg<XMM2, ARG_IN_XMM_SP | ARG_TYPE_VALUE> {}; | ||
| 8324 | template<> struct ArgTraits_win64<3, float, 4> : ArgTraits_win64_reg<XMM3, ARG_IN_XMM_SP | ARG_TYPE_VALUE> {}; | ||
| 8325 | |||
| 8326 | // specialization for double | ||
| 8327 | template<> struct ArgTraits_win64<0, double, 8> : ArgTraits_win64_reg<XMM0, ARG_IN_XMM_DP | ARG_TYPE_VALUE> {}; | ||
| 8328 | template<> struct ArgTraits_win64<1, double, 8> : ArgTraits_win64_reg<XMM1, ARG_IN_XMM_DP | ARG_TYPE_VALUE> {}; | ||
| 8329 | template<> struct ArgTraits_win64<2, double, 8> : ArgTraits_win64_reg<XMM2, ARG_IN_XMM_DP | ARG_TYPE_VALUE> {}; | ||
| 8330 | template<> struct ArgTraits_win64<3, double, 8> : ArgTraits_win64_reg<XMM3, ARG_IN_XMM_DP | ARG_TYPE_VALUE> {}; | ||
| 8331 | |||
| 8332 | |||
| 8333 | /// System V ABI AMD64 argument type traits | ||
| 8334 | template<int N, class T, int Size = sizeof(T)> | ||
| 8335 | struct ArgTraits_linux64 { | ||
| 8336 | enum { | ||
| 8337 | stack_size = (Size + 8 - 1) / 8 * 8, | ||
| 8338 | flag = ARG_IN_STACK | ARG_TYPE_VALUE, | ||
| 8339 | reg_id = INVALID | ||
| 8340 | }; | ||
| 8341 | }; | ||
| 8342 | |||
| 8343 | // INTEGER class | ||
| 8344 | struct ArgTraits_linux64_integer { | ||
| 8345 | enum { | ||
| 8346 | stack_size = 0, | ||
| 8347 | flag = ARG_IN_REG | ARG_TYPE_VALUE, | ||
| 8348 | reg_id = RDI | ||
| 8349 | }; | ||
| 8350 | }; | ||
| 8351 | |||
| 8352 | template<int N> struct ArgTraits_linux64<N, bool, sizeof(bool) > : ArgTraits_linux64_integer {}; | ||
| 8353 | template<int N> struct ArgTraits_linux64<N, char, sizeof(char) > : ArgTraits_linux64_integer {}; | ||
| 8354 | template<int N> struct ArgTraits_linux64<N, unsigned char, sizeof(unsigned char) > : ArgTraits_linux64_integer {}; | ||
| 8355 | template<int N> struct ArgTraits_linux64<N, short, sizeof(short) > : ArgTraits_linux64_integer {}; | ||
| 8356 | template<int N> struct ArgTraits_linux64<N, unsigned short, sizeof(unsigned short) > : ArgTraits_linux64_integer {}; | ||
| 8357 | template<int N> struct ArgTraits_linux64<N, int, sizeof(int) > : ArgTraits_linux64_integer {}; | ||
| 8358 | template<int N> struct ArgTraits_linux64<N, unsigned int, sizeof(unsigned int) > : ArgTraits_linux64_integer {}; | ||
| 8359 | template<int N> struct ArgTraits_linux64<N, long, sizeof(long) > : ArgTraits_linux64_integer {}; | ||
| 8360 | template<int N> struct ArgTraits_linux64<N, unsigned long, sizeof(unsigned long) > : ArgTraits_linux64_integer {}; | ||
| 8361 | template<int N> struct ArgTraits_linux64<N, long long, sizeof(long long) > : ArgTraits_linux64_integer {}; | ||
| 8362 | template<int N> struct ArgTraits_linux64<N, unsigned long long, sizeof(unsigned long long)> : ArgTraits_linux64_integer {}; | ||
| 8363 | template<int N, class T> struct ArgTraits_linux64<N, T *, 8 > : ArgTraits_linux64_integer {}; | ||
| 8364 | |||
| 8365 | // SSE class | ||
| 8366 | template<int Flag> struct ArgTraits_linux64_sse { | ||
| 8367 | enum { | ||
| 8368 | stack_size = 0, | ||
| 8369 | flag = Flag, | ||
| 8370 | reg_id = XMM0 | ||
| 8371 | }; | ||
| 8372 | }; | ||
| 8373 | |||
| 8374 | template<int N> struct ArgTraits_linux64<N, float, sizeof(float)> : ArgTraits_linux64_sse<ARG_IN_XMM_SP | ARG_TYPE_VALUE> {}; | ||
| 8375 | template<int N> struct ArgTraits_linux64<N, double, sizeof(double)> : ArgTraits_linux64_sse<ARG_IN_XMM_DP | ARG_TYPE_VALUE> {}; | ||
| 8376 | #if JITASM_MMINTRIN | ||
| 8377 | template<int N> struct ArgTraits_linux64<N, __m64, sizeof(__m64)> : ArgTraits_linux64_sse<ARG_IN_XMM_INT | ARG_TYPE_VALUE> {}; | ||
| 8378 | #endif | ||
| 8379 | #if JITASM_XMMINTRIN | ||
| 8380 | template<int N> struct ArgTraits_linux64<N, __m128, sizeof(__m128)> : ArgTraits_linux64_sse<ARG_IN_XMM_SP | ARG_TYPE_VALUE> {}; | ||
| 8381 | #endif | ||
| 8382 | #if JITASM_EMMINTRIN | ||
| 8383 | template<int N> struct ArgTraits_linux64<N, __m128d, sizeof(__m128d)> : ArgTraits_linux64_sse<ARG_IN_XMM_DP | ARG_TYPE_VALUE> {}; | ||
| 8384 | template<int N> struct ArgTraits_linux64<N, __m128i, sizeof(__m128i)> : ArgTraits_linux64_sse<ARG_IN_XMM_INT | ARG_TYPE_VALUE> {}; | ||
| 8385 | #endif | ||
| 8386 | |||
| 8387 | |||
| 8388 | /// Special argument type | ||
| 8389 | struct ArgNone {}; | ||
| 8390 | |||
| 8391 | /// Argument information | ||
| 8392 | struct ArgInfo | ||
| 8393 | { | ||
| 8394 | Addr addr; | ||
| 8395 | PhysicalRegID reg_id; | ||
| 8396 | uint32 flag; | ||
| 8397 | uint32 index_gp; | ||
| 8398 | uint32 index_mmx; | ||
| 8399 | uint32 index_xmm; | ||
| 8400 | |||
| 8401 | ✗ | ArgInfo(const Addr& addr_, PhysicalRegID reg_id_, uint32 flg, uint32 idx_gp = 0, uint32 idx_mmx = 0, uint32 idx_xmm_ = 0) : addr(addr_), reg_id(reg_id_), flag(flg), index_gp(idx_gp), index_mmx(idx_mmx), index_xmm(idx_xmm_) {} | |
| 8402 | |||
| 8403 | ✗ | template<class CurArgTraits, class NextArgTraits> ArgInfo Next() const { | |
| 8404 | ✗ | ArgInfo next_arg_info(addr + CurArgTraits::stack_size, static_cast<PhysicalRegID>(NextArgTraits::reg_id), NextArgTraits::flag, index_gp, index_mmx, index_xmm); | |
| 8405 | ✗ | if (CurArgTraits::flag & ARG_IN_REG) next_arg_info.index_gp++; | |
| 8406 | if (CurArgTraits::flag & ARG_IN_MMX) next_arg_info.index_mmx++; | ||
| 8407 | if (CurArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) next_arg_info.index_xmm++; | ||
| 8408 | |||
| 8409 | #ifdef JITASM64 | ||
| 8410 | #ifdef JITASM_WIN | ||
| 8411 | // for Win64 | ||
| 8412 | #else | ||
| 8413 | // for x64 Linux | ||
| 8414 | if (NextArgTraits::flag & ARG_IN_REG) { | ||
| 8415 | ✗ | const PhysicalRegID gp_regs[] = {RDI, RSI, RDX, RCX, R8, R9}; | |
| 8416 | ✗ | next_arg_info.reg_id = next_arg_info.index_gp < 6 ? gp_regs[next_arg_info.index_gp] : INVALID; | |
| 8417 | } | ||
| 8418 | if (CurArgTraits::flag & ARG_IN_REG) { | ||
| 8419 | ✗ | if (reg_id == INVALID) { | |
| 8420 | // This register argument is passed on stack | ||
| 8421 | ✗ | next_arg_info.addr = next_arg_info.addr + 8; | |
| 8422 | } | ||
| 8423 | } | ||
| 8424 | |||
| 8425 | // __m128/__m128d/__m128i | ||
| 8426 | if (NextArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) { | ||
| 8427 | if (next_arg_info.index_xmm < 8) { | ||
| 8428 | next_arg_info.reg_id = static_cast<PhysicalRegID>(next_arg_info.reg_id + next_arg_info.index_xmm); | ||
| 8429 | } else { | ||
| 8430 | next_arg_info.reg_id = INVALID; | ||
| 8431 | } | ||
| 8432 | } | ||
| 8433 | if (CurArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) { | ||
| 8434 | if (reg_id == INVALID) { | ||
| 8435 | // This __m128/__m128d/__m128i argument is passed on stack | ||
| 8436 | next_arg_info.addr = next_arg_info.addr + 16; | ||
| 8437 | } | ||
| 8438 | } | ||
| 8439 | #endif | ||
| 8440 | #else | ||
| 8441 | // for x86 Win/Linux | ||
| 8442 | |||
| 8443 | // __m64 | ||
| 8444 | if (NextArgTraits::flag & ARG_IN_MMX) { | ||
| 8445 | if (next_arg_info.index_mmx < 3) { | ||
| 8446 | next_arg_info.reg_id = static_cast<PhysicalRegID>(next_arg_info.reg_id + next_arg_info.index_mmx); | ||
| 8447 | } else { | ||
| 8448 | next_arg_info.reg_id = INVALID; | ||
| 8449 | } | ||
| 8450 | } | ||
| 8451 | if (CurArgTraits::flag & ARG_IN_MMX) { | ||
| 8452 | if (reg_id == INVALID) { | ||
| 8453 | // This __m64 argument is passed on stack | ||
| 8454 | next_arg_info.addr = next_arg_info.addr + 8; | ||
| 8455 | } | ||
| 8456 | } | ||
| 8457 | |||
| 8458 | // __m128/__m128d/__m128i | ||
| 8459 | if (NextArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) { | ||
| 8460 | if (next_arg_info.index_xmm < 3) { | ||
| 8461 | next_arg_info.reg_id = static_cast<PhysicalRegID>(next_arg_info.reg_id + next_arg_info.index_xmm); | ||
| 8462 | } else { | ||
| 8463 | next_arg_info.reg_id = INVALID; | ||
| 8464 | } | ||
| 8465 | } | ||
| 8466 | if (CurArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) { | ||
| 8467 | if (reg_id == INVALID) { | ||
| 8468 | // This __m128/__m128d/__m128i argument is passed on stack | ||
| 8469 | next_arg_info.addr = next_arg_info.addr + 16; | ||
| 8470 | } | ||
| 8471 | } | ||
| 8472 | #endif | ||
| 8473 | |||
| 8474 | ✗ | return next_arg_info; | |
| 8475 | } | ||
| 8476 | }; | ||
| 8477 | |||
| 8478 | /// Result type traits | ||
| 8479 | template<class T> | ||
| 8480 | struct ResultTraits { | ||
| 8481 | enum { size = sizeof(T) }; | ||
| 8482 | typedef OpdT<sizeof(T) * 8> OpdR; | ||
| 8483 | typedef AddressingPtr<OpdR> ResultPtr; | ||
| 8484 | }; | ||
| 8485 | |||
| 8486 | // specialization for void | ||
| 8487 | template<> | ||
| 8488 | struct ResultTraits<void> { | ||
| 8489 | enum { size = 0 }; | ||
| 8490 | struct OpdR {}; | ||
| 8491 | struct ResultPtr {}; | ||
| 8492 | }; | ||
| 8493 | |||
| 8494 | /// Result store destination | ||
| 8495 | struct ResultDest { | ||
| 8496 | Reg ptr; | ||
| 8497 | ResultDest(Frontend& f, const ArgInfo& dest) | ||
| 8498 | { | ||
| 8499 | if (dest.reg_id != INVALID) { | ||
| 8500 | // result pointer on register | ||
| 8501 | f.DeclareRegArg(ptr, Reg(dest.reg_id), !dest.addr.reg_.IsInvalid() ? f.ptr[dest.addr] : Opd()); | ||
| 8502 | } else if (!dest.addr.reg_.IsInvalid()) { | ||
| 8503 | // result pointer on stack | ||
| 8504 | f.DeclareStackArg(ptr, f.ptr[dest.addr]); | ||
| 8505 | } | ||
| 8506 | } | ||
| 8507 | }; | ||
| 8508 | |||
| 8509 | /// Function result | ||
| 8510 | template<class T, int Size = ResultTraits<T>::size> | ||
| 8511 | struct ResultT { | ||
| 8512 | enum { ArgR = 1 /* First (hidden) argument is pointer for copying result. */}; | ||
| 8513 | typedef typename ResultTraits<T>::OpdR OpdR; | ||
| 8514 | OpdR val_; | ||
| 8515 | ResultT() {} | ||
| 8516 | ResultT(const MemT<OpdR>& val) : val_(val) {} | ||
| 8517 | void StoreResult(Frontend& f, const ResultDest& dst) | ||
| 8518 | { | ||
| 8519 | if (val_.IsMem()) { | ||
| 8520 | f.lea(f.zsi, static_cast<MemT<OpdR>&>(val_)); | ||
| 8521 | f.mov(f.zcx, Size); | ||
| 8522 | f.rep_movsb(dst.ptr, f.zsi, f.zcx); | ||
| 8523 | f.DeclareResultReg(dst.ptr); | ||
| 8524 | } | ||
| 8525 | } | ||
| 8526 | }; | ||
| 8527 | |||
| 8528 | // specialization for void | ||
| 8529 | template<> | ||
| 8530 | struct ResultT<void, 0> { | ||
| 8531 | enum { ArgR = 0 }; | ||
| 8532 | ResultT(); | ||
| 8533 | }; | ||
| 8534 | |||
| 8535 | // specialization for 1byte type | ||
| 8536 | template<class T> | ||
| 8537 | struct ResultT<T, 1> { | ||
| 8538 | enum { ArgR = 0 }; | ||
| 8539 | Opd8 val_; | ||
| 8540 | ResultT() {} | ||
| 8541 | ResultT(const Opd8& val) : val_(val) {} | ||
| 8542 | ResultT(uint8 imm) : val_(Imm8(imm)) {} | ||
| 8543 | void StoreResult(Frontend& f, const ResultDest& /*dst*/) | ||
| 8544 | { | ||
| 8545 | if (val_.IsGpReg()) { | ||
| 8546 | if (val_.GetReg().IsSymbolic()) { | ||
| 8547 | f.DeclareResultReg(val_); | ||
| 8548 | } else if (val_.GetReg().id != AL) { | ||
| 8549 | f.mov(f.al, static_cast<Reg8&>(val_)); | ||
| 8550 | } | ||
| 8551 | } else if (val_.IsMem()) { | ||
| 8552 | f.mov(f.al, static_cast<Mem8&>(val_)); | ||
| 8553 | } else if (val_.IsImm()) { | ||
| 8554 | f.mov(f.al, static_cast<Imm8&>(val_)); | ||
| 8555 | } | ||
| 8556 | } | ||
| 8557 | }; | ||
| 8558 | |||
| 8559 | // specialization for 2bytes type | ||
| 8560 | template<class T> | ||
| 8561 | struct ResultT<T, 2> { | ||
| 8562 | enum { ArgR = 0 }; | ||
| 8563 | Opd16 val_; | ||
| 8564 | ResultT() {} | ||
| 8565 | ResultT(const Opd16& val) : val_(val) {} | ||
| 8566 | ResultT(uint16 imm) : val_(Imm16(imm)) {} | ||
| 8567 | void StoreResult(Frontend& f, const ResultDest& /*dst*/) | ||
| 8568 | { | ||
| 8569 | if (val_.IsGpReg()) { | ||
| 8570 | if (val_.GetReg().IsSymbolic()) { | ||
| 8571 | f.DeclareResultReg(val_); | ||
| 8572 | } else if (val_.GetReg().id != AX) { | ||
| 8573 | f.mov(f.ax, static_cast<Reg16&>(val_)); | ||
| 8574 | } | ||
| 8575 | } else if (val_.IsMem()) { | ||
| 8576 | f.mov(f.ax, static_cast<Mem16&>(val_)); | ||
| 8577 | } else if (val_.IsImm()) { | ||
| 8578 | f.mov(f.ax, static_cast<Imm16&>(val_)); | ||
| 8579 | } | ||
| 8580 | } | ||
| 8581 | }; | ||
| 8582 | |||
| 8583 | // specialization for 4bytes type | ||
| 8584 | template<class T> | ||
| 8585 | struct ResultT<T, 4> { | ||
| 8586 | enum { ArgR = 0 }; | ||
| 8587 | Opd32 val_; | ||
| 8588 | ResultT() {} | ||
| 8589 | ResultT(const Opd32& val) : val_(val) {} | ||
| 8590 | ResultT(uint32 imm) : val_(Imm32(imm)) {} | ||
| 8591 | void StoreResult(Frontend& f, const ResultDest& /*dst*/) | ||
| 8592 | { | ||
| 8593 | if (val_.IsGpReg()) { | ||
| 8594 | if (val_.GetReg().IsSymbolic()) { | ||
| 8595 | f.DeclareResultReg(val_); | ||
| 8596 | } else if (val_.GetReg().id != EAX) { | ||
| 8597 | f.mov(f.eax, static_cast<Reg32&>(val_)); | ||
| 8598 | } | ||
| 8599 | } else if (val_.IsMem()) { | ||
| 8600 | f.mov(f.eax, static_cast<Mem32&>(val_)); | ||
| 8601 | } else if (val_.IsImm()) { | ||
| 8602 | f.mov(f.eax, static_cast<Imm32&>(val_)); | ||
| 8603 | } | ||
| 8604 | } | ||
| 8605 | }; | ||
| 8606 | |||
| 8607 | // specialization for 8bytes type | ||
| 8608 | template<class T> | ||
| 8609 | struct ResultT<T, 8> { | ||
| 8610 | enum { ArgR = 0 }; | ||
| 8611 | Opd64 val_; | ||
| 8612 | ResultT() {} | ||
| 8613 | ResultT(const Opd64& val) : val_(val) {} | ||
| 8614 | ResultT(uint64 imm) : val_(Imm64(imm)) {} | ||
| 8615 | void StoreResult(Frontend& f, const ResultDest& /*dst*/) | ||
| 8616 | { | ||
| 8617 | #ifdef JITASM64 | ||
| 8618 | if (val_.IsGpReg()) { | ||
| 8619 | if (val_.GetReg().IsSymbolic()) { | ||
| 8620 | f.DeclareResultReg(val_); | ||
| 8621 | } else if (val_.GetReg().id != RAX) { | ||
| 8622 | f.mov(f.rax, static_cast<Reg64&>(val_)); | ||
| 8623 | } | ||
| 8624 | } else if (val_.IsMem()) { | ||
| 8625 | f.mov(f.rax, static_cast<Mem64&>(val_)); | ||
| 8626 | } else if (val_.IsImm()) { | ||
| 8627 | f.mov(f.rax, static_cast<Imm64&>(val_)); | ||
| 8628 | } else if (val_.IsMmxReg()) { | ||
| 8629 | f.movq(f.rax, static_cast<MmxReg&>(val_)); | ||
| 8630 | } | ||
| 8631 | #else | ||
| 8632 | if (val_.IsMem()) { | ||
| 8633 | // from memory | ||
| 8634 | Mem32 lo(val_.GetAddressBaseSize(), val_.GetAddressIndexSize(), val_.GetBase(), val_.GetIndex(), val_.GetScale(), val_.GetDisp()); | ||
| 8635 | Mem32 hi(val_.GetAddressBaseSize(), val_.GetAddressIndexSize(), val_.GetBase(), val_.GetIndex(), val_.GetScale(), val_.GetDisp() + 4); | ||
| 8636 | f.mov(f.eax, lo); | ||
| 8637 | f.mov(f.edx, hi); | ||
| 8638 | } else if (val_.IsImm()) { | ||
| 8639 | // from immediate | ||
| 8640 | f.mov(f.eax, static_cast<sint32>(val_.GetImm())); | ||
| 8641 | f.mov(f.edx, static_cast<sint32>(val_.GetImm() >> 32)); | ||
| 8642 | } | ||
| 8643 | #endif | ||
| 8644 | } | ||
| 8645 | }; | ||
| 8646 | |||
| 8647 | // specialization for float | ||
| 8648 | template<> | ||
| 8649 | struct ResultT<float, 4> { | ||
| 8650 | enum { ArgR = 0 }; | ||
| 8651 | detail::Opd val_; | ||
| 8652 | ResultT() {} | ||
| 8653 | ResultT(const FpuReg& fpu) : val_(fpu) {} | ||
| 8654 | ResultT(const Mem32& mem) : val_(mem) {} | ||
| 8655 | ResultT(const XmmReg& xmm) : val_(xmm) {} | ||
| 8656 | ResultT(const float imm) : val_(Imm32(*(uint32*)&imm)) {} | ||
| 8657 | void StoreResult(Frontend& f, const ResultDest& /*dst*/) | ||
| 8658 | { | ||
| 8659 | #ifdef JITASM64 | ||
| 8660 | if (val_.IsFpuReg()) { | ||
| 8661 | // from FPU register | ||
| 8662 | f.fstp(f.real4_ptr[f.rsp - 4]); | ||
| 8663 | f.movss(f.xmm0, f.dword_ptr[f.rsp - 4]); | ||
| 8664 | } else if (val_.IsMem() && val_.GetSize() == O_SIZE_32) { | ||
| 8665 | // from memory | ||
| 8666 | f.movss(f.xmm0, static_cast<Mem32&>(val_)); | ||
| 8667 | } else if (val_.IsXmmReg()) { | ||
| 8668 | // from XMM register | ||
| 8669 | if (val_.GetReg().IsSymbolic()) { | ||
| 8670 | f.DeclareResultReg(val_); | ||
| 8671 | } else if (val_.GetReg().id != XMM0) { | ||
| 8672 | f.movss(f.xmm0, static_cast<XmmReg&>(val_)); | ||
| 8673 | } | ||
| 8674 | } else if (val_.IsImm()) { | ||
| 8675 | // from float immediate | ||
| 8676 | f.mov(f.dword_ptr[f.rsp - 4], static_cast<Imm32&>(val_)); | ||
| 8677 | f.movss(f.xmm0, f.dword_ptr[f.rsp - 4]); | ||
| 8678 | } | ||
| 8679 | #else | ||
| 8680 | if (val_.IsFpuReg()) { | ||
| 8681 | // from FPU register | ||
| 8682 | if (val_.GetReg().id != ST0) { | ||
| 8683 | f.fld(static_cast<FpuReg&>(val_)); | ||
| 8684 | } | ||
| 8685 | } else if (val_.IsMem() && val_.GetSize() == O_SIZE_32) { | ||
| 8686 | // from memory | ||
| 8687 | f.fld(static_cast<Mem32&>(val_)); | ||
| 8688 | } else if (val_.IsXmmReg()) { | ||
| 8689 | // from XMM register | ||
| 8690 | f.movss(f.dword_ptr[f.esp - 4], static_cast<XmmReg&>(val_)); | ||
| 8691 | f.fld(f.real4_ptr[f.esp - 4]); | ||
| 8692 | } else if (val_.IsImm()) { | ||
| 8693 | // from float immediate | ||
| 8694 | f.mov(f.dword_ptr[f.esp - 4], static_cast<Imm32&>(val_)); | ||
| 8695 | f.fld(f.real4_ptr[f.esp - 4]); | ||
| 8696 | } | ||
| 8697 | #endif | ||
| 8698 | } | ||
| 8699 | }; | ||
| 8700 | |||
| 8701 | // specialization for double | ||
| 8702 | template<> | ||
| 8703 | struct ResultT<double, 8> { | ||
| 8704 | enum { ArgR = 0 }; | ||
| 8705 | detail::Opd val_; | ||
| 8706 | double imm_; | ||
| 8707 | ResultT() {} | ||
| 8708 | ResultT(const FpuReg& fpu) : val_(fpu) {} | ||
| 8709 | ResultT(const Mem64& mem) : val_(mem) {} | ||
| 8710 | ResultT(const XmmReg& xmm) : val_(xmm) {} | ||
| 8711 | ResultT(const double imm) : val_(Imm32(0)), imm_(imm) {} | ||
| 8712 | void StoreResult(Frontend& f, const ResultDest& /*dst*/) | ||
| 8713 | { | ||
| 8714 | #ifdef JITASM64 | ||
| 8715 | if (val_.IsFpuReg()) { | ||
| 8716 | // from FPU register | ||
| 8717 | f.fstp(f.real8_ptr[f.rsp - 8]); | ||
| 8718 | f.movsd(f.xmm0, f.qword_ptr[f.rsp - 8]); | ||
| 8719 | } else if (val_.IsMem() && val_.GetSize() == O_SIZE_64) { | ||
| 8720 | // from memory | ||
| 8721 | f.movsd(f.xmm0, static_cast<Mem64&>(val_)); | ||
| 8722 | } else if (val_.IsXmmReg()) { | ||
| 8723 | // from XMM register | ||
| 8724 | if (val_.GetReg().IsSymbolic()) { | ||
| 8725 | f.DeclareResultReg(val_); | ||
| 8726 | } else if (val_.GetReg().id != XMM0) { | ||
| 8727 | f.movsd(f.xmm0, static_cast<XmmReg&>(val_)); | ||
| 8728 | } | ||
| 8729 | } else if (val_.IsImm()) { | ||
| 8730 | // from float immediate | ||
| 8731 | f.mov(f.dword_ptr[f.rsp - 8], *reinterpret_cast<uint32*>(&imm_)); | ||
| 8732 | f.mov(f.dword_ptr[f.rsp - 4], *(reinterpret_cast<uint32*>(&imm_) + 1)); | ||
| 8733 | f.movsd(f.xmm0, f.qword_ptr[f.rsp - 8]); | ||
| 8734 | } | ||
| 8735 | #else | ||
| 8736 | if (val_.IsFpuReg()) { | ||
| 8737 | // from FPU register | ||
| 8738 | if (val_.GetReg().id != ST0) { | ||
| 8739 | f.fld(static_cast<FpuReg&>(val_)); | ||
| 8740 | } | ||
| 8741 | } else if (val_.IsMem() && val_.GetSize() == O_SIZE_64) { | ||
| 8742 | // from memory | ||
| 8743 | f.fld(static_cast<Mem64&>(val_)); | ||
| 8744 | } else if (val_.IsXmmReg()) { | ||
| 8745 | // from XMM register | ||
| 8746 | f.movsd(f.qword_ptr[f.esp - 8], static_cast<XmmReg&>(val_)); | ||
| 8747 | f.fld(f.real8_ptr[f.esp - 8]); | ||
| 8748 | } else if (val_.IsImm()) { // val_ is immediate 0 | ||
| 8749 | // from double immediate | ||
| 8750 | f.mov(f.dword_ptr[f.esp - 8], *reinterpret_cast<uint32*>(&imm_)); | ||
| 8751 | f.mov(f.dword_ptr[f.esp - 4], *(reinterpret_cast<uint32*>(&imm_) + 1)); | ||
| 8752 | f.fld(f.real8_ptr[f.esp - 8]); | ||
| 8753 | } | ||
| 8754 | #endif | ||
| 8755 | } | ||
| 8756 | }; | ||
| 8757 | |||
| 8758 | |||
| 8759 | #if JITASM_MMINTRIN | ||
| 8760 | // specialization for __m64 | ||
| 8761 | template<> | ||
| 8762 | struct ResultT<__m64, 8> { | ||
| 8763 | enum { ArgR = 0 }; | ||
| 8764 | Opd64 val_; | ||
| 8765 | ResultT() {} | ||
| 8766 | ResultT(const MmxReg& mm) : val_(mm) {} | ||
| 8767 | ResultT(const Mem64& mem) : val_(mem) {} | ||
| 8768 | void StoreResult(Frontend& f, const ResultDest& /*dst*/) | ||
| 8769 | { | ||
| 8770 | #if defined(JITASM64) && !defined(JITASM_WIN) | ||
| 8771 | if (val_.IsMmxReg()) { | ||
| 8772 | f.movq2dq(f.xmm0, static_cast<const MmxReg&>(val_)); | ||
| 8773 | } else if (val_.IsMem()) { | ||
| 8774 | f.movq(f.xmm0, static_cast<const Mem64&>(val_)); | ||
| 8775 | } | ||
| 8776 | #else | ||
| 8777 | if (val_.IsMmxReg()) { | ||
| 8778 | if (val_.GetReg().IsSymbolic()) { | ||
| 8779 | f.DeclareResultReg(val_); | ||
| 8780 | } else if (val_.GetReg().id != MM0) { | ||
| 8781 | f.movq(f.mm0, static_cast<const MmxReg&>(val_)); | ||
| 8782 | } | ||
| 8783 | } else if (val_.IsMem()) { | ||
| 8784 | f.movq(f.mm0, static_cast<const Mem64&>(val_)); | ||
| 8785 | } | ||
| 8786 | #endif | ||
| 8787 | } | ||
| 8788 | }; | ||
| 8789 | #endif // JITASM_MMINTRIN | ||
| 8790 | |||
| 8791 | #if JITASM_XMMINTRIN | ||
| 8792 | // specialization for __m128 | ||
| 8793 | template<> | ||
| 8794 | struct ResultT<__m128, 16> { | ||
| 8795 | enum { ArgR = 0 }; | ||
| 8796 | Opd128 val_; | ||
| 8797 | ResultT() {} | ||
| 8798 | ResultT(const XmmReg& xmm) : val_(xmm) {} | ||
| 8799 | ResultT(const Mem128& mem) : val_(mem) {} | ||
| 8800 | void StoreResult(Frontend& f, const ResultDest& /*dst*/) | ||
| 8801 | { | ||
| 8802 | if (val_.IsXmmReg()) { | ||
| 8803 | if (val_.GetReg().IsSymbolic()) { | ||
| 8804 | f.DeclareResultReg(val_); | ||
| 8805 | } else if (val_.GetReg().id != XMM0) { | ||
| 8806 | f.movaps(f.xmm0, static_cast<const XmmReg&>(val_)); | ||
| 8807 | } | ||
| 8808 | } else if (val_.IsMem()) { | ||
| 8809 | f.movaps(f.xmm0, static_cast<const Mem128&>(val_)); | ||
| 8810 | } | ||
| 8811 | } | ||
| 8812 | }; | ||
| 8813 | #endif // JITASM_XMMINTRIN | ||
| 8814 | |||
| 8815 | #if JITASM_EMMINTRIN | ||
| 8816 | // specialization for __m128d | ||
| 8817 | template<> | ||
| 8818 | struct ResultT<__m128d, 16> { | ||
| 8819 | enum { ArgR = 0 }; | ||
| 8820 | Opd128 val_; | ||
| 8821 | ResultT() {} | ||
| 8822 | ResultT(const XmmReg& xmm) : val_(xmm) {} | ||
| 8823 | ResultT(const Mem128& mem) : val_(mem) {} | ||
| 8824 | void StoreResult(Frontend& f, const ResultDest& /*dst*/) | ||
| 8825 | { | ||
| 8826 | if (val_.IsXmmReg()) { | ||
| 8827 | if (val_.GetReg().IsSymbolic()) { | ||
| 8828 | f.DeclareResultReg(val_); | ||
| 8829 | } else if (val_.GetReg().id != XMM0) { | ||
| 8830 | f.movapd(f.xmm0, static_cast<const XmmReg&>(val_)); | ||
| 8831 | } | ||
| 8832 | } else if (val_.IsMem()) { | ||
| 8833 | f.movapd(f.xmm0, static_cast<const Mem128&>(val_)); | ||
| 8834 | } | ||
| 8835 | } | ||
| 8836 | }; | ||
| 8837 | |||
| 8838 | // specialization for __m128i | ||
| 8839 | template<> | ||
| 8840 | struct ResultT<__m128i, 16> { | ||
| 8841 | enum { ArgR = 0 }; | ||
| 8842 | Opd128 val_; | ||
| 8843 | ResultT() {} | ||
| 8844 | ResultT(const XmmReg& xmm) : val_(xmm) {} | ||
| 8845 | ResultT(const Mem128& mem) : val_(mem) {} | ||
| 8846 | void StoreResult(Frontend& f, const ResultDest& /*dst*/) | ||
| 8847 | { | ||
| 8848 | if (val_.IsXmmReg()) { | ||
| 8849 | if (val_.GetReg().IsSymbolic()) { | ||
| 8850 | f.DeclareResultReg(val_); | ||
| 8851 | } else if (val_.GetReg().id != XMM0) { | ||
| 8852 | f.movdqa(f.xmm0, static_cast<const XmmReg&>(val_)); | ||
| 8853 | } | ||
| 8854 | } else if (val_.IsMem()) { | ||
| 8855 | f.movdqa(f.xmm0, static_cast<const Mem128&>(val_)); | ||
| 8856 | } | ||
| 8857 | } | ||
| 8858 | }; | ||
| 8859 | #endif // JITASM_EMMINTRIN | ||
| 8860 | |||
| 8861 | |||
| 8862 | namespace calling_convention_cdecl | ||
| 8863 | { | ||
| 8864 | #ifdef JITASM64 | ||
| 8865 | #ifdef JITASM_WIN | ||
| 8866 | template<int N, class T, int Size = sizeof(T)> struct ArgTraits : ArgTraits_win64<N, T, Size> {}; | ||
| 8867 | #else | ||
| 8868 | template<int N, class T, int Size = sizeof(T)> struct ArgTraits : ArgTraits_linux64<N, T, Size> {}; | ||
| 8869 | #endif | ||
| 8870 | #else | ||
| 8871 | template<int N, class T, int Size = sizeof(T)> struct ArgTraits : ArgTraits_cdecl<N, T, Size> {}; | ||
| 8872 | #endif | ||
| 8873 | |||
| 8874 | template<class R> | ||
| 8875 | ArgInfo ResultInfo() | ||
| 8876 | { | ||
| 8877 | if (ResultT<R>::ArgR) { | ||
| 8878 | #ifdef JITASM64 | ||
| 8879 | return ArgInfo(Addr(RegID::CreatePhysicalRegID(R_TYPE_GP, RBP), SIZE_OF_GP_REG * 2), RCX, ARG_IN_REG | ARG_TYPE_PTR); | ||
| 8880 | #else | ||
| 8881 | return ArgInfo(Addr(RegID::CreatePhysicalRegID(R_TYPE_GP, EBP), SIZE_OF_GP_REG * 2), INVALID, ARG_IN_STACK | ARG_TYPE_PTR); | ||
| 8882 | #endif | ||
| 8883 | } else { | ||
| 8884 | return ArgInfo(Addr(RegID::Invalid(), 0), INVALID, 0); | ||
| 8885 | } | ||
| 8886 | } | ||
| 8887 | |||
| 8888 | template<class R, class A1> | ||
| 8889 | ✗ | ArgInfo ArgInfo1() { return ArgInfo(Addr(RegID::CreatePhysicalRegID(R_TYPE_GP, EBP), SIZE_OF_GP_REG * (2 + ResultT<R>::ArgR)), static_cast<PhysicalRegID>(ArgTraits<ResultT<R>::ArgR + 0, A1>::reg_id), ArgTraits<ResultT<R>::ArgR + 0, A1>::flag); } | |
| 8890 | template<class R, class A1, class A2> | ||
| 8891 | ✗ | ArgInfo ArgInfo2() { return ArgInfo(ArgInfo1<R, A1>()).Next< ArgTraits<ResultT<R>::ArgR + 0, A1>, ArgTraits<ResultT<R>::ArgR + 1, A2> >(); } | |
| 8892 | template<class R, class A1, class A2, class A3> | ||
| 8893 | ✗ | ArgInfo ArgInfo3() { return ArgInfo(ArgInfo2<R, A1, A2>()).Next< ArgTraits<ResultT<R>::ArgR + 1, A2>, ArgTraits<ResultT<R>::ArgR + 2, A3> >(); } | |
| 8894 | template<class R, class A1, class A2, class A3, class A4> | ||
| 8895 | ✗ | ArgInfo ArgInfo4() { return ArgInfo(ArgInfo3<R, A1, A2, A3>()).Next< ArgTraits<ResultT<R>::ArgR + 2, A3>, ArgTraits<ResultT<R>::ArgR + 3, A4> >(); } | |
| 8896 | template<class R, class A1, class A2, class A3, class A4, class A5> | ||
| 8897 | ArgInfo ArgInfo5() { return ArgInfo(ArgInfo4<R, A1, A2, A3, A4>()).Next< ArgTraits<ResultT<R>::ArgR + 3, A4>, ArgTraits<ResultT<R>::ArgR + 4, A5> >(); } | ||
| 8898 | template<class R, class A1, class A2, class A3, class A4, class A5, class A6> | ||
| 8899 | ArgInfo ArgInfo6() { return ArgInfo(ArgInfo5<R, A1, A2, A3, A4, A5>()).Next< ArgTraits<ResultT<R>::ArgR + 4, A5>, ArgTraits<ResultT<R>::ArgR + 5, A6> >(); } | ||
| 8900 | template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7> | ||
| 8901 | ArgInfo ArgInfo7() { return ArgInfo(ArgInfo6<R, A1, A2, A3, A4, A5, A6>()).Next< ArgTraits<ResultT<R>::ArgR + 5, A6>, ArgTraits<ResultT<R>::ArgR + 6, A7> >(); } | ||
| 8902 | template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> | ||
| 8903 | ArgInfo ArgInfo8() { return ArgInfo(ArgInfo7<R, A1, A2, A3, A4, A5, A6, A7>()).Next< ArgTraits<ResultT<R>::ArgR + 6, A7>, ArgTraits<ResultT<R>::ArgR + 7, A8> >(); } | ||
| 8904 | template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> | ||
| 8905 | ArgInfo ArgInfo9() { return ArgInfo(ArgInfo8<R, A1, A2, A3, A4, A5, A6, A7, A8>()).Next< ArgTraits<ResultT<R>::ArgR + 7, A8>, ArgTraits<ResultT<R>::ArgR + 8, A9> >(); } | ||
| 8906 | template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> | ||
| 8907 | ArgInfo ArgInfo10() { return ArgInfo(ArgInfo9<R, A1, A2, A3, A4, A5, A6, A7, A8, A9>()).Next< ArgTraits<ResultT<R>::ArgR + 8, A9>, ArgTraits<ResultT<R>::ArgR + 9, A10> >(); } | ||
| 8908 | |||
| 8909 | /// Function argument | ||
| 8910 | template<class T, size_t Size = sizeof(T)> | ||
| 8911 | struct Arg | ||
| 8912 | { | ||
| 8913 | Addr addr_; | ||
| 8914 | #ifdef JITASM64 | ||
| 8915 | Arg(Frontend& f, const ArgInfo& arg_info) : addr_(Reg()) { | ||
| 8916 | if (arg_info.reg_id != INVALID) { | ||
| 8917 | f.DeclareRegArg(Reg(addr_.reg_), Reg(arg_info.reg_id), f.ptr[arg_info.addr]); | ||
| 8918 | } else { | ||
| 8919 | f.DeclareStackArg(Reg(addr_.reg_), f.ptr[arg_info.addr]); | ||
| 8920 | } | ||
| 8921 | } | ||
| 8922 | #else | ||
| 8923 | Arg(Frontend& f, const ArgInfo& arg_info) : addr_(arg_info.addr) {} | ||
| 8924 | #endif | ||
| 8925 | operator Addr () {return addr_;} | ||
| 8926 | }; | ||
| 8927 | |||
| 8928 | // specialization for 1byte type | ||
| 8929 | template<class T> | ||
| 8930 | struct Arg<T, 1> | ||
| 8931 | { | ||
| 8932 | Frontend *f_; | ||
| 8933 | ArgInfo arg_info_; | ||
| 8934 | |||
| 8935 | Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {} | ||
| 8936 | operator Addr () { | ||
| 8937 | #ifdef JITASM64 | ||
| 8938 | // Dump to shadow space when x64 argument on register | ||
| 8939 | if (arg_info_.reg_id != INVALID) { | ||
| 8940 | f_->movzx(Reg64(arg_info_.reg_id), Reg8(arg_info_.reg_id)); | ||
| 8941 | f_->mov(f_->qword_ptr[arg_info_.addr], Reg64(arg_info_.reg_id)); | ||
| 8942 | } | ||
| 8943 | #endif | ||
| 8944 | return arg_info_.addr; | ||
| 8945 | } | ||
| 8946 | operator Reg8 () { | ||
| 8947 | Reg8 reg; | ||
| 8948 | if (arg_info_.reg_id == INVALID) { | ||
| 8949 | f_->DeclareStackArg(reg, f_->byte_ptr[arg_info_.addr]); // argument on stack | ||
| 8950 | } else { | ||
| 8951 | f_->DeclareRegArg(reg, Reg8(arg_info_.reg_id), f_->byte_ptr[arg_info_.addr]); // argument on register | ||
| 8952 | } | ||
| 8953 | return reg; | ||
| 8954 | } | ||
| 8955 | }; | ||
| 8956 | |||
| 8957 | // specialization for 2byte type | ||
| 8958 | template<class T> | ||
| 8959 | struct Arg<T, 2> | ||
| 8960 | { | ||
| 8961 | Frontend *f_; | ||
| 8962 | ArgInfo arg_info_; | ||
| 8963 | |||
| 8964 | Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {} | ||
| 8965 | operator Addr () { | ||
| 8966 | #ifdef JITASM64 | ||
| 8967 | // Dump to shadow space when x64 argument on register | ||
| 8968 | if (arg_info_.reg_id != INVALID) { | ||
| 8969 | f_->movzx(Reg64(arg_info_.reg_id), Reg16(arg_info_.reg_id)); | ||
| 8970 | f_->mov(f_->qword_ptr[arg_info_.addr], Reg64(arg_info_.reg_id)); | ||
| 8971 | } | ||
| 8972 | #endif | ||
| 8973 | return arg_info_.addr; | ||
| 8974 | } | ||
| 8975 | operator Reg16 () { | ||
| 8976 | Reg16 reg; | ||
| 8977 | if (arg_info_.reg_id == INVALID) { | ||
| 8978 | f_->DeclareStackArg(reg, f_->word_ptr[arg_info_.addr]); // argument on stack | ||
| 8979 | } else { | ||
| 8980 | f_->DeclareRegArg(reg, Reg16(arg_info_.reg_id), f_->word_ptr[arg_info_.addr]); // argument on register | ||
| 8981 | } | ||
| 8982 | return reg; | ||
| 8983 | } | ||
| 8984 | }; | ||
| 8985 | |||
| 8986 | // specialization for 4byte type | ||
| 8987 | template<class T> | ||
| 8988 | struct Arg<T, 4> | ||
| 8989 | { | ||
| 8990 | Frontend *f_; | ||
| 8991 | ArgInfo arg_info_; | ||
| 8992 | |||
| 8993 | Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {} | ||
| 8994 | operator Addr () { | ||
| 8995 | #ifdef JITASM64 | ||
| 8996 | // Dump to shadow space when x64 argument on register | ||
| 8997 | if (arg_info_.reg_id != INVALID) { | ||
| 8998 | f_->mov(f_->qword_ptr[arg_info_.addr], Reg64(arg_info_.reg_id)); | ||
| 8999 | } | ||
| 9000 | #endif | ||
| 9001 | return arg_info_.addr; | ||
| 9002 | } | ||
| 9003 | operator Reg32 () { | ||
| 9004 | Reg32 reg; | ||
| 9005 | if (arg_info_.reg_id == INVALID) { | ||
| 9006 | f_->DeclareStackArg(reg, f_->dword_ptr[arg_info_.addr]); // argument on stack | ||
| 9007 | } else { | ||
| 9008 | f_->DeclareRegArg(reg, Reg32(arg_info_.reg_id), f_->dword_ptr[arg_info_.addr]); // argument on register | ||
| 9009 | } | ||
| 9010 | return reg; | ||
| 9011 | } | ||
| 9012 | }; | ||
| 9013 | |||
| 9014 | #ifdef JITASM64 | ||
| 9015 | // specialization for 8byte type | ||
| 9016 | template<class T> | ||
| 9017 | struct Arg<T, 8> | ||
| 9018 | { | ||
| 9019 | Frontend *f_; | ||
| 9020 | ArgInfo arg_info_; | ||
| 9021 | |||
| 9022 | ✗ | Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {} | |
| 9023 | operator Addr () { | ||
| 9024 | // Dump to shadow space when x64 argument on register | ||
| 9025 | if (arg_info_.reg_id != INVALID) { | ||
| 9026 | f_->mov(f_->qword_ptr[arg_info_.addr], Reg64(arg_info_.reg_id)); | ||
| 9027 | } | ||
| 9028 | return arg_info_.addr; | ||
| 9029 | } | ||
| 9030 | ✗ | operator Reg64 () { | |
| 9031 | ✗ | Reg64 reg; | |
| 9032 | ✗ | if (arg_info_.reg_id == INVALID) { | |
| 9033 | ✗ | f_->DeclareStackArg(reg, f_->qword_ptr[arg_info_.addr]); // argument on stack | |
| 9034 | } else { | ||
| 9035 | ✗ | f_->DeclareRegArg(reg, Reg64(arg_info_.reg_id), f_->qword_ptr[arg_info_.addr]); // argument on register | |
| 9036 | } | ||
| 9037 | ✗ | return reg; | |
| 9038 | } | ||
| 9039 | }; | ||
| 9040 | #endif | ||
| 9041 | |||
| 9042 | // specialization for float | ||
| 9043 | template<> | ||
| 9044 | struct Arg<float, 4> | ||
| 9045 | { | ||
| 9046 | Frontend *f_; | ||
| 9047 | ArgInfo arg_info_; | ||
| 9048 | |||
| 9049 | Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {} | ||
| 9050 | operator Addr () { | ||
| 9051 | #ifdef JITASM64 | ||
| 9052 | // Dump to shadow space when x64 argument on register | ||
| 9053 | if (arg_info_.reg_id != INVALID) { | ||
| 9054 | f_->movss(f_->dword_ptr[arg_info_.addr], XmmReg(arg_info_.reg_id)); | ||
| 9055 | } | ||
| 9056 | #endif | ||
| 9057 | return arg_info_.addr; | ||
| 9058 | } | ||
| 9059 | operator XmmReg () { | ||
| 9060 | XmmReg reg; | ||
| 9061 | if (arg_info_.reg_id == INVALID) { | ||
| 9062 | f_->DeclareStackArg(reg, f_->dword_ptr[arg_info_.addr]); // argument on stack | ||
| 9063 | } else { | ||
| 9064 | f_->DeclareRegArg(reg, XmmReg(arg_info_.reg_id)); // argument on register | ||
| 9065 | } | ||
| 9066 | return reg; | ||
| 9067 | } | ||
| 9068 | }; | ||
| 9069 | |||
| 9070 | // specialization for double | ||
| 9071 | template<> | ||
| 9072 | struct Arg<double, 8> | ||
| 9073 | { | ||
| 9074 | Frontend *f_; | ||
| 9075 | ArgInfo arg_info_; | ||
| 9076 | |||
| 9077 | Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {} | ||
| 9078 | operator Addr () { | ||
| 9079 | #ifdef JITASM64 | ||
| 9080 | // Dump to shadow space when x64 argument on register | ||
| 9081 | if (arg_info_.reg_id != INVALID) { | ||
| 9082 | f_->movsd(f_->qword_ptr[arg_info_.addr], XmmReg(arg_info_.reg_id)); | ||
| 9083 | } | ||
| 9084 | #endif | ||
| 9085 | return arg_info_.addr; | ||
| 9086 | } | ||
| 9087 | operator XmmReg () { | ||
| 9088 | XmmReg reg; | ||
| 9089 | if (arg_info_.reg_id == INVALID) { | ||
| 9090 | f_->DeclareStackArg(reg, f_->qword_ptr[arg_info_.addr]); // argument on stack | ||
| 9091 | } else { | ||
| 9092 | f_->DeclareRegArg(reg, XmmReg(arg_info_.reg_id)); // argument on register | ||
| 9093 | } | ||
| 9094 | return reg; | ||
| 9095 | } | ||
| 9096 | }; | ||
| 9097 | |||
| 9098 | #if JITASM_MMINTRIN | ||
| 9099 | // specialization for __m64 | ||
| 9100 | template<> | ||
| 9101 | struct Arg<__m64, 8> | ||
| 9102 | { | ||
| 9103 | Frontend *f_; | ||
| 9104 | ArgInfo arg_info_; | ||
| 9105 | |||
| 9106 | Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {} | ||
| 9107 | operator Addr () { | ||
| 9108 | if (arg_info_.reg_id != INVALID) { | ||
| 9109 | // Passed by mmx register | ||
| 9110 | if (arg_info_.flag & ARG_IN_REG) { | ||
| 9111 | // Win64 | ||
| 9112 | #ifdef JITASM64 | ||
| 9113 | // Dump to shadow space when Win64 argument on register | ||
| 9114 | Reg64 arg; | ||
| 9115 | f_->DeclareRegArg(arg, Reg64(arg_info_.reg_id)); | ||
| 9116 | f_->mov(f_->qword_ptr[arg_info_.addr], arg); | ||
| 9117 | #endif | ||
| 9118 | return arg_info_.addr; | ||
| 9119 | } else if (arg_info_.flag & ARG_IN_XMM_INT) { | ||
| 9120 | // x64 Linux | ||
| 9121 | XmmReg arg; | ||
| 9122 | f_->DeclareRegArg(arg, XmmReg(arg_info_.reg_id)); | ||
| 9123 | Addr addr = f_->stack_manager_.Alloc(8, 8); | ||
| 9124 | f_->movq(f_->qword_ptr[addr], arg); | ||
| 9125 | return addr; | ||
| 9126 | } else { | ||
| 9127 | MmxReg arg; | ||
| 9128 | f_->DeclareRegArg(arg, MmxReg(arg_info_.reg_id)); | ||
| 9129 | Addr addr = f_->stack_manager_.Alloc(8, 8); | ||
| 9130 | f_->movq(f_->qword_ptr[addr], arg); | ||
| 9131 | return addr; | ||
| 9132 | } | ||
| 9133 | } else { | ||
| 9134 | // Passed by stack | ||
| 9135 | return arg_info_.addr; | ||
| 9136 | } | ||
| 9137 | } | ||
| 9138 | operator MmxReg () { | ||
| 9139 | MmxReg reg; | ||
| 9140 | if (arg_info_.reg_id != INVALID) { | ||
| 9141 | // Passed by register | ||
| 9142 | if (arg_info_.flag & ARG_IN_REG) { | ||
| 9143 | // Win64 | ||
| 9144 | #ifdef JITASM64 | ||
| 9145 | Reg64 arg; | ||
| 9146 | f_->DeclareRegArg(arg, Reg64(arg_info_.reg_id)); | ||
| 9147 | f_->movq(reg, arg); | ||
| 9148 | #endif | ||
| 9149 | } else if(arg_info_.flag & ARG_IN_XMM_INT) { | ||
| 9150 | // x64 Linux | ||
| 9151 | XmmReg arg; | ||
| 9152 | f_->DeclareRegArg(arg, XmmReg(arg_info_.reg_id)); | ||
| 9153 | f_->movdq2q(reg, arg); | ||
| 9154 | } else { | ||
| 9155 | f_->DeclareRegArg(reg, MmxReg(arg_info_.reg_id)); | ||
| 9156 | } | ||
| 9157 | } else { | ||
| 9158 | // Passed by stack | ||
| 9159 | f_->DeclareStackArg(reg, f_->qword_ptr[arg_info_.addr]); | ||
| 9160 | } | ||
| 9161 | return reg; | ||
| 9162 | } | ||
| 9163 | }; | ||
| 9164 | #endif // JITASM_MMINTRIN | ||
| 9165 | |||
| 9166 | #if JITASM_XMMINTRIN | ||
| 9167 | // specialization for __m128 | ||
| 9168 | template<> | ||
| 9169 | struct Arg<__m128, 16> | ||
| 9170 | { | ||
| 9171 | Frontend *f_; | ||
| 9172 | ArgInfo arg_info_; | ||
| 9173 | |||
| 9174 | Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {} | ||
| 9175 | operator Addr () { | ||
| 9176 | if (arg_info_.flag & ARG_TYPE_PTR) { | ||
| 9177 | Reg ptr; | ||
| 9178 | if (arg_info_.reg_id != INVALID) { | ||
| 9179 | f_->DeclareRegArg(ptr, Reg(arg_info_.reg_id)); // argument on register | ||
| 9180 | } else { | ||
| 9181 | f_->mov(ptr, f_->ptr[arg_info_.addr]); | ||
| 9182 | } | ||
| 9183 | return ptr; | ||
| 9184 | } else if (arg_info_.reg_id != INVALID) { | ||
| 9185 | Addr addr = f_->stack_manager_.Alloc(16, 16); | ||
| 9186 | f_->movdqa(f_->xmmword_ptr[addr], XmmReg(arg_info_.reg_id)); | ||
| 9187 | return addr; | ||
| 9188 | } else { | ||
| 9189 | return arg_info_.addr; | ||
| 9190 | } | ||
| 9191 | } | ||
| 9192 | operator XmmReg () { | ||
| 9193 | XmmReg reg; | ||
| 9194 | if (arg_info_.flag & ARG_TYPE_PTR) { | ||
| 9195 | // Passed by pointer | ||
| 9196 | if (arg_info_.reg_id != INVALID) { | ||
| 9197 | // argument pointer on register | ||
| 9198 | f_->movdqa(reg, f_->xmmword_ptr[Reg(arg_info_.reg_id)]); | ||
| 9199 | } else { | ||
| 9200 | // argument pointer on stack | ||
| 9201 | Reg ptr; | ||
| 9202 | f_->mov(ptr, f_->ptr[arg_info_.addr]); | ||
| 9203 | f_->movdqa(reg, f_->xmmword_ptr[ptr]); | ||
| 9204 | } | ||
| 9205 | } else if (arg_info_.reg_id != INVALID) { | ||
| 9206 | // Passed by xmm register | ||
| 9207 | f_->DeclareRegArg(reg, XmmReg(arg_info_.reg_id)); | ||
| 9208 | } else { | ||
| 9209 | // Passed by stack | ||
| 9210 | f_->DeclareStackArg(reg, f_->xmmword_ptr[arg_info_.addr]); | ||
| 9211 | } | ||
| 9212 | return reg; | ||
| 9213 | } | ||
| 9214 | }; | ||
| 9215 | #endif // JITASM_XMMINTRIN | ||
| 9216 | |||
| 9217 | #if JITASM_EMMINTRIN | ||
| 9218 | // specialization for __m128d, __m128i | ||
| 9219 | template<> struct Arg<__m128d, 16> : Arg<__m128, 16> { | ||
| 9220 | Arg(Frontend& f, const ArgInfo& arg_info) : Arg<__m128, 16>(f, arg_info) {} | ||
| 9221 | }; | ||
| 9222 | |||
| 9223 | template<> struct Arg<__m128i, 16> : Arg<__m128, 16> { | ||
| 9224 | Arg(Frontend& f, const ArgInfo& arg_info) : Arg<__m128, 16>(f, arg_info) {} | ||
| 9225 | }; | ||
| 9226 | #endif // JITASM_EMMINTRIN | ||
| 9227 | } // namespace calling_convention_cdecl | ||
| 9228 | |||
| 9229 | } // namespace detail | ||
| 9230 | |||
| 9231 | /// cdecl function | ||
| 9232 | template< | ||
| 9233 | class R, | ||
| 9234 | class Derived, | ||
| 9235 | class A1 = detail::ArgNone, | ||
| 9236 | class A2 = detail::ArgNone, | ||
| 9237 | class A3 = detail::ArgNone, | ||
| 9238 | class A4 = detail::ArgNone, | ||
| 9239 | class A5 = detail::ArgNone, | ||
| 9240 | class A6 = detail::ArgNone, | ||
| 9241 | class A7 = detail::ArgNone, | ||
| 9242 | class A8 = detail::ArgNone, | ||
| 9243 | class A9 = detail::ArgNone, | ||
| 9244 | class A10 = detail::ArgNone> | ||
| 9245 | struct function_cdecl : Frontend | ||
| 9246 | { | ||
| 9247 | typedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); | ||
| 9248 | typedef detail::ResultT<R> Result; ///< main function result type | ||
| 9249 | typename detail::ResultTraits<R>::ResultPtr result_ptr; | ||
| 9250 | |||
| 9251 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9252 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9253 | void naked_main() { | ||
| 9254 | using namespace detail::calling_convention_cdecl; | ||
| 9255 | Prolog(); | ||
| 9256 | detail::ResultDest result_dst(*this, ResultInfo<R>()); | ||
| 9257 | static_cast<Derived *>(this)->main( | ||
| 9258 | Arg<A1>(*this, ArgInfo1<R,A1>()), | ||
| 9259 | Arg<A2>(*this, ArgInfo2<R,A1,A2>()), | ||
| 9260 | Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()), | ||
| 9261 | Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()), | ||
| 9262 | Arg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()), | ||
| 9263 | Arg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>()), | ||
| 9264 | Arg<A7>(*this, ArgInfo7<R,A1,A2,A3,A4,A5,A6,A7>()), | ||
| 9265 | Arg<A8>(*this, ArgInfo8<R,A1,A2,A3,A4,A5,A6,A7,A8>()), | ||
| 9266 | Arg<A9>(*this, ArgInfo9<R,A1,A2,A3,A4,A5,A6,A7,A8,A9>()), | ||
| 9267 | Arg<A10>(*this, ArgInfo10<R,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>()) | ||
| 9268 | ).StoreResult(*this, result_dst); | ||
| 9269 | Epilog(); | ||
| 9270 | } | ||
| 9271 | }; | ||
| 9272 | |||
| 9273 | // specialization for 10 arguments and no result | ||
| 9274 | template<class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> | ||
| 9275 | struct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> : Frontend | ||
| 9276 | { | ||
| 9277 | typedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); | ||
| 9278 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9279 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9280 | void naked_main() { | ||
| 9281 | using namespace detail::calling_convention_cdecl; | ||
| 9282 | Prolog(); | ||
| 9283 | static_cast<Derived *>(this)->main( | ||
| 9284 | Arg<A1>(*this, ArgInfo1<void,A1>()), | ||
| 9285 | Arg<A2>(*this, ArgInfo2<void,A1,A2>()), | ||
| 9286 | Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()), | ||
| 9287 | Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()), | ||
| 9288 | Arg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()), | ||
| 9289 | Arg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()), | ||
| 9290 | Arg<A7>(*this, ArgInfo7<void,A1,A2,A3,A4,A5,A6,A7>()), | ||
| 9291 | Arg<A8>(*this, ArgInfo8<void,A1,A2,A3,A4,A5,A6,A7,A8>()), | ||
| 9292 | Arg<A9>(*this, ArgInfo9<void,A1,A2,A3,A4,A5,A6,A7,A8,A9>()), | ||
| 9293 | Arg<A10>(*this, ArgInfo10<void,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>())); | ||
| 9294 | Epilog(); | ||
| 9295 | } | ||
| 9296 | }; | ||
| 9297 | |||
| 9298 | // specialization for 9 arguments | ||
| 9299 | template<class R, class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> | ||
| 9300 | struct function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, A7, A8, A9, detail::ArgNone> : Frontend | ||
| 9301 | { | ||
| 9302 | typedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8, A9); | ||
| 9303 | typedef detail::ResultT<R> Result; ///< main function result type | ||
| 9304 | typename detail::ResultTraits<R>::ResultPtr result_ptr; | ||
| 9305 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9306 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9307 | void naked_main() { | ||
| 9308 | using namespace detail::calling_convention_cdecl; | ||
| 9309 | Prolog(); | ||
| 9310 | detail::ResultDest result_dst(*this, ResultInfo<R>()); | ||
| 9311 | static_cast<Derived *>(this)->main( | ||
| 9312 | Arg<A1>(*this, ArgInfo1<R,A1>()), | ||
| 9313 | Arg<A2>(*this, ArgInfo2<R,A1,A2>()), | ||
| 9314 | Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()), | ||
| 9315 | Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()), | ||
| 9316 | Arg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()), | ||
| 9317 | Arg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>()), | ||
| 9318 | Arg<A7>(*this, ArgInfo7<R,A1,A2,A3,A4,A5,A6,A7>()), | ||
| 9319 | Arg<A8>(*this, ArgInfo8<R,A1,A2,A3,A4,A5,A6,A7,A8>()), | ||
| 9320 | Arg<A9>(*this, ArgInfo9<R,A1,A2,A3,A4,A5,A6,A7,A8,A9>()) | ||
| 9321 | ).StoreResult(*this, result_dst); | ||
| 9322 | Epilog(); | ||
| 9323 | } | ||
| 9324 | }; | ||
| 9325 | |||
| 9326 | // specialization for 9 arguments and no result | ||
| 9327 | template<class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> | ||
| 9328 | struct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, A7, A8, A9, detail::ArgNone> : Frontend | ||
| 9329 | { | ||
| 9330 | typedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8, A9); | ||
| 9331 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9332 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9333 | void naked_main() { | ||
| 9334 | using namespace detail::calling_convention_cdecl; | ||
| 9335 | Prolog(); | ||
| 9336 | static_cast<Derived *>(this)->main( | ||
| 9337 | Arg<A1>(*this, ArgInfo1<void,A1>()), | ||
| 9338 | Arg<A2>(*this, ArgInfo2<void,A1,A2>()), | ||
| 9339 | Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()), | ||
| 9340 | Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()), | ||
| 9341 | Arg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()), | ||
| 9342 | Arg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()), | ||
| 9343 | Arg<A7>(*this, ArgInfo7<void,A1,A2,A3,A4,A5,A6,A7>()), | ||
| 9344 | Arg<A8>(*this, ArgInfo8<void,A1,A2,A3,A4,A5,A6,A7,A8>()), | ||
| 9345 | Arg<A9>(*this, ArgInfo9<void,A1,A2,A3,A4,A5,A6,A7,A8,A9>())); | ||
| 9346 | Epilog(); | ||
| 9347 | } | ||
| 9348 | }; | ||
| 9349 | |||
| 9350 | // specialization for 8 arguments | ||
| 9351 | template<class R, class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> | ||
| 9352 | struct function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, A7, A8, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9353 | { | ||
| 9354 | typedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8); | ||
| 9355 | typedef detail::ResultT<R> Result; ///< main function result type | ||
| 9356 | typename detail::ResultTraits<R>::ResultPtr result_ptr; | ||
| 9357 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9358 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9359 | void naked_main() { | ||
| 9360 | using namespace detail::calling_convention_cdecl; | ||
| 9361 | Prolog(); | ||
| 9362 | detail::ResultDest result_dst(*this, ResultInfo<R>()); | ||
| 9363 | static_cast<Derived *>(this)->main( | ||
| 9364 | Arg<A1>(*this, ArgInfo1<R,A1>()), | ||
| 9365 | Arg<A2>(*this, ArgInfo2<R,A1,A2>()), | ||
| 9366 | Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()), | ||
| 9367 | Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()), | ||
| 9368 | Arg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()), | ||
| 9369 | Arg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>()), | ||
| 9370 | Arg<A7>(*this, ArgInfo7<R,A1,A2,A3,A4,A5,A6,A7>()), | ||
| 9371 | Arg<A8>(*this, ArgInfo8<R,A1,A2,A3,A4,A5,A6,A7,A8>()) | ||
| 9372 | ).StoreResult(*this, result_dst); | ||
| 9373 | Epilog(); | ||
| 9374 | } | ||
| 9375 | }; | ||
| 9376 | |||
| 9377 | // specialization for 8 arguments and no result | ||
| 9378 | template<class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> | ||
| 9379 | struct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, A7, A8, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9380 | { | ||
| 9381 | typedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8); | ||
| 9382 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9383 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9384 | void naked_main() { | ||
| 9385 | using namespace detail::calling_convention_cdecl; | ||
| 9386 | Prolog(); | ||
| 9387 | static_cast<Derived *>(this)->main( | ||
| 9388 | Arg<A1>(*this, ArgInfo1<void,A1>()), | ||
| 9389 | Arg<A2>(*this, ArgInfo2<void,A1,A2>()), | ||
| 9390 | Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()), | ||
| 9391 | Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()), | ||
| 9392 | Arg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()), | ||
| 9393 | Arg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()), | ||
| 9394 | Arg<A7>(*this, ArgInfo7<void,A1,A2,A3,A4,A5,A6,A7>()), | ||
| 9395 | Arg<A8>(*this, ArgInfo8<void,A1,A2,A3,A4,A5,A6,A7,A8>())); | ||
| 9396 | Epilog(); | ||
| 9397 | } | ||
| 9398 | }; | ||
| 9399 | |||
| 9400 | // specialization for 7 arguments | ||
| 9401 | template<class R, class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7> | ||
| 9402 | struct function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, A7, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9403 | { | ||
| 9404 | typedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7); | ||
| 9405 | typedef detail::ResultT<R> Result; ///< main function result type | ||
| 9406 | typename detail::ResultTraits<R>::ResultPtr result_ptr; | ||
| 9407 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9408 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9409 | void naked_main() { | ||
| 9410 | using namespace detail::calling_convention_cdecl; | ||
| 9411 | Prolog(); | ||
| 9412 | detail::ResultDest result_dst(*this, ResultInfo<R>()); | ||
| 9413 | static_cast<Derived *>(this)->main( | ||
| 9414 | Arg<A1>(*this, ArgInfo1<R,A1>()), | ||
| 9415 | Arg<A2>(*this, ArgInfo2<R,A1,A2>()), | ||
| 9416 | Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()), | ||
| 9417 | Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()), | ||
| 9418 | Arg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()), | ||
| 9419 | Arg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>()), | ||
| 9420 | Arg<A7>(*this, ArgInfo7<R,A1,A2,A3,A4,A5,A6,A7>()) | ||
| 9421 | ).StoreResult(*this, result_dst); | ||
| 9422 | Epilog(); | ||
| 9423 | } | ||
| 9424 | }; | ||
| 9425 | |||
| 9426 | // specialization for 7 arguments and no result | ||
| 9427 | template<class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7> | ||
| 9428 | struct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, A7, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9429 | { | ||
| 9430 | typedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7); | ||
| 9431 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9432 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9433 | void naked_main() { | ||
| 9434 | using namespace detail::calling_convention_cdecl; | ||
| 9435 | Prolog(); | ||
| 9436 | static_cast<Derived *>(this)->main( | ||
| 9437 | Arg<A1>(*this, ArgInfo1<void,A1>()), | ||
| 9438 | Arg<A2>(*this, ArgInfo2<void,A1,A2>()), | ||
| 9439 | Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()), | ||
| 9440 | Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()), | ||
| 9441 | Arg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()), | ||
| 9442 | Arg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()), | ||
| 9443 | Arg<A7>(*this, ArgInfo7<void,A1,A2,A3,A4,A5,A6,A7>())); | ||
| 9444 | Epilog(); | ||
| 9445 | } | ||
| 9446 | }; | ||
| 9447 | |||
| 9448 | // specialization for 6 arguments | ||
| 9449 | template<class R, class Derived, class A1, class A2, class A3, class A4, class A5, class A6> | ||
| 9450 | struct function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9451 | { | ||
| 9452 | typedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6); | ||
| 9453 | typedef detail::ResultT<R> Result; ///< main function result type | ||
| 9454 | typename detail::ResultTraits<R>::ResultPtr result_ptr; | ||
| 9455 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9456 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9457 | void naked_main() { | ||
| 9458 | using namespace detail::calling_convention_cdecl; | ||
| 9459 | Prolog(); | ||
| 9460 | detail::ResultDest result_dst(*this, ResultInfo<R>()); | ||
| 9461 | static_cast<Derived *>(this)->main( | ||
| 9462 | Arg<A1>(*this, ArgInfo1<R,A1>()), | ||
| 9463 | Arg<A2>(*this, ArgInfo2<R,A1,A2>()), | ||
| 9464 | Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()), | ||
| 9465 | Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()), | ||
| 9466 | Arg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()), | ||
| 9467 | Arg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>()) | ||
| 9468 | ).StoreResult(*this, result_dst); | ||
| 9469 | Epilog(); | ||
| 9470 | } | ||
| 9471 | }; | ||
| 9472 | |||
| 9473 | // specialization for 6 arguments and no result | ||
| 9474 | template<class Derived, class A1, class A2, class A3, class A4, class A5, class A6> | ||
| 9475 | struct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9476 | { | ||
| 9477 | typedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6); | ||
| 9478 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9479 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9480 | void naked_main() { | ||
| 9481 | using namespace detail::calling_convention_cdecl; | ||
| 9482 | Prolog(); | ||
| 9483 | static_cast<Derived *>(this)->main( | ||
| 9484 | Arg<A1>(*this, ArgInfo1<void,A1>()), | ||
| 9485 | Arg<A2>(*this, ArgInfo2<void,A1,A2>()), | ||
| 9486 | Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()), | ||
| 9487 | Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()), | ||
| 9488 | Arg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()), | ||
| 9489 | Arg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>())); | ||
| 9490 | Epilog(); | ||
| 9491 | } | ||
| 9492 | }; | ||
| 9493 | |||
| 9494 | // specialization for 5 arguments | ||
| 9495 | template<class R, class Derived, class A1, class A2, class A3, class A4, class A5> | ||
| 9496 | struct function_cdecl<R, Derived, A1, A2, A3, A4, A5, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9497 | { | ||
| 9498 | typedef R (*FuncPtr)(A1, A2, A3, A4, A5); | ||
| 9499 | typedef detail::ResultT<R> Result; ///< main function result type | ||
| 9500 | typename detail::ResultTraits<R>::ResultPtr result_ptr; | ||
| 9501 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9502 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9503 | void naked_main() { | ||
| 9504 | using namespace detail::calling_convention_cdecl; | ||
| 9505 | Prolog(); | ||
| 9506 | detail::ResultDest result_dst(*this, ResultInfo<R>()); | ||
| 9507 | static_cast<Derived *>(this)->main( | ||
| 9508 | Arg<A1>(*this, ArgInfo1<R,A1>()), | ||
| 9509 | Arg<A2>(*this, ArgInfo2<R,A1,A2>()), | ||
| 9510 | Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()), | ||
| 9511 | Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()), | ||
| 9512 | Arg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()) | ||
| 9513 | ).StoreResult(*this, result_dst); | ||
| 9514 | Epilog(); | ||
| 9515 | } | ||
| 9516 | }; | ||
| 9517 | |||
| 9518 | // specialization for 5 arguments and no result | ||
| 9519 | template<class Derived, class A1, class A2, class A3, class A4, class A5> | ||
| 9520 | struct function_cdecl<void, Derived, A1, A2, A3, A4, A5, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9521 | { | ||
| 9522 | typedef void (*FuncPtr)(A1, A2, A3, A4, A5); | ||
| 9523 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9524 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9525 | void naked_main() { | ||
| 9526 | using namespace detail::calling_convention_cdecl; | ||
| 9527 | Prolog(); | ||
| 9528 | static_cast<Derived *>(this)->main( | ||
| 9529 | Arg<A1>(*this, ArgInfo1<void,A1>()), | ||
| 9530 | Arg<A2>(*this, ArgInfo2<void,A1,A2>()), | ||
| 9531 | Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()), | ||
| 9532 | Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()), | ||
| 9533 | Arg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>())); | ||
| 9534 | Epilog(); | ||
| 9535 | } | ||
| 9536 | }; | ||
| 9537 | |||
| 9538 | // specialization for 4 arguments | ||
| 9539 | template<class R, class Derived, class A1, class A2, class A3, class A4> | ||
| 9540 | struct function_cdecl<R, Derived, A1, A2, A3, A4, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9541 | { | ||
| 9542 | typedef R (*FuncPtr)(A1, A2, A3, A4); | ||
| 9543 | typedef detail::ResultT<R> Result; ///< main function result type | ||
| 9544 | typename detail::ResultTraits<R>::ResultPtr result_ptr; | ||
| 9545 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9546 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9547 | void naked_main() { | ||
| 9548 | using namespace detail::calling_convention_cdecl; | ||
| 9549 | Prolog(); | ||
| 9550 | detail::ResultDest result_dst(*this, ResultInfo<R>()); | ||
| 9551 | static_cast<Derived *>(this)->main( | ||
| 9552 | Arg<A1>(*this, ArgInfo1<R,A1>()), | ||
| 9553 | Arg<A2>(*this, ArgInfo2<R,A1,A2>()), | ||
| 9554 | Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()), | ||
| 9555 | Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()) | ||
| 9556 | ).StoreResult(*this, result_dst); | ||
| 9557 | Epilog(); | ||
| 9558 | } | ||
| 9559 | }; | ||
| 9560 | |||
| 9561 | // specialization for 4 arguments and no result | ||
| 9562 | template<class Derived, class A1, class A2, class A3, class A4> | ||
| 9563 | struct function_cdecl<void, Derived, A1, A2, A3, A4, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9564 | { | ||
| 9565 | typedef void (*FuncPtr)(A1, A2, A3, A4); | ||
| 9566 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9567 | ✗ | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | |
| 9568 | ✗ | void naked_main() { | |
| 9569 | using namespace detail::calling_convention_cdecl; | ||
| 9570 | ✗ | Prolog(); | |
| 9571 | ✗ | static_cast<Derived *>(this)->main( | |
| 9572 | ✗ | Arg<A1>(*this, ArgInfo1<void,A1>()), | |
| 9573 | ✗ | Arg<A2>(*this, ArgInfo2<void,A1,A2>()), | |
| 9574 | ✗ | Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()), | |
| 9575 | ✗ | Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>())); | |
| 9576 | ✗ | Epilog(); | |
| 9577 | ✗ | } | |
| 9578 | }; | ||
| 9579 | |||
| 9580 | // specialization for 3 arguments | ||
| 9581 | template<class R, class Derived, class A1, class A2, class A3> | ||
| 9582 | struct function_cdecl<R, Derived, A1, A2, A3, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9583 | { | ||
| 9584 | typedef R (*FuncPtr)(A1, A2, A3); | ||
| 9585 | typedef detail::ResultT<R> Result; ///< main function result type | ||
| 9586 | typename detail::ResultTraits<R>::ResultPtr result_ptr; | ||
| 9587 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9588 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9589 | void naked_main() { | ||
| 9590 | using namespace detail::calling_convention_cdecl; | ||
| 9591 | Prolog(); | ||
| 9592 | detail::ResultDest result_dst(*this, ResultInfo<R>()); | ||
| 9593 | static_cast<Derived *>(this)->main( | ||
| 9594 | Arg<A1>(*this, ArgInfo1<R,A1>()), | ||
| 9595 | Arg<A2>(*this, ArgInfo2<R,A1,A2>()), | ||
| 9596 | Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()) | ||
| 9597 | ).StoreResult(*this, result_dst); | ||
| 9598 | Epilog(); | ||
| 9599 | } | ||
| 9600 | }; | ||
| 9601 | |||
| 9602 | // specialization for 3 arguments and no result | ||
| 9603 | template<class Derived, class A1, class A2, class A3> | ||
| 9604 | struct function_cdecl<void, Derived, A1, A2, A3, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9605 | { | ||
| 9606 | typedef void (*FuncPtr)(A1, A2, A3); | ||
| 9607 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9608 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9609 | void naked_main() { | ||
| 9610 | using namespace detail::calling_convention_cdecl; | ||
| 9611 | Prolog(); | ||
| 9612 | static_cast<Derived *>(this)->main( | ||
| 9613 | Arg<A1>(*this, ArgInfo1<void,A1>()), | ||
| 9614 | Arg<A2>(*this, ArgInfo2<void,A1,A2>()), | ||
| 9615 | Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>())); | ||
| 9616 | Epilog(); | ||
| 9617 | } | ||
| 9618 | }; | ||
| 9619 | |||
| 9620 | // specialization for 2 arguments | ||
| 9621 | template<class R, class Derived, class A1, class A2> | ||
| 9622 | struct function_cdecl<R, Derived, A1, A2, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9623 | { | ||
| 9624 | typedef R (*FuncPtr)(A1, A2); | ||
| 9625 | typedef detail::ResultT<R> Result; ///< main function result type | ||
| 9626 | typename detail::ResultTraits<R>::ResultPtr result_ptr; | ||
| 9627 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9628 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9629 | void naked_main() { | ||
| 9630 | using namespace detail::calling_convention_cdecl; | ||
| 9631 | Prolog(); | ||
| 9632 | detail::ResultDest result_dst(*this, ResultInfo<R>()); | ||
| 9633 | static_cast<Derived *>(this)->main( | ||
| 9634 | Arg<A1>(*this, ArgInfo1<R,A1>()), | ||
| 9635 | Arg<A2>(*this, ArgInfo2<R,A1,A2>()) | ||
| 9636 | ).StoreResult(*this, result_dst); | ||
| 9637 | Epilog(); | ||
| 9638 | } | ||
| 9639 | }; | ||
| 9640 | |||
| 9641 | // specialization for 2 arguments and no result | ||
| 9642 | template<class Derived, class A1, class A2> | ||
| 9643 | struct function_cdecl<void, Derived, A1, A2, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9644 | { | ||
| 9645 | typedef void (*FuncPtr)(A1, A2); | ||
| 9646 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9647 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9648 | void naked_main() { | ||
| 9649 | using namespace detail::calling_convention_cdecl; | ||
| 9650 | Prolog(); | ||
| 9651 | static_cast<Derived *>(this)->main( | ||
| 9652 | Arg<A1>(*this, ArgInfo1<void,A1>()), | ||
| 9653 | Arg<A2>(*this, ArgInfo2<void,A1,A2>())); | ||
| 9654 | Epilog(); | ||
| 9655 | } | ||
| 9656 | }; | ||
| 9657 | |||
| 9658 | // specialization for 1 argument | ||
| 9659 | template<class R, class Derived, class A1> | ||
| 9660 | struct function_cdecl<R, Derived, A1, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9661 | { | ||
| 9662 | typedef R (*FuncPtr)(A1); | ||
| 9663 | typedef detail::ResultT<R> Result; ///< main function result type | ||
| 9664 | typename detail::ResultTraits<R>::ResultPtr result_ptr; | ||
| 9665 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9666 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9667 | void naked_main() { | ||
| 9668 | using namespace detail::calling_convention_cdecl; | ||
| 9669 | Prolog(); | ||
| 9670 | detail::ResultDest result_dst(*this, ResultInfo<R>()); | ||
| 9671 | static_cast<Derived *>(this)->main(Arg<A1>(*this, ArgInfo1<R,A1>())).StoreResult(*this, result_dst); | ||
| 9672 | Epilog(); | ||
| 9673 | } | ||
| 9674 | }; | ||
| 9675 | |||
| 9676 | // specialization for 1 argument and no result | ||
| 9677 | template<class Derived, class A1> | ||
| 9678 | struct function_cdecl<void, Derived, A1, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9679 | { | ||
| 9680 | typedef void (*FuncPtr)(A1); | ||
| 9681 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9682 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9683 | void naked_main() { | ||
| 9684 | using namespace detail::calling_convention_cdecl; | ||
| 9685 | Prolog(); | ||
| 9686 | static_cast<Derived *>(this)->main(Arg<A1>(*this, ArgInfo1<void,A1>())); | ||
| 9687 | Epilog(); | ||
| 9688 | } | ||
| 9689 | }; | ||
| 9690 | |||
| 9691 | // specialization for no arguments | ||
| 9692 | template<class R, class Derived> | ||
| 9693 | struct function_cdecl<R, Derived, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9694 | { | ||
| 9695 | typedef R (*FuncPtr)(); | ||
| 9696 | typedef detail::ResultT<R> Result; ///< main function result type | ||
| 9697 | typename detail::ResultTraits<R>::ResultPtr result_ptr; | ||
| 9698 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9699 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9700 | void naked_main() { | ||
| 9701 | Prolog(); | ||
| 9702 | detail::ResultDest result_dst(*this, detail::calling_convention_cdecl::ResultInfo<R>()); | ||
| 9703 | static_cast<Derived *>(this)->main().StoreResult(*this, result_dst); | ||
| 9704 | Epilog(); | ||
| 9705 | } | ||
| 9706 | }; | ||
| 9707 | |||
| 9708 | // specialization for no arguments and no result | ||
| 9709 | template<class Derived> | ||
| 9710 | struct function_cdecl<void, Derived, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend | ||
| 9711 | { | ||
| 9712 | typedef void (*FuncPtr)(); | ||
| 9713 | operator FuncPtr() { return (FuncPtr)GetCode(); } | ||
| 9714 | void InternalMain() {static_cast<Derived *>(this)->naked_main();} | ||
| 9715 | void naked_main() { | ||
| 9716 | Prolog(); | ||
| 9717 | static_cast<Derived *>(this)->main(); | ||
| 9718 | Epilog(); | ||
| 9719 | } | ||
| 9720 | }; | ||
| 9721 | |||
| 9722 | |||
| 9723 | /// function | ||
| 9724 | template< | ||
| 9725 | class R, | ||
| 9726 | class Derived, | ||
| 9727 | class A1 = detail::ArgNone, | ||
| 9728 | class A2 = detail::ArgNone, | ||
| 9729 | class A3 = detail::ArgNone, | ||
| 9730 | class A4 = detail::ArgNone, | ||
| 9731 | class A5 = detail::ArgNone, | ||
| 9732 | class A6 = detail::ArgNone, | ||
| 9733 | class A7 = detail::ArgNone, | ||
| 9734 | class A8 = detail::ArgNone, | ||
| 9735 | class A9 = detail::ArgNone, | ||
| 9736 | class A10 = detail::ArgNone> | ||
| 9737 | struct function : function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> {}; | ||
| 9738 | |||
| 9739 | } // namespace jitasm | ||
| 9740 | |||
| 9741 | #if defined(_MSC_VER) | ||
| 9742 | #pragma warning( pop ) | ||
| 9743 | #endif | ||
| 9744 | |||
| 9745 | #endif // #ifndef JITASM_H | ||
| 9746 |