assembler-x64.h revision 109988c7ccb6f3fd1a58574fa3dfb88beaef6632
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" 43d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utility functions 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define GENERAL_REGISTERS(V) \ 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rax) \ 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rcx) \ 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rdx) \ 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rbx) \ 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rsp) \ 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rbp) \ 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rsi) \ 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rdi) \ 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r8) \ 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r9) \ 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r10) \ 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r11) \ 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r12) \ 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r13) \ 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r14) \ 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r15) 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_GENERAL_REGISTERS(V) \ 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rax) \ 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rbx) \ 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rdx) \ 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rcx) \ 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rsi) \ 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(rdi) \ 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r8) \ 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r9) \ 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r11) \ 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r12) \ 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r14) \ 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(r15) 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CPU Registers. 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 1) We would prefer to use an enum, but enum values are assignment- 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// compatible with int, which has caused code-generation bugs. 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 2) We would prefer to use a class instead of a struct but we don't like 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the register initialization to depend on the particular initialization 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order (which appears to be different on OS X, Linux, and Windows for the 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// installed versions of C++ we tried). Using a struct permits C-style 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "initialization". Also, the Register objects cannot be const as this 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// forces initialization stubs in MSVC, making us dependent on initialization 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order. 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 3) By not using an enum, we are possibly preventing the compiler from 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// doing certain constant folds, which may significantly reduce the 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// code generated for some assembly instructions (because they boil down 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to a few constants). If this is a problem, we could change the code 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// such that we use an enum in optimized mode, and the struct in debug 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// mode. This way we get the compile-time error checking in debug mode 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and best performance in optimized code. 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct Register { 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Code { 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R, 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GENERAL_REGISTERS(REGISTER_CODE) 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kAfterLast, 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCode_no_reg = -1 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 111b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kNumRegisters = Code::kAfterLast; 113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static Register from_code(int code) { 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(code >= 0); 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(code < kNumRegisters); 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register r = {code}; 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return r; 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const char* ToString(); 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsAllocatable() const; 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is(Register reg) const { return reg_code == reg.reg_code; } 1240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int code() const { 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int bit() const { 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(is_valid()); 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 1 << reg_code; 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_byte_register() const { return reg_code <= 3; } 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the high bit of the register code as a 0 or 1. Used often 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // when constructing the REX prefix byte. 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int high_bit() const { return reg_code >> 3; } 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the 3 low bits of the register code. Used when encoding registers 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in modR/M, SIB, and opcode bytes. 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int low_bits() const { return reg_code & 0x7; } 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Unfortunately we can't make this private in a struct when initializing 1423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // by assignment. 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochGENERAL_REGISTERS(DECLARE_REGISTER) 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register no_reg = {Register::kCode_no_reg}; 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef _WIN64 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Windows calling convention 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_1 = {Register::kCode_rcx}; 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_2 = {Register::kCode_rdx}; 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_3 = {Register::kCode_r8}; 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_4 = {Register::kCode_r9}; 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // AMD64 calling convention 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_1 = {Register::kCode_rdi}; 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_2 = {Register::kCode_rsi}; 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_3 = {Register::kCode_rdx}; 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_4 = {Register::kCode_rcx}; 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // _WIN64 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DOUBLE_REGISTERS(V) \ 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm0) \ 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm1) \ 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm2) \ 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm3) \ 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm4) \ 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm5) \ 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm6) \ 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm7) \ 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm8) \ 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm9) \ 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm10) \ 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm11) \ 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm12) \ 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm13) \ 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm14) \ 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm15) 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm1) \ 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm2) \ 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm3) \ 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm4) \ 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm5) \ 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm6) \ 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm7) \ 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm8) \ 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm9) \ 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm10) \ 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm11) \ 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm12) \ 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm13) \ 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm14) \ 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm15) 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct DoubleRegister { 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Code { 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R, 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DOUBLE_REGISTERS(REGISTER_CODE) 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kAfterLast, 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCode_no_reg = -1 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMaxNumRegisters = Code::kAfterLast; 214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static DoubleRegister from_code(int code) { 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister result = {code}; 217b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return result; 218b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 219b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const char* ToString(); 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsAllocatable() const; 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; } 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; } 2240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int code() const { 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the high bit of the register code as a 0 or 1. Used often 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // when constructing the REX prefix byte. 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int high_bit() const { return reg_code >> 3; } 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the 3 low bits of the register code. Used when encoding registers 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in modR/M, SIB, and opcode bytes. 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int low_bits() const { return reg_code & 0x7; } 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unfortunately we can't make this private in a struct when initializing 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // by assignment. 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) \ 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const DoubleRegister R = {DoubleRegister::kCode_##R}; 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDOUBLE_REGISTERS(DECLARE_REGISTER) 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg}; 247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef DoubleRegister XMMRegister; 250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 251109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtypedef DoubleRegister Simd128Register; 252109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum Condition { 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // any value < 0 is considered no_condition 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block no_condition = -1, 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block overflow = 0, 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block no_overflow = 1, 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block below = 2, 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block above_equal = 3, 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block equal = 4, 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_equal = 5, 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block below_equal = 6, 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block above = 7, 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block negative = 8, 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block positive = 9, 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parity_even = 10, 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parity_odd = 11, 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block less = 12, 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block greater_equal = 13, 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block less_equal = 14, 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block greater = 15, 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Fake conditions that are handled by the 2753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // opcodes using them. 2763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block always = 16, 2773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block never = 17, 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // aliases 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block carry = below, 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_carry = above_equal, 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block zero = equal, 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_zero = not_equal, 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sign = negative, 2843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block not_sign = positive, 2853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block last_condition = greater 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns the equivalent of !cc. 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Negation of the default no_condition (-1) results in a non-default 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// no_condition value (-2). As long as tests for no_condition check 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for condition < 0, this will work as expected. 2939dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monseninline Condition NegateCondition(Condition cc) { 2949dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return static_cast<Condition>(cc ^ 1); 2959dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 2969dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Commute a condition such that {a cond b == b cond' a}. 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline Condition CommuteCondition(Condition cc) { 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (cc) { 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case below: 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return above; 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case above: 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return below; 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case above_equal: 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return below_equal; 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case below_equal: 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return above_equal; 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case less: 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return greater; 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case greater: 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return less; 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case greater_equal: 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return less_equal; 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case less_equal: 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return greater_equal; 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return cc; 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3229dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum RoundingMode { 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundToNearest = 0x0, 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundDown = 0x1, 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundUp = 0x2, 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundToZero = 0x3 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Machine instruction Immediates 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Immediate BASE_EMBEDDED { 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit Immediate(int32_t value) : value_(value) {} 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit Immediate(Smi* value) { 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); // Only available for 31-bit SMI. 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ = static_cast<int32_t>(reinterpret_cast<intptr_t>(value)); 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t value_; 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class Assembler; 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Machine instruction Operands 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum ScaleFactor { 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_1 = 0, 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_2 = 1, 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_4 = 2, 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_8 = 3, 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_int_size = times_4, 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_pointer_size = (kPointerSize == 8) ? times_8 : times_4 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Operand BASE_EMBEDDED { 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + disp/r] 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Operand(Register base, int32_t disp); 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + index*scale + disp/r] 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Operand(Register base, 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register index, 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t disp); 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [index*scale + disp/r] 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Operand(Register index, 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t disp); 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 378f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Offset from existing memory operand. 379f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Offset is added to existing displacement as 32-bit signed values and 380f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // this must not overflow. 381f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand(const Operand& base, int32_t offset); 382f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // [rip + disp/r] 384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit Operand(Label* label); 385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Checks whether either base or index register is the given register. 3871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Does not check the "reg" part of the Operand. 3881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool AddressUsesRegister(Register reg) const; 3891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 39044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Queries related to the size of the generated instruction. 39144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Whether the generated instruction will have a REX prefix. 39244f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool requires_rex() const { return rex_ != 0; } 39344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Size of the ModR/M, SIB and displacement parts of the generated 39444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // instruction. 39544f0eee88ff00398ff7f715fab053374d808c90dSteve Block int operand_size() const { return len_; } 39644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte rex_; 399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch byte buf_[9]; 4001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The number of bytes of buf_ in use. 4011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block byte len_; 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the ModR/M byte without an encoded 'reg' register. The 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register is encoded later as part of the emit_operand operation. 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // set_modrm can be called before or after set_sib and set_disp*. 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_modrm(int mod, Register rm); 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the SIB byte if one is needed. Sets the length to 2 rather than 1. 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_sib(ScaleFactor scale, Register index, Register base); 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Adds operand displacement fields (offsets added to the memory address). 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Needs to be called after set_sib, not before it. 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_disp8(int disp); 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_disp32(int disp); 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void set_disp64(int64_t disp); // for labels. 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class Assembler; 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ASSEMBLER_INSTRUCTION_LIST(V) \ 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(add) \ 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(and) \ 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(cmp) \ 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(dec) \ 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(idiv) \ 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(div) \ 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(imul) \ 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(inc) \ 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(lea) \ 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(mov) \ 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(movzxb) \ 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(movzxw) \ 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(neg) \ 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(not) \ 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(or) \ 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(repmovs) \ 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(sbb) \ 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(sub) \ 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(test) \ 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(xchg) \ 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(xor) 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shift instructions on operands/registers with kPointerSize, kInt32Size and 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// kInt64Size. 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define SHIFT_INSTRUCTION_LIST(V) \ 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(rol, 0x0) \ 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(ror, 0x1) \ 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(rcl, 0x2) \ 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(rcr, 0x3) \ 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(shl, 0x4) \ 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(shr, 0x5) \ 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(sar, 0x7) \ 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Assembler : public AssemblerBase { 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We check before assembling an instruction that there is sufficient 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // space to write an instruction and its relocation information. 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The relocation writer's position must be kGap bytes above the end of 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the generated instructions. This leaves enough space for the 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // longest possible x64 instruction, 15 bytes, and the longest possible 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // relocation information encoding, RelocInfoWriter::kMaxLength == 16. 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // (There is a 15 byte limit on x64 instruction length that rules out some 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // otherwise valid instructions.) 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This allows for a single, fast space check per instruction. 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kGap = 32; 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create an assembler. Instructions and relocation information are emitted 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // into a buffer, with the instructions starting from the beginning and the 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // relocation information starting from the end of the buffer. See CodeDesc 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // for a detailed comment on the layout (globals.h). 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the provided buffer is NULL, the assembler allocates and grows its own 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // buffer, and buffer_size determines the initial buffer size. The buffer is 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // owned by the assembler and deallocated upon destruction of the assembler. 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the provided buffer is not NULL, the assembler uses the provided buffer 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // for code generation and assumes its size to be buffer_size. If the buffer 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is too small, a fatal error occurs. No deallocation of the buffer is done 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // upon destruction of the assembler. 4848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Assembler(Isolate* isolate, void* buffer, int buffer_size); 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~Assembler() { } 48644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // GetCode emits any pending (non-emitted) code and fills the descriptor 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // desc. GetCode() is idempotent; it returns the same result if no other 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Assembler functions are invoked in between GetCode() calls. 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void GetCode(CodeDesc* desc); 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Read/Modify the code target in the relative branch/call instruction at pc. 4933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // On the x64 architecture, we use relative jumps with a 32-bit displacement 4943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // to jump to other Code objects in the Code space in the heap. 4953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Jumps to C functions are done indirectly through a 64-bit register holding 4963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // the absolute address of the target. 4973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // These functions convert between absolute Addresses of Code objects and 4983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // the relative displacements stored in the code. 499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline Address target_address_at(Address pc, Address constant_pool); 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void set_target_address_at( 501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address constant_pool, Address target, 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline Address target_address_at(Address pc, Code* code) { 504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return target_address_at(pc, constant_pool); 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void set_target_address_at( 508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Code* code, Address target, 509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED) { 510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_target_address_at(isolate, pc, constant_pool, target, 512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch icache_flush_mode); 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the code target address at a call site from the return address 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of that call in the instruction stream. 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline Address target_address_from_return_address(Address pc); 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 519d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This sets the branch destination (which is in the instruction on x64). 520d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This is for calls and branches within generated code. 5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline static void deserialization_set_special_target_at( 522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address instruction_payload, Code* code, 523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address target) { 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_target_address_at(isolate, instruction_payload, code, target); 525d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 526d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This sets the internal reference at the pc. 528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline static void deserialization_set_target_internal_reference_at( 529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address target, 530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline RelocInfo::Mode RelocInfoNone() { 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return RelocInfo::NONE64; 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kPointerSize == kInt32Size); 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return RelocInfo::NONE32; 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 539d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 540d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block inline Handle<Object> code_target_object_handle_at(Address pc); 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Address runtime_entry_at(Address pc); 543d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Number of bytes taken up by the branch target in the code. 5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kSpecialTargetSize = 4; // Use 32-bit displacement. 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Distance between the address of the code target in the call instruction 5463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // and the return address pushed on the stack. 5473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement. 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The length of call(kScratchRegister). 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kCallScratchRegisterInstructionLength = 3; 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The length of call(Immediate32). 5511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const int kShortCallInstructionLength = 5; 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The length of movq(kScratchRegister, address). 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kMoveAddressIntoScratchRegisterInstructionLength = 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2 + kPointerSize; 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The length of movq(kScratchRegister, address) and call(kScratchRegister). 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kCallSequenceLength = 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMoveAddressIntoScratchRegisterInstructionLength + 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kCallScratchRegisterInstructionLength; 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The debug break slot must be able to contain an indirect call sequence. 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kDebugBreakSlotLength = kCallSequenceLength; 562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Distance between start of patched debug break slot and the emitted address 563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to jump to. 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kPatchDebugBreakSlotAddressOffset = 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMoveAddressIntoScratchRegisterInstructionLength - kPointerSize; 5667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5679fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block // One byte opcode for test eax,0xXXXXXXXX. 5689fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block static const byte kTestEaxByte = 0xA9; 5691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // One byte opcode for test al, 0xXX. 5701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kTestAlByte = 0xA8; 5711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // One byte opcode for nop. 5721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kNopByte = 0x90; 5731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // One byte prefix for a short conditional jump. 5751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kJccShortPrefix = 0x70; 5761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kJncShortOpcode = kJccShortPrefix | not_carry; 5771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kJcShortOpcode = kJccShortPrefix | carry; 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kJnzShortOpcode = kJccShortPrefix | not_zero; 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kJzShortOpcode = kJccShortPrefix | zero; 5801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // VEX prefix encodings. 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 }; 583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128, kLZ = kL128 }; 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 }; 585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x3 }; 5867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Code generation 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Function names correspond one-to-one to x64 instruction mnemonics. 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Unless specified otherwise, instructions operate on 64-bit operands. 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we need versions of an assembly instruction that operate on different 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // width arguments, we add a single-letter suffix specifying the width. 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This is done for the following instructions: mov, cmp, inc, dec, 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // add, sub, and test. 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // There are no versions of these instructions without the suffix. 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - Instructions on 32-bit (doubleword) operands/registers use 'l'. 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - Instructions on 64-bit (quadword) operands/registers use 'q'. 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - Instructions on operands/registers with pointer size use 'p'. 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size); 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARE_INSTRUCTION(instruction) \ 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1> \ 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##p(P1 p1) { \ 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, kPointerSize); \ 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1> \ 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##l(P1 p1) { \ 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, kInt32Size); \ 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1> \ 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##q(P1 p1) { \ 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, kInt64Size); \ 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2> \ 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##p(P1 p1, P2 p2) { \ 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, p2, kPointerSize); \ 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2> \ 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##l(P1 p1, P2 p2) { \ 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, p2, kInt32Size); \ 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2> \ 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##q(P1 p1, P2 p2) { \ 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, p2, kInt64Size); \ 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2, class P3> \ 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##p(P1 p1, P2 p2, P3 p3) { \ 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, p2, p3, kPointerSize); \ 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2, class P3> \ 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##l(P1 p1, P2 p2, P3 p3) { \ 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, p2, p3, kInt32Size); \ 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch \ 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2, class P3> \ 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instruction##q(P1 p1, P2 p2, P3 p3) { \ 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_##instruction(p1, p2, p3, kInt64Size); \ 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION) 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_INSTRUCTION 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Insert the smallest number of nop instructions 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // possible to align the pc offset to a multiple 6561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // of m, where m must be a power of 2. 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Align(int m); 658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Insert the smallest number of zero bytes possible to align the pc offset 659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to a mulitple of m. m must be a power of 2 (>= 2). 660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DataAlign(int m); 6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Nop(int bytes = 1); 6629dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Aligns code to something that's optimal for a jump target for the platform. 6639dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen void CodeTargetAlign(); 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stack 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void pushfq(); 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void popfq(); 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pushq(Immediate value); 6701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Push a 32 bit integer, and guarantee that it is actually pushed as a 6711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // 32 bit value, the normal push will optimize the 8 bit case. 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pushq_imm32(int32_t imm32); 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pushq(Register src); 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pushq(const Operand& src); 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void popq(Register dst); 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void popq(const Operand& dst); 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void enter(Immediate size); 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void leave(); 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Moves 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movb(Register dst, const Operand& src); 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movb(Register dst, Immediate imm); 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movb(const Operand& dst, Register src); 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movb(const Operand& dst, Immediate imm); 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Move the low 16 bits of a 64-bit register value to a 16-bit 6893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // memory location. 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movw(Register dst, const Operand& src); 6913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void movw(const Operand& dst, Register src); 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movw(const Operand& dst, Immediate imm); 6933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move the offset of the label location relative to the current 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // position (after the move) to the destination. 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movl(const Operand& dst, Label* src); 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loads a pointer into a register with a relocation mode. 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movp(Register dst, void* ptr, RelocInfo::Mode rmode); 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loads a 64-bit immediate into a register. 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movq(Register dst, int64_t value); 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movq(Register dst, uint64_t value); 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 705958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void movsxbl(Register dst, Register src); 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movsxbl(Register dst, const Operand& src); 7073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void movsxbq(Register dst, const Operand& src); 708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void movsxwl(Register dst, Register src); 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movsxwl(Register dst, const Operand& src); 7103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void movsxwq(Register dst, const Operand& src); 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movsxlq(Register dst, Register src); 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movsxlq(Register dst, const Operand& src); 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 714d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Repeated moves. 715d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 716d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void repmovsb(); 717d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void repmovsw(); 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void repmovsp() { emit_repmovs(kPointerSize); } 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void repmovsl() { emit_repmovs(kInt32Size); } 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void repmovsq() { emit_repmovs(kInt64Size); } 721d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 72244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Instruction to load from an immediate 64-bit pointer into RAX. 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void load_rax(void* ptr, RelocInfo::Mode rmode); 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void load_rax(ExternalReference ext); 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Conditional moves. 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmovq(Condition cc, Register dst, Register src); 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmovq(Condition cc, Register dst, const Operand& src); 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmovl(Condition cc, Register dst, Register src); 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmovl(Condition cc, Register dst, const Operand& src); 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(Register dst, Immediate src) { 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_8(0x7, dst, src); 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb_al(Immediate src); 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(Register dst, Register src) { 739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op_8(0x3A, dst, src); 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(Register dst, const Operand& src) { 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op_8(0x3A, dst, src); 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(const Operand& dst, Register src) { 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op_8(0x38, src, dst); 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(const Operand& dst, Immediate src) { 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_8(0x7, dst, src); 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(const Operand& dst, Immediate src) { 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_16(0x7, dst, src); 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(Register dst, Immediate src) { 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_16(0x7, dst, src); 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(Register dst, const Operand& src) { 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_16(0x3B, dst, src); 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(Register dst, Register src) { 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_16(0x3B, dst, src); 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(const Operand& dst, Register src) { 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_16(0x39, src, dst); 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7744515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke void andb(Register dst, Immediate src) { 7754515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke immediate_arithmetic_op_8(0x4, dst, src); 7764515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 7773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void decb(Register dst); 7793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void decb(const Operand& dst); 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Sign-extends rax into rdx:rax. 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cqo(); 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Sign-extends eax into edx:eax. 784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cdq(); 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 786958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Multiply eax by src, put the result in edx:eax. 787958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mull(Register src); 788958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mull(const Operand& src); 789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Multiply rax by src, put the result in rdx:rax. 790958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mulq(Register src); 791958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 792958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode) \ 793958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##p(Register dst, Immediate imm8) { \ 794958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier shift(dst, imm8, subcode, kPointerSize); \ 795958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 796958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 797958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##l(Register dst, Immediate imm8) { \ 798958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier shift(dst, imm8, subcode, kInt32Size); \ 799958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 801958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##q(Register dst, Immediate imm8) { \ 802958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier shift(dst, imm8, subcode, kInt64Size); \ 803958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 804958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 805958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##p(Operand dst, Immediate imm8) { \ 806958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier shift(dst, imm8, subcode, kPointerSize); \ 807958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##l(Operand dst, Immediate imm8) { \ 810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier shift(dst, imm8, subcode, kInt32Size); \ 811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##q(Operand dst, Immediate imm8) { \ 814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier shift(dst, imm8, subcode, kInt64Size); \ 815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 816958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##p_cl(Register dst) { shift(dst, subcode, kPointerSize); } \ 818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##l_cl(Register dst) { shift(dst, subcode, kInt32Size); } \ 820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##q_cl(Register dst) { shift(dst, subcode, kInt64Size); } \ 822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##p_cl(Operand dst) { shift(dst, subcode, kPointerSize); } \ 824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##l_cl(Operand dst) { shift(dst, subcode, kInt32Size); } \ 826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void instruction##q_cl(Operand dst) { shift(dst, subcode, kInt64Size); } 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION) 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_SHIFT_INSTRUCTION 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shifts dst:src left by cl bits, affecting only dst. 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shld(Register dst, Register src); 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shifts src:dst right by cl bits, affecting only dst. 835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shrd(Register dst, Register src); 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void store_rax(void* dst, RelocInfo::Mode mode); 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void store_rax(ExternalReference ref); 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subb(Register dst, Immediate src) { 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_8(0x5, dst, src); 842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void testb(Register dst, Register src); 845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void testb(Register reg, Immediate mask); 846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void testb(const Operand& op, Immediate mask); 847e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void testb(const Operand& op, Register reg); 848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bit operations. 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bt(const Operand& dst, Register src); 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bts(const Operand& dst, Register src); 852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsrq(Register dst, Register src); 853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsrq(Register dst, const Operand& src); 854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bsrl(Register dst, Register src); 855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsrl(Register dst, const Operand& src); 856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsfq(Register dst, Register src); 857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsfq(Register dst, const Operand& src); 858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsfl(Register dst, Register src); 859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsfl(Register dst, const Operand& src); 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Miscellaneous 8623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void clc(); 86344f0eee88ff00398ff7f715fab053374d808c90dSteve Block void cld(); 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cpuid(); 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void hlt(); 866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void int3(); 867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void nop(); 868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ret(int imm16); 869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ud2(); 870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void setcc(Condition cc, Register reg); 871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Label operations & relative jumps (PPUM Appendix D) 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Takes a branch opcode (cc) and a label (L) and generates 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // either a backward branch or a forward branch and links it 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to the label fixup chain. Usage: 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Label L; // unbound label 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // j(cc, &L); // forward branch to unbound label 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bind(&L); // bind label to the current pc 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // j(cc, &L); // backward branch to bound label 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bind(&L); // illegal: a label may be bound only once 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note: The same Label can be used for forward and backward branches 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // but it may be bound only once. 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bind(Label* L); // binds an unbound label L to the current code position 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calls 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call near relative 32-bit displacement, relative to next instruction. 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void call(Label* L); 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void call(Address entry, RelocInfo::Mode rmode); 893257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void call(Handle<Code> target, 8943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch RelocInfo::Mode rmode = RelocInfo::CODE_TARGET, 895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId ast_id = TypeFeedbackId::None()); 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Calls directly to the given address using a relative offset. 8981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Should only ever be used in Code objects for calls within the 8991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // same Code object. Should not be used when generating new code (use labels), 9001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // but only when patching existing code. 9011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void call(Address target); 9021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call near absolute indirect, address in register 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void call(Register adr); 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Jumps 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Jump short or near relative. 9083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Use a 32-bit signed displacement. 909257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Unconditional jump to L 910257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void jmp(Label* L, Label::Distance distance = Label::kFar); 911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void jmp(Address entry, RelocInfo::Mode rmode); 9123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void jmp(Handle<Code> target, RelocInfo::Mode rmode); 913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Jump near absolute indirect (r64) 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void jmp(Register adr); 916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void jmp(const Operand& src); 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Conditional jumps 919257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void j(Condition cc, 920257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* L, 921257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance distance = Label::kFar); 922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void j(Condition cc, Address entry, RelocInfo::Mode rmode); 9233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode); 924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Floating-point operations 926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld(int i); 927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld1(); 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fldz(); 9306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void fldpi(); 931b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void fldln2(); 932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld_s(const Operand& adr); 934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld_d(const Operand& adr); 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fstp_s(const Operand& adr); 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fstp_d(const Operand& adr); 9383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void fstp(int index); 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fild_s(const Operand& adr); 941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fild_d(const Operand& adr); 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fist_s(const Operand& adr); 944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fistp_s(const Operand& adr); 946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fistp_d(const Operand& adr); 947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fisttp_s(const Operand& adr); 949d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void fisttp_d(const Operand& adr); 950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fabs(); 952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fchs(); 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fadd(int i); 955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsub(int i); 956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fmul(int i); 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fdiv(int i); 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fisub_s(const Operand& adr); 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void faddp(int i = 1); 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsubp(int i = 1); 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsubrp(int i = 1); 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fmulp(int i = 1); 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fdivp(int i = 1); 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fprem(); 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fprem1(); 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fxch(int i = 1); 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fincstp(); 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ffree(int i = 0); 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ftst(); 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fucomp(int i); 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fucompp(); 9763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void fucomi(int i); 9773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void fucomip(); 9783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fcompp(); 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fnstsw_ax(); 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fwait(); 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fnclex(); 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsin(); 985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fcos(); 9863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void fptan(); 987b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void fyl2x(); 9883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void f2xm1(); 9893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void fscale(); 9903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void fninit(); 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void frndint(); 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void sahf(); 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // SSE instructions 997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void addss(XMMRegister dst, XMMRegister src); 998958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void addss(XMMRegister dst, const Operand& src); 999958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void subss(XMMRegister dst, XMMRegister src); 1000958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void subss(XMMRegister dst, const Operand& src); 1001958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mulss(XMMRegister dst, XMMRegister src); 1002958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mulss(XMMRegister dst, const Operand& src); 1003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void divss(XMMRegister dst, XMMRegister src); 1004958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void divss(XMMRegister dst, const Operand& src); 1005958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxss(XMMRegister dst, XMMRegister src); 1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxss(XMMRegister dst, const Operand& src); 1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void minss(XMMRegister dst, XMMRegister src); 1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void minss(XMMRegister dst, const Operand& src); 1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sqrtss(XMMRegister dst, XMMRegister src); 1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sqrtss(XMMRegister dst, const Operand& src); 1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1014958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ucomiss(XMMRegister dst, XMMRegister src); 1015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ucomiss(XMMRegister dst, const Operand& src); 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movaps(XMMRegister dst, XMMRegister src); 1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Don't use this unless it's important to keep the 1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // top half of the destination register unchanged. 1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use movaps when moving float values and movd for integer 1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // values in xmm registers. 1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void movss(XMMRegister dst, XMMRegister src); 1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movss(XMMRegister dst, const Operand& src); 1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movss(const Operand& dst, XMMRegister src); 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shufps(XMMRegister dst, XMMRegister src, byte imm8); 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvttss2si(Register dst, const Operand& src); 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvttss2si(Register dst, XMMRegister src); 1030109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void cvtlsi2ss(XMMRegister dst, const Operand& src); 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvtlsi2ss(XMMRegister dst, Register src); 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void andps(XMMRegister dst, XMMRegister src); 1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void andps(XMMRegister dst, const Operand& src); 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void orps(XMMRegister dst, XMMRegister src); 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void orps(XMMRegister dst, const Operand& src); 1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xorps(XMMRegister dst, XMMRegister src); 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xorps(XMMRegister dst, const Operand& src); 1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void addps(XMMRegister dst, XMMRegister src); 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void addps(XMMRegister dst, const Operand& src); 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void subps(XMMRegister dst, XMMRegister src); 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void subps(XMMRegister dst, const Operand& src); 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mulps(XMMRegister dst, XMMRegister src); 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mulps(XMMRegister dst, const Operand& src); 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void divps(XMMRegister dst, XMMRegister src); 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void divps(XMMRegister dst, const Operand& src); 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movmskps(Register dst, XMMRegister src); 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // SSE2 instructions 10526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movd(XMMRegister dst, Register src); 1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void movd(XMMRegister dst, const Operand& src); 10546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movd(Register dst, XMMRegister src); 10556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movq(XMMRegister dst, Register src); 10566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movq(Register dst, XMMRegister src); 1057257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void movq(XMMRegister dst, XMMRegister src); 10586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1059257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Don't use this unless it's important to keep the 1060257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // top half of the destination register unchanged. 1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use movapd when moving double values and movq for integer 1062257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // values in xmm registers. 1063053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block void movsd(XMMRegister dst, XMMRegister src); 1064257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1065257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void movsd(const Operand& dst, XMMRegister src); 10666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movsd(XMMRegister dst, const Operand& src); 1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void movdqa(const Operand& dst, XMMRegister src); 10691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void movdqa(XMMRegister dst, const Operand& src); 10701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movdqu(const Operand& dst, XMMRegister src); 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movdqu(XMMRegister dst, const Operand& src); 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1074257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void movapd(XMMRegister dst, XMMRegister src); 1075257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void psllq(XMMRegister reg, byte imm8); 1077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void psrlq(XMMRegister reg, byte imm8); 1078958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void pslld(XMMRegister reg, byte imm8); 1079958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void psrld(XMMRegister reg, byte imm8); 10808defd9ff6930b4e24729971a61cf7469daf119beSteve Block 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvttsd2si(Register dst, const Operand& src); 10821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void cvttsd2si(Register dst, XMMRegister src); 1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void cvttss2siq(Register dst, XMMRegister src); 1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void cvttss2siq(Register dst, const Operand& src); 108525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen void cvttsd2siq(Register dst, XMMRegister src); 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvttsd2siq(Register dst, const Operand& src); 1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvtlsi2sd(XMMRegister dst, const Operand& src); 1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvtlsi2sd(XMMRegister dst, Register src); 1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void cvtqsi2ss(XMMRegister dst, const Operand& src); 1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void cvtqsi2ss(XMMRegister dst, Register src); 1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvtqsi2sd(XMMRegister dst, const Operand& src); 1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvtqsi2sd(XMMRegister dst, Register src); 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10978defd9ff6930b4e24729971a61cf7469daf119beSteve Block 10986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void cvtss2sd(XMMRegister dst, XMMRegister src); 10998defd9ff6930b4e24729971a61cf7469daf119beSteve Block void cvtss2sd(XMMRegister dst, const Operand& src); 11008defd9ff6930b4e24729971a61cf7469daf119beSteve Block void cvtsd2ss(XMMRegister dst, XMMRegister src); 1101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cvtsd2ss(XMMRegister dst, const Operand& src); 11028defd9ff6930b4e24729971a61cf7469daf119beSteve Block 11038defd9ff6930b4e24729971a61cf7469daf119beSteve Block void cvtsd2si(Register dst, XMMRegister src); 11048defd9ff6930b4e24729971a61cf7469daf119beSteve Block void cvtsd2siq(Register dst, XMMRegister src); 11056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void addsd(XMMRegister dst, XMMRegister src); 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void addsd(XMMRegister dst, const Operand& src); 1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subsd(XMMRegister dst, XMMRegister src); 1109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void subsd(XMMRegister dst, const Operand& src); 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mulsd(XMMRegister dst, XMMRegister src); 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mulsd(XMMRegister dst, const Operand& src); 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void divsd(XMMRegister dst, XMMRegister src); 1113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void divsd(XMMRegister dst, const Operand& src); 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxsd(XMMRegister dst, XMMRegister src); 1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxsd(XMMRegister dst, const Operand& src); 1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void minsd(XMMRegister dst, XMMRegister src); 1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void minsd(XMMRegister dst, const Operand& src); 1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1120e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void andpd(XMMRegister dst, XMMRegister src); 1121e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void orpd(XMMRegister dst, XMMRegister src); 1122402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void xorpd(XMMRegister dst, XMMRegister src); 11236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void sqrtsd(XMMRegister dst, XMMRegister src); 1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sqrtsd(XMMRegister dst, const Operand& src); 1125402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1126402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void ucomisd(XMMRegister dst, XMMRegister src); 11278defd9ff6930b4e24729971a61cf7469daf119beSteve Block void ucomisd(XMMRegister dst, const Operand& src); 1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmpltsd(XMMRegister dst, XMMRegister src); 1129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void pcmpeqd(XMMRegister dst, XMMRegister src); 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movmskpd(Register dst, XMMRegister src); 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void punpckldq(XMMRegister dst, XMMRegister src); 1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void punpckhdq(XMMRegister dst, XMMRegister src); 1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // SSE 4.1 instruction 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void extractps(Register dst, XMMRegister src, byte imm8); 1138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pextrd(Register dst, XMMRegister src, int8_t imm8); 1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pinsrd(XMMRegister dst, Register src, int8_t imm8); 1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pinsrd(XMMRegister dst, const Operand& src, int8_t imm8); 1143257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void roundss(XMMRegister dst, XMMRegister src, RoundingMode mode); 1145257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode); 1146257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // AVX instruction 1148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x99, dst, src1, src2); 1150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xa9, dst, src1, src2); 1153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xb9, dst, src1, src2); 1156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x99, dst, src1, src2); 1159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xa9, dst, src1, src2); 1162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xb9, dst, src1, src2); 1165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9b, dst, src1, src2); 1168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xab, dst, src1, src2); 1171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbb, dst, src1, src2); 1174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9b, dst, src1, src2); 1177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xab, dst, src1, src2); 1180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbb, dst, src1, src2); 1183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9d, dst, src1, src2); 1186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xad, dst, src1, src2); 1189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbd, dst, src1, src2); 1192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9d, dst, src1, src2); 1195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xad, dst, src1, src2); 1198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbd, dst, src1, src2); 1201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9f, dst, src1, src2); 1204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xaf, dst, src1, src2); 1207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbf, dst, src1, src2); 1210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9f, dst, src1, src2); 1213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xaf, dst, src1, src2); 1216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbf, dst, src1, src2); 1219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmasd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 1221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmasd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x99, dst, src1, src2); 1225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xa9, dst, src1, src2); 1228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xb9, dst, src1, src2); 1231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x99, dst, src1, src2); 1234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xa9, dst, src1, src2); 1237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xb9, dst, src1, src2); 1240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9b, dst, src1, src2); 1243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xab, dst, src1, src2); 1246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbb, dst, src1, src2); 1249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9b, dst, src1, src2); 1252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xab, dst, src1, src2); 1255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbb, dst, src1, src2); 1258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9d, dst, src1, src2); 1261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xad, dst, src1, src2); 1264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbd, dst, src1, src2); 1267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9d, dst, src1, src2); 1270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xad, dst, src1, src2); 1273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbd, dst, src1, src2); 1276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9f, dst, src1, src2); 1279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xaf, dst, src1, src2); 1282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbf, dst, src1, src2); 1285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9f, dst, src1, src2); 1288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xaf, dst, src1, src2); 1291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbf, dst, src1, src2); 1294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmass(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 1296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmass(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovd(XMMRegister dst, Register src); 1299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovd(XMMRegister dst, const Operand& src); 1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovd(Register dst, XMMRegister src); 1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovq(XMMRegister dst, Register src); 1302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovq(XMMRegister dst, const Operand& src); 1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovq(Register dst, XMMRegister src); 1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x10, dst, src1, src2); 1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovsd(XMMRegister dst, const Operand& src) { 1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x10, dst, xmm0, src); 1310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovsd(const Operand& dst, XMMRegister src) { 1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x11, src, xmm0, dst); 1313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_SP_3(instr, opcode) \ 1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_S_3(instr, opcode) \ 1317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_P_3(instr, opcode) 1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_S_3(instr, opcode) \ 1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_3(instr##ss, opcode, vss) \ 1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_3(instr##sd, opcode, vsd) 1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_P_3(instr, opcode) \ 1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_3(instr##ps, opcode, vps) \ 1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_3(instr##pd, opcode, vpd) 1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_3(instr, opcode, impl) \ 1328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ 1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch impl(opcode, dst, src1, src2); \ 1330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void instr(XMMRegister dst, XMMRegister src1, const Operand& src2) { \ 1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch impl(opcode, dst, src1, src2); \ 1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vsqrt, 0x51); 1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vadd, 0x58); 1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vsub, 0x5c); 1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vmul, 0x59); 1339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vdiv, 0x5e); 1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vmin, 0x5d); 1341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_SP_3(vmax, 0x5f); 1342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_P_3(vand, 0x54); 1343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_P_3(vor, 0x56); 1344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_P_3(vxor, 0x57); 1345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_3(vpcmpeqd, 0x76, vpd); 1346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AVX_3(vcvtsd2ss, 0x5a, vsd); 1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_3 1349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_S_3 1350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_P_3 1351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_SP_3 1352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vpsrlq(XMMRegister dst, XMMRegister src, byte imm8) { 1354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister iop = {2}; 1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vpd(0x73, iop, dst, src); 1356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(imm8); 1357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vpsllq(XMMRegister dst, XMMRegister src, byte imm8) { 1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister iop = {6}; 1360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vpd(0x73, iop, dst, src); 1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(imm8); 1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtss2sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x5a, dst, src1, src2, kF3, k0F, kWIG); 1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtss2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x5a, dst, src1, src2, kF3, k0F, kWIG); 1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, Register src2) { 1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister isrc2 = {src2.code()}; 1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2a, dst, src1, isrc2, kF2, k0F, kW0); 1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2a, dst, src1, src2, kF2, k0F, kW0); 1375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1376109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, Register src2) { 1377109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch XMMRegister isrc2 = {src2.code()}; 1378109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vsd(0x2a, dst, src1, isrc2, kF3, k0F, kW0); 1379109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1380109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1381109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vsd(0x2a, dst, src1, src2, kF3, k0F, kW0); 1382109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Register src2) { 1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister isrc2 = {src2.code()}; 1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2a, dst, src1, isrc2, kF3, k0F, kW1); 1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2a, dst, src1, src2, kF3, k0F, kW1); 1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, Register src2) { 1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister isrc2 = {src2.code()}; 1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2a, dst, src1, isrc2, kF2, k0F, kW1); 1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2a, dst, src1, src2, kF2, k0F, kW1); 1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1397109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void vcvttss2si(Register dst, XMMRegister src) { 1398109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch XMMRegister idst = {dst.code()}; 1399109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vsd(0x2c, idst, xmm0, src, kF3, k0F, kW0); 1400109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1401109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void vcvttss2si(Register dst, const Operand& src) { 1402109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch XMMRegister idst = {dst.code()}; 1403109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vsd(0x2c, idst, xmm0, src, kF3, k0F, kW0); 1404109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvttsd2si(Register dst, XMMRegister src) { 1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2c, idst, xmm0, src, kF2, k0F, kW0); 1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvttsd2si(Register dst, const Operand& src) { 1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2c, idst, xmm0, src, kF2, k0F, kW0); 1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvttss2siq(Register dst, XMMRegister src) { 1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2c, idst, xmm0, src, kF3, k0F, kW1); 1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvttss2siq(Register dst, const Operand& src) { 1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2c, idst, xmm0, src, kF3, k0F, kW1); 1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvttsd2siq(Register dst, XMMRegister src) { 1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2c, idst, xmm0, src, kF2, k0F, kW1); 1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvttsd2siq(Register dst, const Operand& src) { 1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2c, idst, xmm0, src, kF2, k0F, kW1); 1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vcvtsd2si(Register dst, XMMRegister src) { 1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2d, idst, xmm0, src, kF2, k0F, kW0); 1432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vucomisd(XMMRegister dst, XMMRegister src) { 1434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2e, dst, xmm0, src, k66, k0F, kWIG); 1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vucomisd(XMMRegister dst, const Operand& src) { 1437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x2e, dst, xmm0, src, k66, k0F, kWIG); 1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vroundss(XMMRegister dst, XMMRegister src1, XMMRegister src2, 1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode) { 1441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x0a, dst, src1, src2, k66, k0F3A, kWIG); 1442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(static_cast<byte>(mode) | 0x8); // Mask precision exception. 1443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vroundsd(XMMRegister dst, XMMRegister src1, XMMRegister src2, 1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode) { 1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x0b, dst, src1, src2, k66, k0F3A, kWIG); 1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit(static_cast<byte>(mode) | 0x8); // Mask precision exception. 1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vsd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(op, dst, src1, src2, kF2, k0F, kWIG); 1452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2) { 1454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(op, dst, src1, src2, kF2, k0F, kWIG); 1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vsd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2, 1457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SIMDPrefix pp, LeadingOpcode m, VexW w); 1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2, 1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SIMDPrefix pp, LeadingOpcode m, VexW w); 1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vss(0x10, dst, src1, src2); 1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovss(XMMRegister dst, const Operand& src) { 1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vss(0x10, dst, xmm0, src); 1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovss(const Operand& dst, XMMRegister src) { 1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vss(0x11, src, xmm0, dst); 1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vucomiss(XMMRegister dst, XMMRegister src); 1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vucomiss(XMMRegister dst, const Operand& src); 1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vss(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vss(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovaps(XMMRegister dst, XMMRegister src) { vps(0x28, dst, xmm0, src); } 1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovapd(XMMRegister dst, XMMRegister src) { vpd(0x28, dst, xmm0, src); } 1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmovmskpd(Register dst, XMMRegister src) { 1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister idst = {dst.code()}; 1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vpd(0x50, idst, xmm0, src); 1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vps(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vps(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vpd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 1485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vpd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // BMI instruction 1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void andnq(Register dst, Register src1, Register src2) { 1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf2, dst, src1, src2); 1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void andnq(Register dst, Register src1, const Operand& src2) { 1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf2, dst, src1, src2); 1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void andnl(Register dst, Register src1, Register src2) { 1495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf2, dst, src1, src2); 1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void andnl(Register dst, Register src1, const Operand& src2) { 1498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf2, dst, src1, src2); 1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bextrq(Register dst, Register src1, Register src2) { 1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf7, dst, src2, src1); 1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bextrq(Register dst, const Operand& src1, Register src2) { 1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf7, dst, src2, src1); 1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bextrl(Register dst, Register src1, Register src2) { 1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf7, dst, src2, src1); 1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bextrl(Register dst, const Operand& src1, Register src2) { 1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf7, dst, src2, src1); 1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsiq(Register dst, Register src) { 1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {3}; 1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf3, ireg, dst, src); 1515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsiq(Register dst, const Operand& src) { 1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {3}; 1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf3, ireg, dst, src); 1519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsil(Register dst, Register src) { 1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {3}; 1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf3, ireg, dst, src); 1523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsil(Register dst, const Operand& src) { 1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {3}; 1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf3, ireg, dst, src); 1527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsmskq(Register dst, Register src) { 1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {2}; 1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf3, ireg, dst, src); 1531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsmskq(Register dst, const Operand& src) { 1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {2}; 1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf3, ireg, dst, src); 1535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsmskl(Register dst, Register src) { 1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {2}; 1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf3, ireg, dst, src); 1539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsmskl(Register dst, const Operand& src) { 1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {2}; 1542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf3, ireg, dst, src); 1543958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsrq(Register dst, Register src) { 1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {1}; 1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf3, ireg, dst, src); 1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsrq(Register dst, const Operand& src) { 1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {1}; 1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1q(0xf3, ireg, dst, src); 1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsrl(Register dst, Register src) { 1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {1}; 1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf3, ireg, dst, src); 1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsrl(Register dst, const Operand& src) { 1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {1}; 1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1l(0xf3, ireg, dst, src); 1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void tzcntq(Register dst, Register src); 1561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void tzcntq(Register dst, const Operand& src); 1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void tzcntl(Register dst, Register src); 1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void tzcntl(Register dst, const Operand& src); 1564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lzcntq(Register dst, Register src); 1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lzcntq(Register dst, const Operand& src); 1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lzcntl(Register dst, Register src); 1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lzcntl(Register dst, const Operand& src); 1569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void popcntq(Register dst, Register src); 1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void popcntq(Register dst, const Operand& src); 1572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void popcntl(Register dst, Register src); 1573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void popcntl(Register dst, const Operand& src); 1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bzhiq(Register dst, Register src1, Register src2) { 1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kNone, 0xf5, dst, src2, src1); 1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bzhiq(Register dst, const Operand& src1, Register src2) { 1579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kNone, 0xf5, dst, src2, src1); 1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bzhil(Register dst, Register src1, Register src2) { 1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kNone, 0xf5, dst, src2, src1); 1583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bzhil(Register dst, const Operand& src1, Register src2) { 1585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kNone, 0xf5, dst, src2, src1); 1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mulxq(Register dst1, Register dst2, Register src) { 1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF2, 0xf6, dst1, dst2, src); 1589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mulxq(Register dst1, Register dst2, const Operand& src) { 1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF2, 0xf6, dst1, dst2, src); 1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mulxl(Register dst1, Register dst2, Register src) { 1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF2, 0xf6, dst1, dst2, src); 1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mulxl(Register dst1, Register dst2, const Operand& src) { 1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF2, 0xf6, dst1, dst2, src); 1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pdepq(Register dst, Register src1, Register src2) { 1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF2, 0xf5, dst, src1, src2); 1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pdepq(Register dst, Register src1, const Operand& src2) { 1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF2, 0xf5, dst, src1, src2); 1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pdepl(Register dst, Register src1, Register src2) { 1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF2, 0xf5, dst, src1, src2); 1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pdepl(Register dst, Register src1, const Operand& src2) { 1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF2, 0xf5, dst, src1, src2); 1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pextq(Register dst, Register src1, Register src2) { 1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF3, 0xf5, dst, src1, src2); 1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pextq(Register dst, Register src1, const Operand& src2) { 1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF3, 0xf5, dst, src1, src2); 1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pextl(Register dst, Register src1, Register src2) { 1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF3, 0xf5, dst, src1, src2); 1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pextl(Register dst, Register src1, const Operand& src2) { 1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF3, 0xf5, dst, src1, src2); 1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sarxq(Register dst, Register src1, Register src2) { 1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF3, 0xf7, dst, src2, src1); 1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sarxq(Register dst, const Operand& src1, Register src2) { 1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF3, 0xf7, dst, src2, src1); 1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sarxl(Register dst, Register src1, Register src2) { 1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF3, 0xf7, dst, src2, src1); 1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sarxl(Register dst, const Operand& src1, Register src2) { 1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF3, 0xf7, dst, src2, src1); 1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shlxq(Register dst, Register src1, Register src2) { 1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(k66, 0xf7, dst, src2, src1); 1637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shlxq(Register dst, const Operand& src1, Register src2) { 1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(k66, 0xf7, dst, src2, src1); 1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shlxl(Register dst, Register src1, Register src2) { 1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(k66, 0xf7, dst, src2, src1); 1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shlxl(Register dst, const Operand& src1, Register src2) { 1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(k66, 0xf7, dst, src2, src1); 1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shrxq(Register dst, Register src1, Register src2) { 1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF2, 0xf7, dst, src2, src1); 1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shrxq(Register dst, const Operand& src1, Register src2) { 1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2q(kF2, 0xf7, dst, src2, src1); 1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shrxl(Register dst, Register src1, Register src2) { 1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF2, 0xf7, dst, src2, src1); 1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shrxl(Register dst, const Operand& src1, Register src2) { 1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2l(kF2, 0xf7, dst, src2, src1); 1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rorxq(Register dst, Register src, byte imm8); 1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rorxq(Register dst, const Operand& src, byte imm8); 1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rorxl(Register dst, Register src, byte imm8); 1662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rorxl(Register dst, const Operand& src, byte imm8); 1663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check the code size generated from label to here. 16653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int SizeOfCodeGeneratedSince(Label* label) { 16663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return pc_offset() - label->pos(); 16673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Mark generator continuation. 1670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordGeneratorContinuation(); 1671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 16727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark address of a debug break slot. 1673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordDebugBreakSlot(RelocInfo::Mode mode); 16747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Record a comment relocation entry that can be used by a disassembler. 1676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Use --code-comments to enable. 1677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordComment(const char* msg); 1678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Record a deoptimization reason that can be used by a log or cpu profiler. 1680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use --trace-deopt to enable. 1681109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void RecordDeoptReason(const int reason, int raw_position); 1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PatchConstantPoolAccessInstruction(int pc_offset, int offset, 1684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access, 1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Type type) { 1686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // No embedded constant pool support. 1687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Writes a single word of data in the code stream. 1691b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Used for inline tables, e.g., jump-tables. 1692b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void db(uint8_t data); 1693b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void dd(uint32_t data); 1694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dq(uint64_t data); 1695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dp(uintptr_t data) { dq(data); } 1696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dq(Label* label); 1697b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 16983e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu PositionsRecorder* positions_recorder() { return &positions_recorder_; } 1699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if there is less than kGap bytes available in the buffer. 1701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If this is the case, we need to grow the buffer before emitting 1702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // an instruction or relocation information. 1703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool buffer_overflow() const { 1704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return pc_ >= reloc_info_writer.pos() - kGap; 1705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the number of bytes available in the buffer. 1708d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block inline int available_space() const { 1709d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return static_cast<int>(reloc_info_writer.pos() - pc_); 1710d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static bool IsNop(Address addr); 17137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Avoid overflows for displacements etc. 1715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kMaximalBufferSize = 512*MB; 1716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch byte byte_at(int pos) { return buffer_[pos]; } 17183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void set_byte_at(int pos, byte value) { buffer_[pos] = value; } 17193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 172044f0eee88ff00398ff7f715fab053374d808c90dSteve Block protected: 1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Call near indirect 1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void call(const Operand& operand); 1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 1725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* addr_at(int pos) { return buffer_ + pos; } 1726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t long_at(int pos) { 1727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *reinterpret_cast<uint32_t*>(addr_at(pos)); 1728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void long_at_put(int pos, uint32_t x) { 1730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; 1731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // code emission 1734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void GrowBuffer(); 1735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit(byte x) { *pc_++ = x; } 1737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emitl(uint32_t x); 1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emitp(void* x, RelocInfo::Mode rmode); 1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emitq(uint64_t x); 1740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emitw(uint16_t x); 1741257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch inline void emit_code_target(Handle<Code> target, 1742257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RelocInfo::Mode rmode, 1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId ast_id = TypeFeedbackId::None()); 1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode); 1745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit(Immediate x) { emitl(x.value_); } 1746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emits a REX prefix that encodes a 64-bit operand size and 1748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top bit of both register codes. 1749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is set. 1751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(XMMRegister reg, Register rm_reg); 17526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block inline void emit_rex_64(Register reg, XMMRegister rm_reg); 17536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block inline void emit_rex_64(Register reg, Register rm_reg); 1754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emits a REX prefix that encodes a 64-bit operand size and 1756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top bit of the destination, index, and base register codes. 1757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of reg is used for REX.R, the high bit of op's base 1758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register is used for REX.B, and the high bit of op's index register 1759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is used for REX.X. REX.W is set. 1760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(Register reg, const Operand& op); 1761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(XMMRegister reg, const Operand& op); 1762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emits a REX prefix that encodes a 64-bit operand size and 1764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top bit of the register code. 1765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of register is used for REX.B. 1766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is set and REX.R and REX.X are clear. 1767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(Register rm_reg); 1768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emits a REX prefix that encodes a 64-bit operand size and 1770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top bit of the index and base register codes. 1771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of op's base register is used for REX.B, and the high 1772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bit of op's index register is used for REX.X. 1773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is set and REX.R clear. 1774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(const Operand& op); 1775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size. 1777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_rex_64() { emit(0x48); } 1778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is clear. 1781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_32(Register reg, Register rm_reg); 1782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of reg is used for REX.R, the high bit of op's base 1784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register is used for REX.B, and the high bit of op's index register 1785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is used for REX.X. REX.W is cleared. 1786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_32(Register reg, const Operand& op); 1787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of rm_reg goes to REX.B. 1789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W, REX.R and REX.X are clear. 1790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_32(Register rm_reg); 1791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of base goes to REX.B and high bit of index to REX.X. 1793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W and REX.R are clear. 1794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_32(const Operand& op); 1795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is cleared. If no REX bits are set, no byte is emitted. 1798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(Register reg, Register rm_reg); 1799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of reg is used for REX.R, the high bit of op's base 1801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register is used for REX.B, and the high bit of op's index register 1802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing 1803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is emitted. 1804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(Register reg, const Operand& op); 1805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // As for emit_optional_rex_32(Register, Register), except that 1807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the registers are XMM registers. 1808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base); 1809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // As for emit_optional_rex_32(Register, Register), except that 18116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // one of the registers is an XMM registers. 1812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(XMMRegister reg, Register base); 1813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 18146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // As for emit_optional_rex_32(Register, Register), except that 18156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // one of the registers is an XMM registers. 18166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block inline void emit_optional_rex_32(Register reg, XMMRegister base); 18176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // As for emit_optional_rex_32(Register, const Operand&), except that 1819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the register is an XMM register. 1820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(XMMRegister reg, const Operand& op); 1821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Optionally do as emit_rex_32(Register) if the register number has 1823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the high bit set. 1824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(Register rm_reg); 1825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_optional_rex_32(XMMRegister rm_reg); 1826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Optionally do as emit_rex_32(const Operand&) if the operand register 1828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // numbers have a high bit set. 1829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(const Operand& op); 1830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_rex(int size) { 1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (size == kInt64Size) { 1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_rex_64(); 1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(size == kInt32Size); 1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1> 1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_rex(P1 p1, int size) { 1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (size == kInt64Size) { 1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_rex_64(p1); 1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(size == kInt32Size); 1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_optional_rex_32(p1); 1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class P1, class P2> 1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_rex(P1 p1, P2 p2, int size) { 1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (size == kInt64Size) { 1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_rex_64(p1, p2); 1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(size == kInt32Size); 1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_optional_rex_32(p1, p2); 1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1859958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Emit vex prefix 1860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void emit_vex2_byte0() { emit(0xc5); } 1861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l, 1862958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SIMDPrefix pp); 1863958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void emit_vex3_byte0() { emit(0xc4); } 1864958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_vex3_byte1(XMMRegister reg, XMMRegister rm, LeadingOpcode m); 1865958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_vex3_byte1(XMMRegister reg, const Operand& rm, 1866958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LeadingOpcode m); 1867958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l, 1868958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SIMDPrefix pp); 1869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, XMMRegister rm, 1870958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VectorLength l, SIMDPrefix pp, LeadingOpcode m, 1871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VexW w); 1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void emit_vex_prefix(Register reg, Register v, Register rm, 1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorLength l, SIMDPrefix pp, LeadingOpcode m, 1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VexW w); 1875958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, const Operand& rm, 1876958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VectorLength l, SIMDPrefix pp, LeadingOpcode m, 1877958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VexW w); 1878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void emit_vex_prefix(Register reg, Register v, const Operand& rm, 1879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorLength l, SIMDPrefix pp, LeadingOpcode m, 1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VexW w); 1881958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit the ModR/M byte, and optionally the SIB byte and 1883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1- or 4-byte offset for a memory operand. Also encodes 1884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the second operand of the operation, a register or operation 1885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // subcode, into the reg field of the ModR/M byte. 1886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_operand(Register reg, const Operand& adr) { 1887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(reg.low_bits(), adr); 1888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit the ModR/M byte, and optionally the SIB byte and 1891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1- or 4-byte offset for a memory operand. Also used to encode 1892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a three-bit opcode extension into the ModR/M byte. 1893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_operand(int rm, const Operand& adr); 1894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit a ModR/M byte with registers coded in the reg and rm_reg fields. 1896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_modrm(Register reg, Register rm_reg) { 1897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits()); 1898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit a ModR/M byte with an operation subcode in the reg field and 1901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a register in the rm_reg field. 1902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_modrm(int code, Register rm_reg) { 1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint3(code)); 1904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0xC0 | code << 3 | rm_reg.low_bits()); 1905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit the code-object-relative offset of the label's position 1908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_code_relative_offset(Label* label); 1909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The first argument is the reg field, the second argument is the r/m field. 1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sse_operand(XMMRegister dst, XMMRegister src); 1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sse_operand(XMMRegister reg, const Operand& adr); 1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sse_operand(Register reg, const Operand& adr); 1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sse_operand(XMMRegister dst, Register src); 1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sse_operand(Register dst, XMMRegister src); 1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit machine code for one of the operations ADD, ADC, SUB, SBC, 1918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // AND, OR, XOR, or CMP. The encodings of these operations are all 1919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // similar, differing just in the opcode or in the reg field of the 1920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ModR/M byte. 1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void arithmetic_op_8(byte opcode, Register reg, Register rm_reg); 1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg); 1923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void arithmetic_op_16(byte opcode, Register reg, Register rm_reg); 1924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg); 1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Operate on operands/registers with pointer size, 32-bit or 64-bit size. 1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size); 1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void arithmetic_op(byte opcode, 1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg, 1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& rm_reg, 1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size); 1931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Operate on a byte in memory or register. 1932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_8(byte subcode, 1933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register dst, 1934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 1935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_8(byte subcode, 1936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Operand& dst, 1937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 1938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Operate on a word in memory or register. 1939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_16(byte subcode, 1940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register dst, 1941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 1942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_16(byte subcode, 1943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Operand& dst, 1944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Operate on operands/registers with pointer size, 32-bit or 64-bit size. 1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void immediate_arithmetic_op(byte subcode, 1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate src, 1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size); 1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void immediate_arithmetic_op(byte subcode, 1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& dst, 1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate src, 1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size); 1954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit machine code for a shift operation. 1956958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void shift(Operand dst, Immediate shift_amount, int subcode, int size); 1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shift(Register dst, Immediate shift_amount, int subcode, int size); 1958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shift dst by cl % 64 bits. 1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shift(Register dst, int subcode, int size); 1960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void shift(Operand dst, int subcode, int size); 1961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_farith(int b1, int b2, int i); 1963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // labels 1965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // void print(Label* L); 1966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bind_to(Label* L, int pos); 1967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // record reloc info for current pc_ 1969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Arithmetics 1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_add(Register dst, Register src, int size) { 1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x03, dst, src, size); 1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_add(Register dst, Immediate src, int size) { 1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x0, dst, src, size); 1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_add(Register dst, const Operand& src, int size) { 1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x03, dst, src, size); 1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_add(const Operand& dst, Register src, int size) { 1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x1, src, dst, size); 1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_add(const Operand& dst, Immediate src, int size) { 1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x0, dst, src, size); 1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_and(Register dst, Register src, int size) { 1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x23, dst, src, size); 1994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_and(Register dst, const Operand& src, int size) { 1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x23, dst, src, size); 1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_and(const Operand& dst, Register src, int size) { 2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x21, src, dst, size); 2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_and(Register dst, Immediate src, int size) { 2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x4, dst, src, size); 2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_and(const Operand& dst, Immediate src, int size) { 2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x4, dst, src, size); 2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_cmp(Register dst, Register src, int size) { 2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x3B, dst, src, size); 2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_cmp(Register dst, const Operand& src, int size) { 2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x3B, dst, src, size); 2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_cmp(const Operand& dst, Register src, int size) { 2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x39, src, dst, size); 2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_cmp(Register dst, Immediate src, int size) { 2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x7, dst, src, size); 2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_cmp(const Operand& dst, Immediate src, int size) { 2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x7, dst, src, size); 2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_dec(Register dst, int size); 2033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_dec(const Operand& dst, int size); 2034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Divide rdx:rax by src. Quotient in rax, remainder in rdx when size is 64. 2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Divide edx:eax by lower 32 bits of src. Quotient in eax, remainder in edx 2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // when size is 32. 2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_idiv(Register src, int size); 2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_div(Register src, int size); 2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Signed multiply instructions. 2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32. 2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_imul(Register src, int size); 2044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void emit_imul(const Operand& src, int size); 2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_imul(Register dst, Register src, int size); 2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_imul(Register dst, const Operand& src, int size); 2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_imul(Register dst, Register src, Immediate imm, int size); 2048958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void emit_imul(Register dst, const Operand& src, Immediate imm, int size); 2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_inc(Register dst, int size); 2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_inc(const Operand& dst, int size); 2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_lea(Register dst, const Operand& src, int size); 2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_mov(Register dst, const Operand& src, int size); 2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_mov(Register dst, Register src, int size); 2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_mov(const Operand& dst, Register src, int size); 2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_mov(Register dst, Immediate value, int size); 2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_mov(const Operand& dst, Immediate value, int size); 2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_movzxb(Register dst, const Operand& src, int size); 2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_movzxb(Register dst, Register src, int size); 2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_movzxw(Register dst, const Operand& src, int size); 2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_movzxw(Register dst, Register src, int size); 2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_neg(Register dst, int size); 2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_neg(const Operand& dst, int size); 2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_not(Register dst, int size); 2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_not(const Operand& dst, int size); 2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_or(Register dst, Register src, int size) { 2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x0B, dst, src, size); 2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_or(Register dst, const Operand& src, int size) { 2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x0B, dst, src, size); 2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_or(const Operand& dst, Register src, int size) { 2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x9, src, dst, size); 2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_or(Register dst, Immediate src, int size) { 2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x1, dst, src, size); 2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_or(const Operand& dst, Immediate src, int size) { 2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x1, dst, src, size); 2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_repmovs(int size); 2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sbb(Register dst, Register src, int size) { 2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x1b, dst, src, size); 2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sub(Register dst, Register src, int size) { 2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x2B, dst, src, size); 2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sub(Register dst, Immediate src, int size) { 2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x5, dst, src, size); 2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sub(Register dst, const Operand& src, int size) { 2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x2B, dst, src, size); 2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sub(const Operand& dst, Register src, int size) { 2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x29, src, dst, size); 2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sub(const Operand& dst, Immediate src, int size) { 2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x5, dst, src, size); 2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_test(Register dst, Register src, int size); 2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_test(Register reg, Immediate mask, int size); 2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_test(const Operand& op, Register reg, int size); 2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_test(const Operand& op, Immediate mask, int size); 2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_test(Register reg, const Operand& op, int size) { 2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return emit_test(op, reg, size); 2124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xchg(Register dst, Register src, int size); 2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xchg(Register dst, const Operand& src, int size); 2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xor(Register dst, Register src, int size) { 2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (size == kInt64Size && dst.code() == src.code()) { 2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore 2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // there is no need to make this a 64 bit operation. 2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x33, dst, src, kInt32Size); 2134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x33, dst, src, size); 2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xor(Register dst, const Operand& src, int size) { 2140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x33, dst, src, size); 2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xor(Register dst, Immediate src, int size) { 2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x6, dst, src, size); 2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xor(const Operand& dst, Immediate src, int size) { 2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate_arithmetic_op(0x6, dst, src, size); 2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_xor(const Operand& dst, Register src, int size) { 2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arithmetic_op(0x31, src, dst, size); 2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Most BMI instructions are similiar. 2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi1q(byte op, Register reg, Register vreg, Register rm); 2157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi1q(byte op, Register reg, Register vreg, const Operand& rm); 2158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi1l(byte op, Register reg, Register vreg, Register rm); 2159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi1l(byte op, Register reg, Register vreg, const Operand& rm); 2160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm); 2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg, 2162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operand& rm); 2163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm); 2164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg, 2165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operand& rm); 2166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class CodePatcher; 2168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class EnsureSpace; 2169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class RegExpMacroAssemblerX64; 2170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // code generation 2172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfoWriter reloc_info_writer; 2173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Internal reference positions, required for (potential) patching in 2175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // GrowBuffer(); contains only those internal references whose labels 2176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // are already bound. 2177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch std::deque<int> internal_reference_positions_; 2178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 21793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block List< Handle<Code> > code_targets_; 2180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21813e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu PositionsRecorder positions_recorder_; 21823e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu friend class PositionsRecorder; 2183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 2184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper class that ensures that there is enough space for generating 2187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instructions and relocation information. The constructor makes 2188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// sure that there is enough space and (in debug mode) the destructor 2189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// checks that we did not generate too much. 2190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EnsureSpace BASE_EMBEDDED { 2191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { 2193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (assembler_->buffer_overflow()) assembler_->GrowBuffer(); 2194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 2195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block space_before_ = assembler_->available_space(); 2196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 2197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 2200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~EnsureSpace() { 2201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bytes_generated = space_before_ - assembler_->available_space(); 2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(bytes_generated < assembler_->kGap); 2203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 2205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 2207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler* assembler_; 2208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 2209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int space_before_; 2210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 2211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 2212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 2214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 2215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_X64_ASSEMBLER_X64_H_ 2217