assembler-x64.h revision c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7a
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright (c) 1994-2006 Sun Microsystems Inc. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All Rights Reserved. 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistributions of source code must retain the above copyright notice, 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this list of conditions and the following disclaimer. 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistribution in binary form must reproduce the above copyright 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer in the 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// documentation and/or other materials provided with the distribution. 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Neither the name of Sun Microsystems or the names of contributors may 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be used to endorse or promote products derived from this software without 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// specific prior written permission. 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The original source code covered by the above license above has been 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modified significantly by Google Inc. 333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A lightweight X64 Assembler. 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_X64_ASSEMBLER_X64_H_ 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_X64_ASSEMBLER_X64_H_ 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <deque> 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/assembler.h" 43f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/x64/sse-instr.h" 44d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utility functions 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define GENERAL_REGISTERS(V) \ 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rax) \ 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rcx) \ 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rdx) \ 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rbx) \ 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rsp) \ 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rbp) \ 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rsi) \ 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rdi) \ 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r8) \ 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r9) \ 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r10) \ 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r11) \ 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r12) \ 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r13) \ 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r14) \ 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r15) 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_GENERAL_REGISTERS(V) \ 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rax) \ 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rbx) \ 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rdx) \ 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rcx) \ 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rsi) \ 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rdi) \ 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r8) \ 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r9) \ 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r11) \ 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r12) \ 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r14) \ 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r15) 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CPU Registers. 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 1) We would prefer to use an enum, but enum values are assignment- 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// compatible with int, which has caused code-generation bugs. 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 2) We would prefer to use a class instead of a struct but we don't like 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the register initialization to depend on the particular initialization 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order (which appears to be different on OS X, Linux, and Windows for the 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// installed versions of C++ we tried). Using a struct permits C-style 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "initialization". Also, the Register objects cannot be const as this 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// forces initialization stubs in MSVC, making us dependent on initialization 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order. 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 3) By not using an enum, we are possibly preventing the compiler from 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// doing certain constant folds, which may significantly reduce the 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// code generated for some assembly instructions (because they boil down 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to a few constants). If this is a problem, we could change the code 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// such that we use an enum in optimized mode, and the struct in debug 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// mode. This way we get the compile-time error checking in debug mode 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and best performance in optimized code. 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct Register { 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Code { 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R, 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GENERAL_REGISTERS(REGISTER_CODE) 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kAfterLast, 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCode_no_reg = -1 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 112b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kNumRegisters = Code::kAfterLast; 114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static Register from_code(int code) { 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(code >= 0); 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(code < kNumRegisters); 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register r = {code}; 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return r; 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is(Register reg) const { return reg_code == reg.reg_code; } 1230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int code() const { 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int bit() const { 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(is_valid()); 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 1 << reg_code; 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_byte_register() const { return reg_code <= 3; } 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the high bit of the register code as a 0 or 1. Used often 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // when constructing the REX prefix byte. 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int high_bit() const { return reg_code >> 3; } 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the 3 low bits of the register code. Used when encoding registers 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in modR/M, SIB, and opcode bytes. 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int low_bits() const { return reg_code & 0x7; } 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Unfortunately we can't make this private in a struct when initializing 1413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // by assignment. 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochGENERAL_REGISTERS(DECLARE_REGISTER) 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register no_reg = {Register::kCode_no_reg}; 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef _WIN64 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Windows calling convention 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_1 = {Register::kCode_rcx}; 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_2 = {Register::kCode_rdx}; 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_3 = {Register::kCode_r8}; 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_4 = {Register::kCode_r9}; 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // AMD64 calling convention 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_1 = {Register::kCode_rdi}; 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_2 = {Register::kCode_rsi}; 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_3 = {Register::kCode_rdx}; 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_4 = {Register::kCode_rcx}; 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // _WIN64 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DOUBLE_REGISTERS(V) \ 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm0) \ 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm1) \ 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm2) \ 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm3) \ 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm4) \ 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm5) \ 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm6) \ 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm7) \ 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm8) \ 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm9) \ 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm10) \ 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm11) \ 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm12) \ 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm13) \ 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm14) \ 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm15) 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 185bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define FLOAT_REGISTERS DOUBLE_REGISTERS 186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define SIMD128_REGISTERS DOUBLE_REGISTERS 187bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ 18913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch V(xmm0) \ 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm1) \ 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm2) \ 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm3) \ 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm4) \ 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm5) \ 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm6) \ 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm7) \ 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm8) \ 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm9) \ 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm10) \ 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm11) \ 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm12) \ 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm13) \ 20313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch V(xmm14) 20413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 20513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochstatic const bool kSimpleFPAliasing = true; 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 207bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochstruct XMMRegister { 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Code { 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R, 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DOUBLE_REGISTERS(REGISTER_CODE) 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kAfterLast, 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCode_no_reg = -1 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMaxNumRegisters = Code::kAfterLast; 217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 218bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch static XMMRegister from_code(int code) { 219bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch XMMRegister result = {code}; 220b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return result; 221b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 222b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; } 224bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool is(XMMRegister reg) const { return reg_code == reg.reg_code; } 2250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int code() const { 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the high bit of the register code as a 0 or 1. Used often 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // when constructing the REX prefix byte. 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int high_bit() const { return reg_code >> 3; } 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the 3 low bits of the register code. Used when encoding registers 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in modR/M, SIB, and opcode bytes. 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int low_bits() const { return reg_code & 0x7; } 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unfortunately we can't make this private in a struct when initializing 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // by assignment. 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 242bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtypedef XMMRegister FloatRegister; 243bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 244bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtypedef XMMRegister DoubleRegister; 245bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 246bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtypedef XMMRegister Simd128Register; 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) \ 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const DoubleRegister R = {DoubleRegister::kCode_##R}; 250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDOUBLE_REGISTERS(DECLARE_REGISTER) 251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER 252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg}; 253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum Condition { 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // any value < 0 is considered no_condition 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block no_condition = -1, 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block overflow = 0, 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block no_overflow = 1, 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block below = 2, 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block above_equal = 3, 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block equal = 4, 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_equal = 5, 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block below_equal = 6, 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block above = 7, 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block negative = 8, 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block positive = 9, 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parity_even = 10, 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parity_odd = 11, 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block less = 12, 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block greater_equal = 13, 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block less_equal = 14, 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block greater = 15, 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Fake conditions that are handled by the 2763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // opcodes using them. 2773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block always = 16, 2783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block never = 17, 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // aliases 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block carry = below, 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_carry = above_equal, 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block zero = equal, 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_zero = not_equal, 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sign = negative, 2853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block not_sign = positive, 2863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block last_condition = greater 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns the equivalent of !cc. 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Negation of the default no_condition (-1) results in a non-default 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// no_condition value (-2). As long as tests for no_condition check 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for condition < 0, this will work as expected. 2949dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monseninline Condition NegateCondition(Condition cc) { 2959dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return static_cast<Condition>(cc ^ 1); 2969dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 2979dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Commute a condition such that {a cond b == b cond' a}. 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline Condition CommuteCondition(Condition cc) { 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (cc) { 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case below: 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return above; 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case above: 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return below; 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case above_equal: 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return below_equal; 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case below_equal: 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return above_equal; 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case less: 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return greater; 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case greater: 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return less; 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case greater_equal: 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return less_equal; 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case less_equal: 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return greater_equal; 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return cc; 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3239dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum RoundingMode { 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundToNearest = 0x0, 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundDown = 0x1, 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundUp = 0x2, 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundToZero = 0x3 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Machine instruction Immediates 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Immediate BASE_EMBEDDED { 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit Immediate(int32_t value) : value_(value) {} 338bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch explicit Immediate(int32_t value, RelocInfo::Mode rmode) 339bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch : value_(value), rmode_(rmode) {} 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit Immediate(Smi* value) { 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); // Only available for 31-bit SMI. 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ = static_cast<int32_t>(reinterpret_cast<intptr_t>(value)); 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t value_; 347bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch RelocInfo::Mode rmode_ = RelocInfo::NONE32; 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class Assembler; 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Machine instruction Operands 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum ScaleFactor { 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_1 = 0, 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_2 = 1, 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_4 = 2, 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_8 = 3, 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_int_size = times_4, 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_pointer_size = (kPointerSize == 8) ? times_8 : times_4 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Operand BASE_EMBEDDED { 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + disp/r] 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Operand(Register base, int32_t disp); 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + index*scale + disp/r] 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Operand(Register base, 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register index, 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t disp); 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [index*scale + disp/r] 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Operand(Register index, 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t disp); 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 382f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Offset from existing memory operand. 383f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Offset is added to existing displacement as 32-bit signed values and 384f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // this must not overflow. 385f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand(const Operand& base, int32_t offset); 386f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // [rip + disp/r] 388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit Operand(Label* label); 389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Checks whether either base or index register is the given register. 3911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Does not check the "reg" part of the Operand. 3921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool AddressUsesRegister(Register reg) const; 3931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 39444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Queries related to the size of the generated instruction. 39544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Whether the generated instruction will have a REX prefix. 39644f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool requires_rex() const { return rex_ != 0; } 39744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Size of the ModR/M, SIB and displacement parts of the generated 39844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // instruction. 39944f0eee88ff00398ff7f715fab053374d808c90dSteve Block int operand_size() const { return len_; } 40044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte rex_; 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch byte buf_[9]; 4041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The number of bytes of buf_ in use. 4051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block byte len_; 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the ModR/M byte without an encoded 'reg' register. The 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register is encoded later as part of the emit_operand operation. 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // set_modrm can be called before or after set_sib and set_disp*. 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_modrm(int mod, Register rm); 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the SIB byte if one is needed. Sets the length to 2 rather than 1. 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_sib(ScaleFactor scale, Register index, Register base); 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Adds operand displacement fields (offsets added to the memory address). 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Needs to be called after set_sib, not before it. 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_disp8(int disp); 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_disp32(int disp); 419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void set_disp64(int64_t disp); // for labels. 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class Assembler; 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ASSEMBLER_INSTRUCTION_LIST(V) \ 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(add) \ 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(and) \ 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(cmp) \ 42813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch V(cmpxchg) \ 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(dec) \ 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(idiv) \ 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(div) \ 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(imul) \ 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(inc) \ 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(lea) \ 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(mov) \ 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(movzxb) \ 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(movzxw) \ 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(neg) \ 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(not) \ 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(or) \ 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(repmovs) \ 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(sbb) \ 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(sub) \ 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(test) \ 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(xchg) \ 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(xor) 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shift instructions on operands/registers with kPointerSize, kInt32Size and 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// kInt64Size. 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define SHIFT_INSTRUCTION_LIST(V) \ 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(rol, 0x0) \ 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(ror, 0x1) \ 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(rcl, 0x2) \ 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(rcr, 0x3) \ 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(shl, 0x4) \ 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(shr, 0x5) \ 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(sar, 0x7) \ 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Assembler : public AssemblerBase { 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We check before assembling an instruction that there is sufficient 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // space to write an instruction and its relocation information. 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The relocation writer's position must be kGap bytes above the end of 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the generated instructions. This leaves enough space for the 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // longest possible x64 instruction, 15 bytes, and the longest possible 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // relocation information encoding, RelocInfoWriter::kMaxLength == 16. 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // (There is a 15 byte limit on x64 instruction length that rules out some 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // otherwise valid instructions.) 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This allows for a single, fast space check per instruction. 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kGap = 32; 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create an assembler. Instructions and relocation information are emitted 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // into a buffer, with the instructions starting from the beginning and the 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // relocation information starting from the end of the buffer. See CodeDesc 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // for a detailed comment on the layout (globals.h). 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the provided buffer is NULL, the assembler allocates and grows its own 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // buffer, and buffer_size determines the initial buffer size. The buffer is 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // owned by the assembler and deallocated upon destruction of the assembler. 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the provided buffer is not NULL, the assembler uses the provided buffer 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // for code generation and assumes its size to be buffer_size. If the buffer 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is too small, a fatal error occurs. No deallocation of the buffer is done 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // upon destruction of the assembler. 4878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Assembler(Isolate* isolate, void* buffer, int buffer_size); 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~Assembler() { } 48944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // GetCode emits any pending (non-emitted) code and fills the descriptor 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // desc. GetCode() is idempotent; it returns the same result if no other 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Assembler functions are invoked in between GetCode() calls. 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void GetCode(CodeDesc* desc); 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Read/Modify the code target in the relative branch/call instruction at pc. 4963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // On the x64 architecture, we use relative jumps with a 32-bit displacement 4973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // to jump to other Code objects in the Code space in the heap. 4983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Jumps to C functions are done indirectly through a 64-bit register holding 4993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // the absolute address of the target. 5003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // These functions convert between absolute Addresses of Code objects and 5013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // the relative displacements stored in the code. 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline Address target_address_at(Address pc, Address constant_pool); 503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void set_target_address_at( 504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address constant_pool, Address target, 505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline Address target_address_at(Address pc, Code* code) { 507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return target_address_at(pc, constant_pool); 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void set_target_address_at( 511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Code* code, Address target, 512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED) { 513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_target_address_at(isolate, pc, constant_pool, target, 515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch icache_flush_mode); 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the code target address at a call site from the return address 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of that call in the instruction stream. 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline Address target_address_from_return_address(Address pc); 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 522d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This sets the branch destination (which is in the instruction on x64). 523d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This is for calls and branches within generated code. 5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline static void deserialization_set_special_target_at( 525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address instruction_payload, Code* code, 526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address target) { 527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_target_address_at(isolate, instruction_payload, code, target); 528d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 529d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This sets the internal reference at the pc. 531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline static void deserialization_set_target_internal_reference_at( 532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address target, 533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline RelocInfo::Mode RelocInfoNone() { 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return RelocInfo::NONE64; 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kPointerSize == kInt32Size); 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return RelocInfo::NONE32; 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 542d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 543d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block inline Handle<Object> code_target_object_handle_at(Address pc); 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Address runtime_entry_at(Address pc); 546d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Number of bytes taken up by the branch target in the code. 5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kSpecialTargetSize = 4; // Use 32-bit displacement. 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Distance between the address of the code target in the call instruction 5493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // and the return address pushed on the stack. 5503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement. 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The length of call(kScratchRegister). 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kCallScratchRegisterInstructionLength = 3; 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The length of call(Immediate32). 5541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const int kShortCallInstructionLength = 5; 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The length of movq(kScratchRegister, address). 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kMoveAddressIntoScratchRegisterInstructionLength = 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2 + kPointerSize; 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The length of movq(kScratchRegister, address) and call(kScratchRegister). 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kCallSequenceLength = 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMoveAddressIntoScratchRegisterInstructionLength + 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kCallScratchRegisterInstructionLength; 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The debug break slot must be able to contain an indirect call sequence. 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kDebugBreakSlotLength = kCallSequenceLength; 565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Distance between start of patched debug break slot and the emitted address 566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to jump to. 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kPatchDebugBreakSlotAddressOffset = 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMoveAddressIntoScratchRegisterInstructionLength - kPointerSize; 5697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5709fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block // One byte opcode for test eax,0xXXXXXXXX. 5719fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block static const byte kTestEaxByte = 0xA9; 5721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // One byte opcode for test al, 0xXX. 5731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kTestAlByte = 0xA8; 5741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // One byte opcode for nop. 5751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kNopByte = 0x90; 5761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // One byte prefix for a short conditional jump. 5781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kJccShortPrefix = 0x70; 5791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kJncShortOpcode = kJccShortPrefix | not_carry; 5801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kJcShortOpcode = kJccShortPrefix | carry; 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kJnzShortOpcode = kJccShortPrefix | not_zero; 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kJzShortOpcode = kJccShortPrefix | zero; 5831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // VEX prefix encodings. 585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 }; 586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128, kLZ = kL128 }; 587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 }; 588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x3 }; 5897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Code generation 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Function names correspond one-to-one to x64 instruction mnemonics. 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Unless specified otherwise, instructions operate on 64-bit operands. 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we need versions of an assembly instruction that operate on different 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // width arguments, we add a single-letter suffix specifying the width. 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This is done for the following instructions: mov, cmp, inc, dec, 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // add, sub, and test. 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // There are no versions of these instructions without the suffix. 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - Instructions on 32-bit (doubleword) operands/registers use 'l'. 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - Instructions on 64-bit (quadword) operands/registers use 'q'. 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - Instructions on operands/registers with pointer size use 'p'. 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size); 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARE_INSTRUCTION(instruction) \ 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1> \ 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##p(P1 p1) { \ 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, kPointerSize); \ 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1> \ 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##l(P1 p1) { \ 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, kInt32Size); \ 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1> \ 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##q(P1 p1) { \ 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, kInt64Size); \ 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2> \ 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##p(P1 p1, P2 p2) { \ 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, p2, kPointerSize); \ 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2> \ 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##l(P1 p1, P2 p2) { \ 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, p2, kInt32Size); \ 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2> \ 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##q(P1 p1, P2 p2) { \ 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, p2, kInt64Size); \ 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2, class P3> \ 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##p(P1 p1, P2 p2, P3 p3) { \ 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, p2, p3, kPointerSize); \ 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2, class P3> \ 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##l(P1 p1, P2 p2, P3 p3) { \ 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, p2, p3, kInt32Size); \ 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2, class P3> \ 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##q(P1 p1, P2 p2, P3 p3) { \ 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, p2, p3, kInt64Size); \ 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION) 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_INSTRUCTION 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Insert the smallest number of nop instructions 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // possible to align the pc offset to a multiple 6591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // of m, where m must be a power of 2. 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Align(int m); 661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Insert the smallest number of zero bytes possible to align the pc offset 662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to a mulitple of m. m must be a power of 2 (>= 2). 663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DataAlign(int m); 6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Nop(int bytes = 1); 6659dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Aligns code to something that's optimal for a jump target for the platform. 6669dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen void CodeTargetAlign(); 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stack 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void pushfq(); 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void popfq(); 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pushq(Immediate value); 6731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Push a 32 bit integer, and guarantee that it is actually pushed as a 6741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // 32 bit value, the normal push will optimize the 8 bit case. 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pushq_imm32(int32_t imm32); 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pushq(Register src); 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pushq(const Operand& src); 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void popq(Register dst); 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void popq(const Operand& dst); 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void enter(Immediate size); 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void leave(); 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Moves 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movb(Register dst, const Operand& src); 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movb(Register dst, Immediate imm); 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movb(const Operand& dst, Register src); 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movb(const Operand& dst, Immediate imm); 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Move the low 16 bits of a 64-bit register value to a 16-bit 6923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // memory location. 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movw(Register dst, const Operand& src); 6943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void movw(const Operand& dst, Register src); 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movw(const Operand& dst, Immediate imm); 6963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move the offset of the label location relative to the current 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // position (after the move) to the destination. 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movl(const Operand& dst, Label* src); 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loads a pointer into a register with a relocation mode. 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movp(Register dst, void* ptr, RelocInfo::Mode rmode); 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loads a 64-bit immediate into a register. 7053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void movq(Register dst, int64_t value, 7063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RelocInfo::Mode rmode = RelocInfo::NONE64); 7073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void movq(Register dst, uint64_t value, 7083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RelocInfo::Mode rmode = RelocInfo::NONE64); 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void movsxbl(Register dst, Register src); 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movsxbl(Register dst, const Operand& src); 712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void movsxbq(Register dst, Register src); 7133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void movsxbq(Register dst, const Operand& src); 714958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void movsxwl(Register dst, Register src); 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movsxwl(Register dst, const Operand& src); 716f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void movsxwq(Register dst, Register src); 7173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void movsxwq(Register dst, const Operand& src); 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movsxlq(Register dst, Register src); 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movsxlq(Register dst, const Operand& src); 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 721d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Repeated moves. 722d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 723d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void repmovsb(); 724d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void repmovsw(); 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void repmovsp() { emit_repmovs(kPointerSize); } 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void repmovsl() { emit_repmovs(kInt32Size); } 727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void repmovsq() { emit_repmovs(kInt64Size); } 728d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 72944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Instruction to load from an immediate 64-bit pointer into RAX. 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void load_rax(void* ptr, RelocInfo::Mode rmode); 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void load_rax(ExternalReference ext); 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Conditional moves. 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmovq(Condition cc, Register dst, Register src); 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmovq(Condition cc, Register dst, const Operand& src); 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmovl(Condition cc, Register dst, Register src); 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmovl(Condition cc, Register dst, const Operand& src); 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(Register dst, Immediate src) { 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_8(0x7, dst, src); 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb_al(Immediate src); 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(Register dst, Register src) { 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op_8(0x3A, dst, src); 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(Register dst, const Operand& src) { 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op_8(0x3A, dst, src); 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(const Operand& dst, Register src) { 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op_8(0x38, src, dst); 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(const Operand& dst, Immediate src) { 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_8(0x7, dst, src); 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(const Operand& dst, Immediate src) { 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_16(0x7, dst, src); 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(Register dst, Immediate src) { 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_16(0x7, dst, src); 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(Register dst, const Operand& src) { 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_16(0x3B, dst, src); 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(Register dst, Register src) { 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_16(0x3B, dst, src); 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(const Operand& dst, Register src) { 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_16(0x39, src, dst); 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void testb(Register reg, const Operand& op) { testb(op, reg); } 7823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 7833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void testw(Register reg, const Operand& op) { testw(op, reg); } 7843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 7854515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke void andb(Register dst, Immediate src) { 7864515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke immediate_arithmetic_op_8(0x4, dst, src); 7874515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 7883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void decb(Register dst); 7903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void decb(const Operand& dst); 791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 79213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Lock prefix. 79313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void lock(); 79413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 795bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void xchgb(Register reg, const Operand& op); 796bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void xchgw(Register reg, const Operand& op); 797bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 79813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void cmpxchgb(const Operand& dst, Register src); 79913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void cmpxchgw(const Operand& dst, Register src); 80013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Sign-extends rax into rdx:rax. 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cqo(); 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Sign-extends eax into edx:eax. 804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cdq(); 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 806958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Multiply eax by src, put the result in edx:eax. 807958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mull(Register src); 808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mull(const Operand& src); 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Multiply rax by src, put the result in rdx:rax. 810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mulq(Register src); 811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode) \ 813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##p(Register dst, Immediate imm8) { \ 814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier shift(dst, imm8, subcode, kPointerSize); \ 815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 816958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##l(Register dst, Immediate imm8) { \ 818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier shift(dst, imm8, subcode, kInt32Size); \ 819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##q(Register dst, Immediate imm8) { \ 822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier shift(dst, imm8, subcode, kInt64Size); \ 823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##p(Operand dst, Immediate imm8) { \ 826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier shift(dst, imm8, subcode, kPointerSize); \ 827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 828958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##l(Operand dst, Immediate imm8) { \ 830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier shift(dst, imm8, subcode, kInt32Size); \ 831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##q(Operand dst, Immediate imm8) { \ 834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier shift(dst, imm8, subcode, kInt64Size); \ 835958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##p_cl(Register dst) { shift(dst, subcode, kPointerSize); } \ 838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##l_cl(Register dst) { shift(dst, subcode, kInt32Size); } \ 840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##q_cl(Register dst) { shift(dst, subcode, kInt64Size); } \ 842958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 843958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##p_cl(Operand dst) { shift(dst, subcode, kPointerSize); } \ 844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##l_cl(Operand dst) { shift(dst, subcode, kInt32Size); } \ 846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##q_cl(Operand dst) { shift(dst, subcode, kInt64Size); } 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION) 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_SHIFT_INSTRUCTION 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shifts dst:src left by cl bits, affecting only dst. 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shld(Register dst, Register src); 853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shifts src:dst right by cl bits, affecting only dst. 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shrd(Register dst, Register src); 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void store_rax(void* dst, RelocInfo::Mode mode); 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void store_rax(ExternalReference ref); 859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subb(Register dst, Immediate src) { 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_8(0x5, dst, src); 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void testb(Register dst, Register src); 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void testb(Register reg, Immediate mask); 866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void testb(const Operand& op, Immediate mask); 867e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void testb(const Operand& op, Register reg); 868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void testw(Register dst, Register src); 8703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void testw(Register reg, Immediate mask); 8713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void testw(const Operand& op, Immediate mask); 8723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void testw(const Operand& op, Register reg); 8733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bit operations. 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bt(const Operand& dst, Register src); 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bts(const Operand& dst, Register src); 877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsrq(Register dst, Register src); 878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsrq(Register dst, const Operand& src); 879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bsrl(Register dst, Register src); 880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsrl(Register dst, const Operand& src); 881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsfq(Register dst, Register src); 882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsfq(Register dst, const Operand& src); 883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsfl(Register dst, Register src); 884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsfl(Register dst, const Operand& src); 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Miscellaneous 8873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void clc(); 88844f0eee88ff00398ff7f715fab053374d808c90dSteve Block void cld(); 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cpuid(); 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void hlt(); 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void int3(); 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void nop(); 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ret(int imm16); 894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ud2(); 895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void setcc(Condition cc, Register reg); 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Label operations & relative jumps (PPUM Appendix D) 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Takes a branch opcode (cc) and a label (L) and generates 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // either a backward branch or a forward branch and links it 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to the label fixup chain. Usage: 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Label L; // unbound label 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // j(cc, &L); // forward branch to unbound label 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bind(&L); // bind label to the current pc 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // j(cc, &L); // backward branch to bound label 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bind(&L); // illegal: a label may be bound only once 908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note: The same Label can be used for forward and backward branches 910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // but it may be bound only once. 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bind(Label* L); // binds an unbound label L to the current code position 913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calls 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call near relative 32-bit displacement, relative to next instruction. 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void call(Label* L); 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void call(Address entry, RelocInfo::Mode rmode); 918257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void call(Handle<Code> target, 9193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch RelocInfo::Mode rmode = RelocInfo::CODE_TARGET, 920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId ast_id = TypeFeedbackId::None()); 921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Calls directly to the given address using a relative offset. 9231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Should only ever be used in Code objects for calls within the 9241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // same Code object. Should not be used when generating new code (use labels), 9251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // but only when patching existing code. 9261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void call(Address target); 9271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call near absolute indirect, address in register 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void call(Register adr); 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Jumps 932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Jump short or near relative. 9333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Use a 32-bit signed displacement. 934257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Unconditional jump to L 935257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void jmp(Label* L, Label::Distance distance = Label::kFar); 936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void jmp(Address entry, RelocInfo::Mode rmode); 9373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void jmp(Handle<Code> target, RelocInfo::Mode rmode); 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Jump near absolute indirect (r64) 940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void jmp(Register adr); 941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void jmp(const Operand& src); 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Conditional jumps 944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void j(Condition cc, 945257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* L, 946257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance distance = Label::kFar); 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void j(Condition cc, Address entry, RelocInfo::Mode rmode); 9483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode); 949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Floating-point operations 951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld(int i); 952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld1(); 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fldz(); 9556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void fldpi(); 956b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void fldln2(); 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld_s(const Operand& adr); 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld_d(const Operand& adr); 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fstp_s(const Operand& adr); 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fstp_d(const Operand& adr); 9633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void fstp(int index); 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fild_s(const Operand& adr); 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fild_d(const Operand& adr); 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fist_s(const Operand& adr); 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fistp_s(const Operand& adr); 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fistp_d(const Operand& adr); 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fisttp_s(const Operand& adr); 974d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void fisttp_d(const Operand& adr); 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fabs(); 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fchs(); 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fadd(int i); 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsub(int i); 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fmul(int i); 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fdiv(int i); 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fisub_s(const Operand& adr); 985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void faddp(int i = 1); 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsubp(int i = 1); 988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsubrp(int i = 1); 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fmulp(int i = 1); 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fdivp(int i = 1); 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fprem(); 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fprem1(); 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fxch(int i = 1); 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fincstp(); 996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ffree(int i = 0); 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ftst(); 999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fucomp(int i); 1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fucompp(); 10013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void fucomi(int i); 10023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void fucomip(); 10033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fcompp(); 1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fnstsw_ax(); 1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fwait(); 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fnclex(); 1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsin(); 1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fcos(); 10113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void fptan(); 1012b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void fyl2x(); 10133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void f2xm1(); 10143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void fscale(); 10153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void fninit(); 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void frndint(); 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void sahf(); 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // SSE instructions 1022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void addss(XMMRegister dst, XMMRegister src); 1023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void addss(XMMRegister dst, const Operand& src); 1024958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void subss(XMMRegister dst, XMMRegister src); 1025958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void subss(XMMRegister dst, const Operand& src); 1026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mulss(XMMRegister dst, XMMRegister src); 1027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mulss(XMMRegister dst, const Operand& src); 1028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void divss(XMMRegister dst, XMMRegister src); 1029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void divss(XMMRegister dst, const Operand& src); 1030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxss(XMMRegister dst, XMMRegister src); 1032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxss(XMMRegister dst, const Operand& src); 1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void minss(XMMRegister dst, XMMRegister src); 1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void minss(XMMRegister dst, const Operand& src); 1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sqrtss(XMMRegister dst, XMMRegister src); 1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sqrtss(XMMRegister dst, const Operand& src); 1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1039958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ucomiss(XMMRegister dst, XMMRegister src); 1040958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ucomiss(XMMRegister dst, const Operand& src); 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movaps(XMMRegister dst, XMMRegister src); 1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Don't use this unless it's important to keep the 1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // top half of the destination register unchanged. 1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use movaps when moving float values and movd for integer 1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // values in xmm registers. 1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void movss(XMMRegister dst, XMMRegister src); 1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movss(XMMRegister dst, const Operand& src); 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movss(const Operand& dst, XMMRegister src); 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shufps(XMMRegister dst, XMMRegister src, byte imm8); 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvttss2si(Register dst, const Operand& src); 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvttss2si(Register dst, XMMRegister src); 1055109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void cvtlsi2ss(XMMRegister dst, const Operand& src); 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvtlsi2ss(XMMRegister dst, Register src); 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void andps(XMMRegister dst, XMMRegister src); 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void andps(XMMRegister dst, const Operand& src); 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void orps(XMMRegister dst, XMMRegister src); 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void orps(XMMRegister dst, const Operand& src); 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xorps(XMMRegister dst, XMMRegister src); 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xorps(XMMRegister dst, const Operand& src); 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void addps(XMMRegister dst, XMMRegister src); 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void addps(XMMRegister dst, const Operand& src); 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void subps(XMMRegister dst, XMMRegister src); 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void subps(XMMRegister dst, const Operand& src); 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mulps(XMMRegister dst, XMMRegister src); 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mulps(XMMRegister dst, const Operand& src); 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void divps(XMMRegister dst, XMMRegister src); 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void divps(XMMRegister dst, const Operand& src); 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movmskps(Register dst, XMMRegister src); 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1076f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vinstr(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2, 1077f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch SIMDPrefix pp, LeadingOpcode m, VexW w); 1078f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vinstr(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2, 1079f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch SIMDPrefix pp, LeadingOpcode m, VexW w); 1080f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // SSE2 instructions 1082f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void sse2_instr(XMMRegister dst, XMMRegister src, byte prefix, byte escape, 1083f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch byte opcode); 1084f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void sse2_instr(XMMRegister dst, const Operand& src, byte prefix, byte escape, 1085f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch byte opcode); 1086f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define DECLARE_SSE2_INSTRUCTION(instruction, prefix, escape, opcode) \ 1087f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void instruction(XMMRegister dst, XMMRegister src) { \ 1088f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch sse2_instr(dst, src, 0x##prefix, 0x##escape, 0x##opcode); \ 1089f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } \ 1090f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void instruction(XMMRegister dst, const Operand& src) { \ 1091f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch sse2_instr(dst, src, 0x##prefix, 0x##escape, 0x##opcode); \ 1092f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1093f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1094f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch SSE2_INSTRUCTION_LIST(DECLARE_SSE2_INSTRUCTION) 1095f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef DECLARE_SSE2_INSTRUCTION 1096f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1097f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define DECLARE_SSE2_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \ 1098f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void v##instruction(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ 1099f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0); \ 1100f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } \ 1101f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void v##instruction(XMMRegister dst, XMMRegister src1, \ 1102f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const Operand& src2) { \ 1103f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0); \ 1104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1105f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1106f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch SSE2_INSTRUCTION_LIST(DECLARE_SSE2_AVX_INSTRUCTION) 1107f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef DECLARE_SSE2_AVX_INSTRUCTION 1108f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1109f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // SSE3 1110f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void lddqu(XMMRegister dst, const Operand& src); 1111f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1112f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // SSSE3 1113f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void ssse3_instr(XMMRegister dst, XMMRegister src, byte prefix, byte escape1, 1114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch byte escape2, byte opcode); 1115f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void ssse3_instr(XMMRegister dst, const Operand& src, byte prefix, 1116f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch byte escape1, byte escape2, byte opcode); 1117f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1118f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define DECLARE_SSSE3_INSTRUCTION(instruction, prefix, escape1, escape2, \ 1119f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch opcode) \ 1120f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void instruction(XMMRegister dst, XMMRegister src) { \ 1121f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ssse3_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \ 1122f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } \ 1123f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void instruction(XMMRegister dst, const Operand& src) { \ 1124f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ssse3_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \ 1125f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1126f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1127f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch SSSE3_INSTRUCTION_LIST(DECLARE_SSSE3_INSTRUCTION) 1128f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef DECLARE_SSSE3_INSTRUCTION 1129f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1130f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // SSE4 1131f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void sse4_instr(XMMRegister dst, XMMRegister src, byte prefix, byte escape1, 1132f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch byte escape2, byte opcode); 1133f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void sse4_instr(XMMRegister dst, const Operand& src, byte prefix, 1134f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch byte escape1, byte escape2, byte opcode); 1135f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define DECLARE_SSE4_INSTRUCTION(instruction, prefix, escape1, escape2, \ 1136f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch opcode) \ 1137f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void instruction(XMMRegister dst, XMMRegister src) { \ 1138f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \ 1139f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } \ 1140f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void instruction(XMMRegister dst, const Operand& src) { \ 1141f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \ 1142f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1143f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1144f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch SSE4_INSTRUCTION_LIST(DECLARE_SSE4_INSTRUCTION) 1145f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef DECLARE_SSE4_INSTRUCTION 1146f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1147f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define DECLARE_SSE34_AVX_INSTRUCTION(instruction, prefix, escape1, escape2, \ 1148f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch opcode) \ 1149f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void v##instruction(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ 1150f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0); \ 1151f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } \ 1152f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void v##instruction(XMMRegister dst, XMMRegister src1, \ 1153f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const Operand& src2) { \ 1154f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0); \ 1155f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1156f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch SSSE3_INSTRUCTION_LIST(DECLARE_SSE34_AVX_INSTRUCTION) 1158f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch SSE4_INSTRUCTION_LIST(DECLARE_SSE34_AVX_INSTRUCTION) 1159f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef DECLARE_SSE34_AVX_INSTRUCTION 1160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 11616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movd(XMMRegister dst, Register src); 1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void movd(XMMRegister dst, const Operand& src); 11636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movd(Register dst, XMMRegister src); 11646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movq(XMMRegister dst, Register src); 11656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movq(Register dst, XMMRegister src); 1166257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void movq(XMMRegister dst, XMMRegister src); 11676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1168257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Don't use this unless it's important to keep the 1169257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // top half of the destination register unchanged. 1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use movapd when moving double values and movq for integer 1171257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // values in xmm registers. 1172053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block void movsd(XMMRegister dst, XMMRegister src); 1173257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1174257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void movsd(const Operand& dst, XMMRegister src); 11756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movsd(XMMRegister dst, const Operand& src); 1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void movdqa(const Operand& dst, XMMRegister src); 11781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void movdqa(XMMRegister dst, const Operand& src); 11791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movdqu(const Operand& dst, XMMRegister src); 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movdqu(XMMRegister dst, const Operand& src); 1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1183257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void movapd(XMMRegister dst, XMMRegister src); 1184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void movupd(XMMRegister dst, const Operand& src); 1185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void movupd(const Operand& dst, XMMRegister src); 1186257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void psllq(XMMRegister reg, byte imm8); 1188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void psrlq(XMMRegister reg, byte imm8); 1189f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void psllw(XMMRegister reg, byte imm8); 1190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void pslld(XMMRegister reg, byte imm8); 1191f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void psrlw(XMMRegister reg, byte imm8); 1192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void psrld(XMMRegister reg, byte imm8); 1193f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void psraw(XMMRegister reg, byte imm8); 1194f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void psrad(XMMRegister reg, byte imm8); 11958defd9ff6930b4e24729971a61cf7469daf119beSteve Block 1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvttsd2si(Register dst, const Operand& src); 11971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void cvttsd2si(Register dst, XMMRegister src); 1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void cvttss2siq(Register dst, XMMRegister src); 1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void cvttss2siq(Register dst, const Operand& src); 120025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen void cvttsd2siq(Register dst, XMMRegister src); 1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvttsd2siq(Register dst, const Operand& src); 1202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvtlsi2sd(XMMRegister dst, const Operand& src); 1204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvtlsi2sd(XMMRegister dst, Register src); 1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void cvtqsi2ss(XMMRegister dst, const Operand& src); 1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void cvtqsi2ss(XMMRegister dst, Register src); 1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvtqsi2sd(XMMRegister dst, const Operand& src); 1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvtqsi2sd(XMMRegister dst, Register src); 1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12128defd9ff6930b4e24729971a61cf7469daf119beSteve Block 12136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void cvtss2sd(XMMRegister dst, XMMRegister src); 12148defd9ff6930b4e24729971a61cf7469daf119beSteve Block void cvtss2sd(XMMRegister dst, const Operand& src); 12158defd9ff6930b4e24729971a61cf7469daf119beSteve Block void cvtsd2ss(XMMRegister dst, XMMRegister src); 1216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cvtsd2ss(XMMRegister dst, const Operand& src); 12178defd9ff6930b4e24729971a61cf7469daf119beSteve Block 12188defd9ff6930b4e24729971a61cf7469daf119beSteve Block void cvtsd2si(Register dst, XMMRegister src); 12198defd9ff6930b4e24729971a61cf7469daf119beSteve Block void cvtsd2siq(Register dst, XMMRegister src); 12206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void addsd(XMMRegister dst, XMMRegister src); 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void addsd(XMMRegister dst, const Operand& src); 1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subsd(XMMRegister dst, XMMRegister src); 1224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void subsd(XMMRegister dst, const Operand& src); 1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mulsd(XMMRegister dst, XMMRegister src); 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mulsd(XMMRegister dst, const Operand& src); 1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void divsd(XMMRegister dst, XMMRegister src); 1228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void divsd(XMMRegister dst, const Operand& src); 1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxsd(XMMRegister dst, XMMRegister src); 1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxsd(XMMRegister dst, const Operand& src); 1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void minsd(XMMRegister dst, XMMRegister src); 1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void minsd(XMMRegister dst, const Operand& src); 1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1235e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void andpd(XMMRegister dst, XMMRegister src); 1236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void andpd(XMMRegister dst, const Operand& src); 1237e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void orpd(XMMRegister dst, XMMRegister src); 1238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void orpd(XMMRegister dst, const Operand& src); 1239402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void xorpd(XMMRegister dst, XMMRegister src); 1240f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void xorpd(XMMRegister dst, const Operand& src); 12416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void sqrtsd(XMMRegister dst, XMMRegister src); 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sqrtsd(XMMRegister dst, const Operand& src); 1243402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1244402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void ucomisd(XMMRegister dst, XMMRegister src); 12458defd9ff6930b4e24729971a61cf7469daf119beSteve Block void ucomisd(XMMRegister dst, const Operand& src); 1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmpltsd(XMMRegister dst, XMMRegister src); 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movmskpd(Register dst, XMMRegister src); 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void punpckldq(XMMRegister dst, XMMRegister src); 125113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void punpckldq(XMMRegister dst, const Operand& src); 1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void punpckhdq(XMMRegister dst, XMMRegister src); 1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // SSE 4.1 instruction 125513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void insertps(XMMRegister dst, XMMRegister src, byte imm8); 1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void extractps(Register dst, XMMRegister src, byte imm8); 1257f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void pextrb(Register dst, XMMRegister src, int8_t imm8); 1258f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void pextrb(const Operand& dst, XMMRegister src, int8_t imm8); 1259f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void pextrw(Register dst, XMMRegister src, int8_t imm8); 1260f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void pextrw(const Operand& dst, XMMRegister src, int8_t imm8); 1261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pextrd(Register dst, XMMRegister src, int8_t imm8); 1262f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void pextrd(const Operand& dst, XMMRegister src, int8_t imm8); 1263f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void pinsrb(XMMRegister dst, Register src, int8_t imm8); 1264f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void pinsrb(XMMRegister dst, const Operand& src, int8_t imm8); 1265f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void pinsrw(XMMRegister dst, Register src, int8_t imm8); 1266f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void pinsrw(XMMRegister dst, const Operand& src, int8_t imm8); 1267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pinsrd(XMMRegister dst, Register src, int8_t imm8); 1268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pinsrd(XMMRegister dst, const Operand& src, int8_t imm8); 1269257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void roundss(XMMRegister dst, XMMRegister src, RoundingMode mode); 1271257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode); 1272257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 127313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void cmpps(XMMRegister dst, XMMRegister src, int8_t cmp); 1274f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void cmpps(XMMRegister dst, const Operand& src, int8_t cmp); 1275f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void cmppd(XMMRegister dst, XMMRegister src, int8_t cmp); 1276f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void cmppd(XMMRegister dst, const Operand& src, int8_t cmp); 1277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1278f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define SSE_CMP_P(instr, imm8) \ 1279f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void instr##ps(XMMRegister dst, XMMRegister src) { cmpps(dst, src, imm8); } \ 1280f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void instr##ps(XMMRegister dst, const Operand& src) { \ 1281f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cmpps(dst, src, imm8); \ 1282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } \ 1283f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void instr##pd(XMMRegister dst, XMMRegister src) { cmppd(dst, src, imm8); } \ 1284f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void instr##pd(XMMRegister dst, const Operand& src) { cmppd(dst, src, imm8); } 1285f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1286f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SSE_CMP_P(cmpeq, 0x0); 1287f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SSE_CMP_P(cmplt, 0x1); 1288f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SSE_CMP_P(cmple, 0x2); 1289f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SSE_CMP_P(cmpneq, 0x4); 1290f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SSE_CMP_P(cmpnlt, 0x5); 1291f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SSE_CMP_P(cmpnle, 0x6); 1292f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1293f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#undef SSE_CMP_P 129413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 129513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void minps(XMMRegister dst, XMMRegister src); 129613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void minps(XMMRegister dst, const Operand& src); 129713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void maxps(XMMRegister dst, XMMRegister src); 129813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void maxps(XMMRegister dst, const Operand& src); 129913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void rcpps(XMMRegister dst, XMMRegister src); 130013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void rcpps(XMMRegister dst, const Operand& src); 130113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void rsqrtps(XMMRegister dst, XMMRegister src); 130213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void rsqrtps(XMMRegister dst, const Operand& src); 130313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void sqrtps(XMMRegister dst, XMMRegister src); 130413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void sqrtps(XMMRegister dst, const Operand& src); 130513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void movups(XMMRegister dst, XMMRegister src); 130613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void movups(XMMRegister dst, const Operand& src); 130713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void movups(const Operand& dst, XMMRegister src); 130813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void psrldq(XMMRegister dst, uint8_t shift); 130913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle); 1310f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void pshufd(XMMRegister dst, const Operand& src, uint8_t shuffle); 131113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void cvtdq2ps(XMMRegister dst, XMMRegister src); 131213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void cvtdq2ps(XMMRegister dst, const Operand& src); 131313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 1314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // AVX instruction 1315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x99, dst, src1, src2); 1317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xa9, dst, src1, src2); 1320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xb9, dst, src1, src2); 1323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x99, dst, src1, src2); 1326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xa9, dst, src1, src2); 1329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xb9, dst, src1, src2); 1332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9b, dst, src1, src2); 1335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xab, dst, src1, src2); 1338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbb, dst, src1, src2); 1341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9b, dst, src1, src2); 1344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xab, dst, src1, src2); 1347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbb, dst, src1, src2); 1350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9d, dst, src1, src2); 1353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xad, dst, src1, src2); 1356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbd, dst, src1, src2); 1359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9d, dst, src1, src2); 1362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xad, dst, src1, src2); 1365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbd, dst, src1, src2); 1368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9f, dst, src1, src2); 1371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xaf, dst, src1, src2); 1374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbf, dst, src1, src2); 1377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9f, dst, src1, src2); 1380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xaf, dst, src1, src2); 1383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbf, dst, src1, src2); 1386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmasd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 1388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmasd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x99, dst, src1, src2); 1392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xa9, dst, src1, src2); 1395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xb9, dst, src1, src2); 1398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x99, dst, src1, src2); 1401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xa9, dst, src1, src2); 1404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xb9, dst, src1, src2); 1407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9b, dst, src1, src2); 1410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xab, dst, src1, src2); 1413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbb, dst, src1, src2); 1416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9b, dst, src1, src2); 1419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xab, dst, src1, src2); 1422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbb, dst, src1, src2); 1425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9d, dst, src1, src2); 1428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xad, dst, src1, src2); 1431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbd, dst, src1, src2); 1434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9d, dst, src1, src2); 1437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xad, dst, src1, src2); 1440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbd, dst, src1, src2); 1443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9f, dst, src1, src2); 1446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xaf, dst, src1, src2); 1449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbf, dst, src1, src2); 1452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9f, dst, src1, src2); 1455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xaf, dst, src1, src2); 1458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbf, dst, src1, src2); 1461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmass(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 1463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmass(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovd(XMMRegister dst, Register src); 1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovd(XMMRegister dst, const Operand& src); 1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovd(Register dst, XMMRegister src); 1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovq(XMMRegister dst, Register src); 1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovq(XMMRegister dst, const Operand& src); 1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovq(Register dst, XMMRegister src); 1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x10, dst, src1, src2); 1474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovsd(XMMRegister dst, const Operand& src) { 1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x10, dst, xmm0, src); 1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovsd(const Operand& dst, XMMRegister src) { 1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x11, src, xmm0, dst); 1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_SP_3(instr, opcode) \ 1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_S_3(instr, opcode) \ 1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_P_3(instr, opcode) 1485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_S_3(instr, opcode) \ 1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_3(instr##ss, opcode, vss) \ 1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_3(instr##sd, opcode, vsd) 1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_P_3(instr, opcode) \ 1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_3(instr##ps, opcode, vps) \ 1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_3(instr##pd, opcode, vpd) 1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_3(instr, opcode, impl) \ 1495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ 1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch impl(opcode, dst, src1, src2); \ 1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 1498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void instr(XMMRegister dst, XMMRegister src1, const Operand& src2) { \ 1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch impl(opcode, dst, src1, src2); \ 1500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vsqrt, 0x51); 1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vadd, 0x58); 1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vsub, 0x5c); 1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vmul, 0x59); 1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vdiv, 0x5e); 1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vmin, 0x5d); 1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vmax, 0x5f); 1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_P_3(vand, 0x54); 1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_P_3(vor, 0x56); 1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_P_3(vxor, 0x57); 1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_3(vcvtsd2ss, 0x5a, vsd); 1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_3 1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_S_3 1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_P_3 1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_SP_3 1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vpsrlq(XMMRegister dst, XMMRegister src, byte imm8) { 1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister iop = {2}; 1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vpd(0x73, iop, dst, src); 1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(imm8); 1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vpsllq(XMMRegister dst, XMMRegister src, byte imm8) { 1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister iop = {6}; 1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vpd(0x73, iop, dst, src); 1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(imm8); 1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtss2sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1530f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x5a, dst, src1, src2, kF3, k0F, kWIG); 1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtss2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1533f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x5a, dst, src1, src2, kF3, k0F, kWIG); 1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, Register src2) { 1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister isrc2 = {src2.code()}; 1537f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2a, dst, src1, isrc2, kF2, k0F, kW0); 1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1540f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2a, dst, src1, src2, kF2, k0F, kW0); 1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1542109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, Register src2) { 1543109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch XMMRegister isrc2 = {src2.code()}; 1544f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2a, dst, src1, isrc2, kF3, k0F, kW0); 1545109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1546109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1547f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2a, dst, src1, src2, kF3, k0F, kW0); 1548109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Register src2) { 1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister isrc2 = {src2.code()}; 1551f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2a, dst, src1, isrc2, kF3, k0F, kW1); 1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1554f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2a, dst, src1, src2, kF3, k0F, kW1); 1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, Register src2) { 1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister isrc2 = {src2.code()}; 1558f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2a, dst, src1, isrc2, kF2, k0F, kW1); 1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1561f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2a, dst, src1, src2, kF2, k0F, kW1); 1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void vcvttss2si(Register dst, XMMRegister src) { 1564109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch XMMRegister idst = {dst.code()}; 1565f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW0); 1566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void vcvttss2si(Register dst, const Operand& src) { 1568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch XMMRegister idst = {dst.code()}; 1569f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW0); 1570109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvttsd2si(Register dst, XMMRegister src) { 1572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1573f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW0); 1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvttsd2si(Register dst, const Operand& src) { 1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1577f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW0); 1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvttss2siq(Register dst, XMMRegister src) { 1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1581f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW1); 1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvttss2siq(Register dst, const Operand& src) { 1584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1585f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW1); 1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvttsd2siq(Register dst, XMMRegister src) { 1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1589f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW1); 1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvttsd2siq(Register dst, const Operand& src) { 1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1593f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW1); 1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtsd2si(Register dst, XMMRegister src) { 1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1597f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2d, idst, xmm0, src, kF2, k0F, kW0); 1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vucomisd(XMMRegister dst, XMMRegister src) { 1600f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2e, dst, xmm0, src, k66, k0F, kWIG); 1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vucomisd(XMMRegister dst, const Operand& src) { 1603f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x2e, dst, xmm0, src, k66, k0F, kWIG); 1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vroundss(XMMRegister dst, XMMRegister src1, XMMRegister src2, 1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode) { 1607f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x0a, dst, src1, src2, k66, k0F3A, kWIG); 1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(static_cast<byte>(mode) | 0x8); // Mask precision exception. 1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vroundsd(XMMRegister dst, XMMRegister src1, XMMRegister src2, 1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode) { 1612f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x0b, dst, src1, src2, k66, k0F3A, kWIG); 1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(static_cast<byte>(mode) | 0x8); // Mask precision exception. 1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vsd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1617f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(op, dst, src1, src2, kF2, k0F, kWIG); 1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2) { 1620f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(op, dst, src1, src2, kF2, k0F, kWIG); 1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vss(0x10, dst, src1, src2); 1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovss(XMMRegister dst, const Operand& src) { 1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vss(0x10, dst, xmm0, src); 1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovss(const Operand& dst, XMMRegister src) { 1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vss(0x11, src, xmm0, dst); 1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vucomiss(XMMRegister dst, XMMRegister src); 1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vucomiss(XMMRegister dst, const Operand& src); 1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vss(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vss(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovaps(XMMRegister dst, XMMRegister src) { vps(0x28, dst, xmm0, src); } 1638f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void vmovups(XMMRegister dst, XMMRegister src) { vps(0x10, dst, xmm0, src); } 1639f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void vmovups(XMMRegister dst, const Operand& src) { 1640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vps(0x10, dst, xmm0, src); 1641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void vmovups(const Operand& dst, XMMRegister src) { 1643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vps(0x11, src, xmm0, dst); 1644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovapd(XMMRegister dst, XMMRegister src) { vpd(0x28, dst, xmm0, src); } 1646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void vmovupd(XMMRegister dst, const Operand& src) { 1647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vpd(0x10, dst, xmm0, src); 1648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void vmovupd(const Operand& dst, XMMRegister src) { 1650f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vpd(0x11, src, xmm0, dst); 1651f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1652f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void vmovmskps(Register dst, XMMRegister src) { 1653f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch XMMRegister idst = {dst.code()}; 1654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vps(0x50, idst, xmm0, src); 1655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovmskpd(Register dst, XMMRegister src) { 1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vpd(0x50, idst, xmm0, src); 1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1660f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void vcmpps(XMMRegister dst, XMMRegister src1, XMMRegister src2, int8_t cmp) { 1661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vps(0xC2, dst, src1, src2); 1662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch emit(cmp); 1663f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1664f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void vcmpps(XMMRegister dst, XMMRegister src1, const Operand& src2, 1665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int8_t cmp) { 1666f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vps(0xC2, dst, src1, src2); 1667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch emit(cmp); 1668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void vcmppd(XMMRegister dst, XMMRegister src1, XMMRegister src2, int8_t cmp) { 1670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vpd(0xC2, dst, src1, src2); 1671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch emit(cmp); 1672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void vcmppd(XMMRegister dst, XMMRegister src1, const Operand& src2, 1674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int8_t cmp) { 1675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vpd(0xC2, dst, src1, src2); 1676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch emit(cmp); 1677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1679f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define AVX_CMP_P(instr, imm8) \ 1680f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void instr##ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ 1681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vcmpps(dst, src1, src2, imm8); \ 1682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } \ 1683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void instr##ps(XMMRegister dst, XMMRegister src1, const Operand& src2) { \ 1684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vcmpps(dst, src1, src2, imm8); \ 1685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } \ 1686f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void instr##pd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ 1687f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vcmppd(dst, src1, src2, imm8); \ 1688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } \ 1689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void instr##pd(XMMRegister dst, XMMRegister src1, const Operand& src2) { \ 1690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vcmppd(dst, src1, src2, imm8); \ 1691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AVX_CMP_P(vcmpeq, 0x0); 1694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AVX_CMP_P(vcmplt, 0x1); 1695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AVX_CMP_P(vcmple, 0x2); 1696f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AVX_CMP_P(vcmpneq, 0x4); 1697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AVX_CMP_P(vcmpnlt, 0x5); 1698f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AVX_CMP_P(vcmpnle, 0x6); 1699f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1700f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#undef AVX_CMP_P 1701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1702f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vlddqu(XMMRegister dst, const Operand& src) { 1703f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0xF0, dst, xmm0, src, kF2, k0F, kWIG); 1704f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1705f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpsllw(XMMRegister dst, XMMRegister src, int8_t imm8) { 1706f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch XMMRegister iop = {6}; 1707f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x71, iop, dst, src, k66, k0F, kWIG); 1708f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1709f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1710f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpsrlw(XMMRegister dst, XMMRegister src, int8_t imm8) { 1711f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch XMMRegister iop = {2}; 1712f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x71, iop, dst, src, k66, k0F, kWIG); 1713f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1714f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1715f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpsraw(XMMRegister dst, XMMRegister src, int8_t imm8) { 1716f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch XMMRegister iop = {4}; 1717f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x71, iop, dst, src, k66, k0F, kWIG); 1718f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1719f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1720f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpslld(XMMRegister dst, XMMRegister src, int8_t imm8) { 1721f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch XMMRegister iop = {6}; 1722f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x72, iop, dst, src, k66, k0F, kWIG); 1723f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1724f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1725f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpsrld(XMMRegister dst, XMMRegister src, int8_t imm8) { 1726f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch XMMRegister iop = {2}; 1727f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x72, iop, dst, src, k66, k0F, kWIG); 1728f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1729f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1730f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpsrad(XMMRegister dst, XMMRegister src, int8_t imm8) { 1731f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch XMMRegister iop = {4}; 1732f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x72, iop, dst, src, k66, k0F, kWIG); 1733f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1734f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1735f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpextrb(Register dst, XMMRegister src, int8_t imm8) { 1736f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch XMMRegister idst = {dst.code()}; 1737f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x14, src, xmm0, idst, k66, k0F3A, kW0); 1738f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1739f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1740f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpextrb(const Operand& dst, XMMRegister src, int8_t imm8) { 1741f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x14, src, xmm0, dst, k66, k0F3A, kW0); 1742f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1743f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1744f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpextrw(Register dst, XMMRegister src, int8_t imm8) { 1745f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch XMMRegister idst = {dst.code()}; 1746f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0xc5, idst, xmm0, src, k66, k0F, kW0); 1747f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1748f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1749f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpextrw(const Operand& dst, XMMRegister src, int8_t imm8) { 1750f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x15, src, xmm0, dst, k66, k0F3A, kW0); 1751f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1752f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1753f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpextrd(Register dst, XMMRegister src, int8_t imm8) { 1754f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch XMMRegister idst = {dst.code()}; 1755f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x16, src, xmm0, idst, k66, k0F3A, kW0); 1756f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1757f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpextrd(const Operand& dst, XMMRegister src, int8_t imm8) { 1759f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x16, src, xmm0, dst, k66, k0F3A, kW0); 1760f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1761f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1762f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpinsrb(XMMRegister dst, XMMRegister src1, Register src2, int8_t imm8) { 1763f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch XMMRegister isrc = {src2.code()}; 1764f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x20, dst, src1, isrc, k66, k0F3A, kW0); 1765f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1766f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1767f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpinsrb(XMMRegister dst, XMMRegister src1, const Operand& src2, 1768f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int8_t imm8) { 1769f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x20, dst, src1, src2, k66, k0F3A, kW0); 1770f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1771f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1772f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpinsrw(XMMRegister dst, XMMRegister src1, Register src2, int8_t imm8) { 1773f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch XMMRegister isrc = {src2.code()}; 1774f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0xc4, dst, src1, isrc, k66, k0F, kW0); 1775f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1776f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1777f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpinsrw(XMMRegister dst, XMMRegister src1, const Operand& src2, 1778f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int8_t imm8) { 1779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0xc4, dst, src1, src2, k66, k0F, kW0); 1780f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1781f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1782f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpinsrd(XMMRegister dst, XMMRegister src1, Register src2, int8_t imm8) { 1783f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch XMMRegister isrc = {src2.code()}; 1784f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x22, dst, src1, isrc, k66, k0F3A, kW0); 1785f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1786f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1787f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpinsrd(XMMRegister dst, XMMRegister src1, const Operand& src2, 1788f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int8_t imm8) { 1789f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x22, dst, src1, src2, k66, k0F3A, kW0); 1790f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1791f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1792f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void vpshufd(XMMRegister dst, XMMRegister src, int8_t imm8) { 1793f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vinstr(0x70, dst, xmm0, src, k66, k0F, kWIG); 1794f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch emit(imm8); 1795f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1796f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vps(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vps(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vpd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 1800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vpd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // BMI instruction 1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void andnq(Register dst, Register src1, Register src2) { 1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf2, dst, src1, src2); 1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void andnq(Register dst, Register src1, const Operand& src2) { 1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf2, dst, src1, src2); 1808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void andnl(Register dst, Register src1, Register src2) { 1810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf2, dst, src1, src2); 1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void andnl(Register dst, Register src1, const Operand& src2) { 1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf2, dst, src1, src2); 1814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bextrq(Register dst, Register src1, Register src2) { 1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf7, dst, src2, src1); 1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bextrq(Register dst, const Operand& src1, Register src2) { 1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf7, dst, src2, src1); 1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bextrl(Register dst, Register src1, Register src2) { 1822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf7, dst, src2, src1); 1823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bextrl(Register dst, const Operand& src1, Register src2) { 1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf7, dst, src2, src1); 1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsiq(Register dst, Register src) { 1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {3}; 1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf3, ireg, dst, src); 1830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsiq(Register dst, const Operand& src) { 1832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {3}; 1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf3, ireg, dst, src); 1834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsil(Register dst, Register src) { 1836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {3}; 1837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf3, ireg, dst, src); 1838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsil(Register dst, const Operand& src) { 1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {3}; 1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf3, ireg, dst, src); 1842958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsmskq(Register dst, Register src) { 1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {2}; 1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf3, ireg, dst, src); 1846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsmskq(Register dst, const Operand& src) { 1848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {2}; 1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf3, ireg, dst, src); 1850958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsmskl(Register dst, Register src) { 1852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {2}; 1853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf3, ireg, dst, src); 1854958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsmskl(Register dst, const Operand& src) { 1856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {2}; 1857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf3, ireg, dst, src); 1858958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsrq(Register dst, Register src) { 1860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {1}; 1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf3, ireg, dst, src); 1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsrq(Register dst, const Operand& src) { 1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {1}; 1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf3, ireg, dst, src); 1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsrl(Register dst, Register src) { 1868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {1}; 1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf3, ireg, dst, src); 1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsrl(Register dst, const Operand& src) { 1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {1}; 1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf3, ireg, dst, src); 1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void tzcntq(Register dst, Register src); 1876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void tzcntq(Register dst, const Operand& src); 1877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void tzcntl(Register dst, Register src); 1878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void tzcntl(Register dst, const Operand& src); 1879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lzcntq(Register dst, Register src); 1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lzcntq(Register dst, const Operand& src); 1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lzcntl(Register dst, Register src); 1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lzcntl(Register dst, const Operand& src); 1884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void popcntq(Register dst, Register src); 1886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void popcntq(Register dst, const Operand& src); 1887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void popcntl(Register dst, Register src); 1888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void popcntl(Register dst, const Operand& src); 1889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bzhiq(Register dst, Register src1, Register src2) { 1891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kNone, 0xf5, dst, src2, src1); 1892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bzhiq(Register dst, const Operand& src1, Register src2) { 1894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kNone, 0xf5, dst, src2, src1); 1895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bzhil(Register dst, Register src1, Register src2) { 1897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kNone, 0xf5, dst, src2, src1); 1898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bzhil(Register dst, const Operand& src1, Register src2) { 1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kNone, 0xf5, dst, src2, src1); 1901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mulxq(Register dst1, Register dst2, Register src) { 1903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF2, 0xf6, dst1, dst2, src); 1904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mulxq(Register dst1, Register dst2, const Operand& src) { 1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF2, 0xf6, dst1, dst2, src); 1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mulxl(Register dst1, Register dst2, Register src) { 1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF2, 0xf6, dst1, dst2, src); 1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mulxl(Register dst1, Register dst2, const Operand& src) { 1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF2, 0xf6, dst1, dst2, src); 1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pdepq(Register dst, Register src1, Register src2) { 1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF2, 0xf5, dst, src1, src2); 1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pdepq(Register dst, Register src1, const Operand& src2) { 1918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF2, 0xf5, dst, src1, src2); 1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pdepl(Register dst, Register src1, Register src2) { 1921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF2, 0xf5, dst, src1, src2); 1922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pdepl(Register dst, Register src1, const Operand& src2) { 1924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF2, 0xf5, dst, src1, src2); 1925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pextq(Register dst, Register src1, Register src2) { 1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF3, 0xf5, dst, src1, src2); 1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pextq(Register dst, Register src1, const Operand& src2) { 1930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF3, 0xf5, dst, src1, src2); 1931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pextl(Register dst, Register src1, Register src2) { 1933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF3, 0xf5, dst, src1, src2); 1934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pextl(Register dst, Register src1, const Operand& src2) { 1936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF3, 0xf5, dst, src1, src2); 1937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sarxq(Register dst, Register src1, Register src2) { 1939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF3, 0xf7, dst, src2, src1); 1940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sarxq(Register dst, const Operand& src1, Register src2) { 1942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF3, 0xf7, dst, src2, src1); 1943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sarxl(Register dst, Register src1, Register src2) { 1945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF3, 0xf7, dst, src2, src1); 1946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sarxl(Register dst, const Operand& src1, Register src2) { 1948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF3, 0xf7, dst, src2, src1); 1949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shlxq(Register dst, Register src1, Register src2) { 1951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(k66, 0xf7, dst, src2, src1); 1952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shlxq(Register dst, const Operand& src1, Register src2) { 1954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(k66, 0xf7, dst, src2, src1); 1955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shlxl(Register dst, Register src1, Register src2) { 1957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(k66, 0xf7, dst, src2, src1); 1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shlxl(Register dst, const Operand& src1, Register src2) { 1960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(k66, 0xf7, dst, src2, src1); 1961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shrxq(Register dst, Register src1, Register src2) { 1963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF2, 0xf7, dst, src2, src1); 1964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shrxq(Register dst, const Operand& src1, Register src2) { 1966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF2, 0xf7, dst, src2, src1); 1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shrxl(Register dst, Register src1, Register src2) { 1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF2, 0xf7, dst, src2, src1); 1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shrxl(Register dst, const Operand& src1, Register src2) { 1972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF2, 0xf7, dst, src2, src1); 1973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rorxq(Register dst, Register src, byte imm8); 1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rorxq(Register dst, const Operand& src, byte imm8); 1976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rorxl(Register dst, Register src, byte imm8); 1977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rorxl(Register dst, const Operand& src, byte imm8); 1978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check the code size generated from label to here. 19803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int SizeOfCodeGeneratedSince(Label* label) { 19813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return pc_offset() - label->pos(); 19823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Mark generator continuation. 1985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordGeneratorContinuation(); 1986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 19877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark address of a debug break slot. 1988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordDebugBreakSlot(RelocInfo::Mode mode); 19897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Record a comment relocation entry that can be used by a disassembler. 1991b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Use --code-comments to enable. 1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordComment(const char* msg); 1993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Record a deoptimization reason that can be used by a log or cpu profiler. 1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use --trace-deopt to enable. 1996c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position, 1997c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int id); 1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PatchConstantPoolAccessInstruction(int pc_offset, int offset, 2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access, 2001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Type type) { 2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // No embedded constant pool support. 2003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2006b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Writes a single word of data in the code stream. 2007b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Used for inline tables, e.g., jump-tables. 2008b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void db(uint8_t data); 2009b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void dd(uint32_t data); 2010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dq(uint64_t data); 2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dp(uintptr_t data) { dq(data); } 2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dq(Label* label); 2013b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if there is less than kGap bytes available in the buffer. 2015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If this is the case, we need to grow the buffer before emitting 2016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // an instruction or relocation information. 2017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool buffer_overflow() const { 2018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return pc_ >= reloc_info_writer.pos() - kGap; 2019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the number of bytes available in the buffer. 2022d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block inline int available_space() const { 2023d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return static_cast<int>(reloc_info_writer.pos() - pc_); 2024d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 2025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static bool IsNop(Address addr); 20277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Avoid overflows for displacements etc. 2029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kMaximalBufferSize = 512*MB; 2030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch byte byte_at(int pos) { return buffer_[pos]; } 20323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void set_byte_at(int pos, byte value) { buffer_[pos] = value; } 20333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2034f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Address pc() const { return pc_; } 2035f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 203644f0eee88ff00398ff7f715fab053374d808c90dSteve Block protected: 2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Call near indirect 2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void call(const Operand& operand); 2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 2041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* addr_at(int pos) { return buffer_ + pos; } 2042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t long_at(int pos) { 2043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *reinterpret_cast<uint32_t*>(addr_at(pos)); 2044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void long_at_put(int pos, uint32_t x) { 2046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; 2047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // code emission 2050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void GrowBuffer(); 2051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit(byte x) { *pc_++ = x; } 2053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emitl(uint32_t x); 2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emitp(void* x, RelocInfo::Mode rmode); 2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emitq(uint64_t x); 2056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emitw(uint16_t x); 2057257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch inline void emit_code_target(Handle<Code> target, 2058257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RelocInfo::Mode rmode, 2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId ast_id = TypeFeedbackId::None()); 2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode); 2061bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void emit(Immediate x) { 2062bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!RelocInfo::IsNone(x.rmode_)) { 2063bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch RecordRelocInfo(x.rmode_); 2064bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2065bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch emitl(x.value_); 2066bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emits a REX prefix that encodes a 64-bit operand size and 2069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top bit of both register codes. 2070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 2071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is set. 2072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(XMMRegister reg, Register rm_reg); 20736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block inline void emit_rex_64(Register reg, XMMRegister rm_reg); 20746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block inline void emit_rex_64(Register reg, Register rm_reg); 2075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emits a REX prefix that encodes a 64-bit operand size and 2077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top bit of the destination, index, and base register codes. 2078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of reg is used for REX.R, the high bit of op's base 2079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register is used for REX.B, and the high bit of op's index register 2080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is used for REX.X. REX.W is set. 2081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(Register reg, const Operand& op); 2082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(XMMRegister reg, const Operand& op); 2083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emits a REX prefix that encodes a 64-bit operand size and 2085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top bit of the register code. 2086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of register is used for REX.B. 2087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is set and REX.R and REX.X are clear. 2088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(Register rm_reg); 2089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emits a REX prefix that encodes a 64-bit operand size and 2091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top bit of the index and base register codes. 2092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of op's base register is used for REX.B, and the high 2093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bit of op's index register is used for REX.X. 2094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is set and REX.R clear. 2095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(const Operand& op); 2096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size. 2098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_rex_64() { emit(0x48); } 2099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 2101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is clear. 2102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_32(Register reg, Register rm_reg); 2103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of reg is used for REX.R, the high bit of op's base 2105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register is used for REX.B, and the high bit of op's index register 2106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is used for REX.X. REX.W is cleared. 2107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_32(Register reg, const Operand& op); 2108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of rm_reg goes to REX.B. 2110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W, REX.R and REX.X are clear. 2111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_32(Register rm_reg); 2112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of base goes to REX.B and high bit of index to REX.X. 2114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W and REX.R are clear. 2115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_32(const Operand& op); 2116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 2118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is cleared. If no REX bits are set, no byte is emitted. 2119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(Register reg, Register rm_reg); 2120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of reg is used for REX.R, the high bit of op's base 2122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register is used for REX.B, and the high bit of op's index register 2123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing 2124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is emitted. 2125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(Register reg, const Operand& op); 2126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // As for emit_optional_rex_32(Register, Register), except that 2128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the registers are XMM registers. 2129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base); 2130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // As for emit_optional_rex_32(Register, Register), except that 21326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // one of the registers is an XMM registers. 2133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(XMMRegister reg, Register base); 2134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // As for emit_optional_rex_32(Register, Register), except that 21366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // one of the registers is an XMM registers. 21376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block inline void emit_optional_rex_32(Register reg, XMMRegister base); 21386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // As for emit_optional_rex_32(Register, const Operand&), except that 2140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the register is an XMM register. 2141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(XMMRegister reg, const Operand& op); 2142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Optionally do as emit_rex_32(Register) if the register number has 2144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the high bit set. 2145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(Register rm_reg); 2146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_optional_rex_32(XMMRegister rm_reg); 2147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Optionally do as emit_rex_32(const Operand&) if the operand register 2149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // numbers have a high bit set. 2150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(const Operand& op); 2151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_rex(int size) { 2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (size == kInt64Size) { 2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_rex_64(); 2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(size == kInt32Size); 2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1> 2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_rex(P1 p1, int size) { 2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (size == kInt64Size) { 2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_rex_64(p1); 2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(size == kInt32Size); 2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_optional_rex_32(p1); 2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2> 2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_rex(P1 p1, P2 p2, int size) { 2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (size == kInt64Size) { 2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_rex_64(p1, p2); 2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(size == kInt32Size); 2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_optional_rex_32(p1, p2); 2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Emit vex prefix 2181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void emit_vex2_byte0() { emit(0xc5); } 2182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l, 2183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SIMDPrefix pp); 2184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void emit_vex3_byte0() { emit(0xc4); } 2185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_vex3_byte1(XMMRegister reg, XMMRegister rm, LeadingOpcode m); 2186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_vex3_byte1(XMMRegister reg, const Operand& rm, 2187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LeadingOpcode m); 2188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l, 2189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SIMDPrefix pp); 2190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, XMMRegister rm, 2191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VectorLength l, SIMDPrefix pp, LeadingOpcode m, 2192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VexW w); 2193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void emit_vex_prefix(Register reg, Register v, Register rm, 2194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorLength l, SIMDPrefix pp, LeadingOpcode m, 2195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VexW w); 2196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, const Operand& rm, 2197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VectorLength l, SIMDPrefix pp, LeadingOpcode m, 2198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VexW w); 2199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void emit_vex_prefix(Register reg, Register v, const Operand& rm, 2200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorLength l, SIMDPrefix pp, LeadingOpcode m, 2201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VexW w); 2202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit the ModR/M byte, and optionally the SIB byte and 2204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1- or 4-byte offset for a memory operand. Also encodes 2205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the second operand of the operation, a register or operation 2206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // subcode, into the reg field of the ModR/M byte. 2207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_operand(Register reg, const Operand& adr) { 2208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(reg.low_bits(), adr); 2209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit the ModR/M byte, and optionally the SIB byte and 2212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1- or 4-byte offset for a memory operand. Also used to encode 2213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a three-bit opcode extension into the ModR/M byte. 2214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_operand(int rm, const Operand& adr); 2215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit a ModR/M byte with registers coded in the reg and rm_reg fields. 2217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_modrm(Register reg, Register rm_reg) { 2218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits()); 2219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit a ModR/M byte with an operation subcode in the reg field and 2222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a register in the rm_reg field. 2223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_modrm(int code, Register rm_reg) { 2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint3(code)); 2225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0xC0 | code << 3 | rm_reg.low_bits()); 2226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit the code-object-relative offset of the label's position 2229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_code_relative_offset(Label* label); 2230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The first argument is the reg field, the second argument is the r/m field. 2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sse_operand(XMMRegister dst, XMMRegister src); 2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sse_operand(XMMRegister reg, const Operand& adr); 2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sse_operand(Register reg, const Operand& adr); 2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sse_operand(XMMRegister dst, Register src); 2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sse_operand(Register dst, XMMRegister src); 223713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void emit_sse_operand(XMMRegister dst); 2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit machine code for one of the operations ADD, ADC, SUB, SBC, 2240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // AND, OR, XOR, or CMP. The encodings of these operations are all 2241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // similar, differing just in the opcode or in the reg field of the 2242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ModR/M byte. 2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void arithmetic_op_8(byte opcode, Register reg, Register rm_reg); 2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg); 2245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void arithmetic_op_16(byte opcode, Register reg, Register rm_reg); 2246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg); 2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Operate on operands/registers with pointer size, 32-bit or 64-bit size. 2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size); 2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void arithmetic_op(byte opcode, 2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg, 2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& rm_reg, 2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size); 2253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Operate on a byte in memory or register. 2254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_8(byte subcode, 2255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register dst, 2256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 2257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_8(byte subcode, 2258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Operand& dst, 2259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 2260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Operate on a word in memory or register. 2261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_16(byte subcode, 2262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register dst, 2263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 2264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_16(byte subcode, 2265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Operand& dst, 2266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Operate on operands/registers with pointer size, 32-bit or 64-bit size. 2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void immediate_arithmetic_op(byte subcode, 2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate src, 2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size); 2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void immediate_arithmetic_op(byte subcode, 2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& dst, 2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate src, 2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size); 2276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit machine code for a shift operation. 2278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void shift(Operand dst, Immediate shift_amount, int subcode, int size); 2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shift(Register dst, Immediate shift_amount, int subcode, int size); 2280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shift dst by cl % 64 bits. 2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shift(Register dst, int subcode, int size); 2282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void shift(Operand dst, int subcode, int size); 2283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_farith(int b1, int b2, int i); 2285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // labels 2287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // void print(Label* L); 2288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bind_to(Label* L, int pos); 2289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // record reloc info for current pc_ 2291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 2292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Arithmetics 2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_add(Register dst, Register src, int size) { 2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x03, dst, src, size); 2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_add(Register dst, Immediate src, int size) { 2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x0, dst, src, size); 2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_add(Register dst, const Operand& src, int size) { 2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x03, dst, src, size); 2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_add(const Operand& dst, Register src, int size) { 2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x1, src, dst, size); 2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_add(const Operand& dst, Immediate src, int size) { 2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x0, dst, src, size); 2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_and(Register dst, Register src, int size) { 2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x23, dst, src, size); 2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_and(Register dst, const Operand& src, int size) { 2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x23, dst, src, size); 2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_and(const Operand& dst, Register src, int size) { 2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x21, src, dst, size); 2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_and(Register dst, Immediate src, int size) { 2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x4, dst, src, size); 2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_and(const Operand& dst, Immediate src, int size) { 2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x4, dst, src, size); 2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_cmp(Register dst, Register src, int size) { 2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x3B, dst, src, size); 2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_cmp(Register dst, const Operand& src, int size) { 2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x3B, dst, src, size); 2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_cmp(const Operand& dst, Register src, int size) { 2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x39, src, dst, size); 2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_cmp(Register dst, Immediate src, int size) { 2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x7, dst, src, size); 2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_cmp(const Operand& dst, Immediate src, int size) { 2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x7, dst, src, size); 2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 235413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Compare {al,ax,eax,rax} with src. If equal, set ZF and write dst into 235513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // src. Otherwise clear ZF and write src into {al,ax,eax,rax}. This 235613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // operation is only atomic if prefixed by the lock instruction. 235713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void emit_cmpxchg(const Operand& dst, Register src, int size); 235813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_dec(Register dst, int size); 2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_dec(const Operand& dst, int size); 2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Divide rdx:rax by src. Quotient in rax, remainder in rdx when size is 64. 2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Divide edx:eax by lower 32 bits of src. Quotient in eax, remainder in edx 2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // when size is 32. 2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_idiv(Register src, int size); 2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_div(Register src, int size); 2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Signed multiply instructions. 2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32. 2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_imul(Register src, int size); 2371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void emit_imul(const Operand& src, int size); 2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_imul(Register dst, Register src, int size); 2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_imul(Register dst, const Operand& src, int size); 2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_imul(Register dst, Register src, Immediate imm, int size); 2375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void emit_imul(Register dst, const Operand& src, Immediate imm, int size); 2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_inc(Register dst, int size); 2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_inc(const Operand& dst, int size); 2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_lea(Register dst, const Operand& src, int size); 2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_mov(Register dst, const Operand& src, int size); 2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_mov(Register dst, Register src, int size); 2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_mov(const Operand& dst, Register src, int size); 2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_mov(Register dst, Immediate value, int size); 2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_mov(const Operand& dst, Immediate value, int size); 2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_movzxb(Register dst, const Operand& src, int size); 2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_movzxb(Register dst, Register src, int size); 2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_movzxw(Register dst, const Operand& src, int size); 2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_movzxw(Register dst, Register src, int size); 2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_neg(Register dst, int size); 2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_neg(const Operand& dst, int size); 2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_not(Register dst, int size); 2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_not(const Operand& dst, int size); 2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_or(Register dst, Register src, int size) { 2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x0B, dst, src, size); 2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_or(Register dst, const Operand& src, int size) { 2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x0B, dst, src, size); 2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_or(const Operand& dst, Register src, int size) { 2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x9, src, dst, size); 2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_or(Register dst, Immediate src, int size) { 2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x1, dst, src, size); 2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_or(const Operand& dst, Immediate src, int size) { 2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x1, dst, src, size); 2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_repmovs(int size); 2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sbb(Register dst, Register src, int size) { 2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x1b, dst, src, size); 2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sub(Register dst, Register src, int size) { 2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x2B, dst, src, size); 2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sub(Register dst, Immediate src, int size) { 2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x5, dst, src, size); 2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sub(Register dst, const Operand& src, int size) { 2434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x2B, dst, src, size); 2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sub(const Operand& dst, Register src, int size) { 2438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x29, src, dst, size); 2439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sub(const Operand& dst, Immediate src, int size) { 2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x5, dst, src, size); 2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_test(Register dst, Register src, int size); 2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_test(Register reg, Immediate mask, int size); 2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_test(const Operand& op, Register reg, int size); 2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_test(const Operand& op, Immediate mask, int size); 2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_test(Register reg, const Operand& op, int size) { 2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return emit_test(op, reg, size); 2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xchg(Register dst, Register src, int size); 2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xchg(Register dst, const Operand& src, int size); 2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xor(Register dst, Register src, int size) { 2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (size == kInt64Size && dst.code() == src.code()) { 2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore 2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // there is no need to make this a 64 bit operation. 2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x33, dst, src, kInt32Size); 2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x33, dst, src, size); 2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xor(Register dst, const Operand& src, int size) { 2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x33, dst, src, size); 2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xor(Register dst, Immediate src, int size) { 2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x6, dst, src, size); 2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xor(const Operand& dst, Immediate src, int size) { 2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x6, dst, src, size); 2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xor(const Operand& dst, Register src, int size) { 2479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x31, src, dst, size); 2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Most BMI instructions are similiar. 2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi1q(byte op, Register reg, Register vreg, Register rm); 2484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi1q(byte op, Register reg, Register vreg, const Operand& rm); 2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi1l(byte op, Register reg, Register vreg, Register rm); 2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi1l(byte op, Register reg, Register vreg, const Operand& rm); 2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm); 2488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg, 2489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operand& rm); 2490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm); 2491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg, 2492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operand& rm); 2493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class CodePatcher; 2495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class EnsureSpace; 2496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class RegExpMacroAssemblerX64; 2497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // code generation 2499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfoWriter reloc_info_writer; 2500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Internal reference positions, required for (potential) patching in 2502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // GrowBuffer(); contains only those internal references whose labels 2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // are already bound. 2504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch std::deque<int> internal_reference_positions_; 2505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 25063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block List< Handle<Code> > code_targets_; 2507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 2508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper class that ensures that there is enough space for generating 2511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instructions and relocation information. The constructor makes 2512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// sure that there is enough space and (in debug mode) the destructor 2513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// checks that we did not generate too much. 2514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EnsureSpace BASE_EMBEDDED { 2515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 2516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { 2517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (assembler_->buffer_overflow()) assembler_->GrowBuffer(); 2518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 2519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block space_before_ = assembler_->available_space(); 2520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 2521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 2524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~EnsureSpace() { 2525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bytes_generated = space_before_ - assembler_->available_space(); 2526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(bytes_generated < assembler_->kGap); 2527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 2529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 2531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler* assembler_; 2532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 2533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int space_before_; 2534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 2535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 2536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 2538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 2539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_X64_ASSEMBLER_X64_H_ 2541