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. 331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Copyright 2011 the V8 project authors. All rights reserved. 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A light-weight IA32 Assembler. 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_IA32_ASSEMBLER_IA32_H_ 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_IA32_ASSEMBLER_IA32_H_ 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <deque> 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/assembler.h" 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/isolate.h" 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/utils.h" 45d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define GENERAL_REGISTERS(V) \ 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(eax) \ 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(ecx) \ 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(edx) \ 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(ebx) \ 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(esp) \ 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(ebp) \ 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(esi) \ 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(edi) 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_GENERAL_REGISTERS(V) \ 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(eax) \ 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(ecx) \ 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(edx) \ 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(ebx) \ 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(esi) \ 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(edi) 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DOUBLE_REGISTERS(V) \ 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm0) \ 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm1) \ 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm2) \ 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm3) \ 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm4) \ 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm5) \ 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm6) \ 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm7) 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 77bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define FLOAT_REGISTERS DOUBLE_REGISTERS 78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define SIMD128_REGISTERS DOUBLE_REGISTERS 79bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm1) \ 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm2) \ 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm3) \ 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm4) \ 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm5) \ 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm6) \ 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xmm7) 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CPU Registers. 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 1) We would prefer to use an enum, but enum values are assignment- 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// compatible with int, which has caused code-generation bugs. 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 2) We would prefer to use a class instead of a struct but we don't like 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the register initialization to depend on the particular initialization 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order (which appears to be different on OS X, Linux, and Windows for the 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// installed versions of C++ we tried). Using a struct permits C-style 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "initialization". Also, the Register objects cannot be const as this 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// forces initialization stubs in MSVC, making us dependent on initialization 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order. 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 3) By not using an enum, we are possibly preventing the compiler from 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// doing certain constant folds, which may significantly reduce the 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// code generated for some assembly instructions (because they boil down 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to a few constants). If this is a problem, we could change the code 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// such that we use an enum in optimized mode, and the struct in debug 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// mode. This way we get the compile-time error checking in debug mode 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and best performance in optimized code. 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct Register { 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Code { 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R, 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GENERAL_REGISTERS(REGISTER_CODE) 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kAfterLast, 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCode_no_reg = -1 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kNumRegisters = Code::kAfterLast; 120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static Register from_code(int code) { 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(code >= 0); 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(code < kNumRegisters); 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register r = {code}; 125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return r; 126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is(Register reg) const { return reg_code == reg.reg_code; } 1290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int code() const { 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int bit() const { 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 1 << reg_code; 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_byte_register() const { return reg_code <= 3; } 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Unfortunately we can't make this private in a struct. 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochGENERAL_REGISTERS(DECLARE_REGISTER) 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register no_reg = {Register::kCode_no_reg}; 149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 15013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochstatic const bool kSimpleFPAliasing = true; 15113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 152bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochstruct XMMRegister { 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Code { 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R, 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DOUBLE_REGISTERS(REGISTER_CODE) 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kAfterLast, 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCode_no_reg = -1 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMaxNumRegisters = Code::kAfterLast; 162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 163bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch static XMMRegister from_code(int code) { 164bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch XMMRegister result = {code}; 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; } 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int code() const { 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 175bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool is(XMMRegister reg) const { return reg_code == reg.reg_code; } 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 180bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtypedef XMMRegister FloatRegister; 181bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 182bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtypedef XMMRegister DoubleRegister; 183bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 184bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtypedef XMMRegister Simd128Register; 185bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) \ 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const DoubleRegister R = {DoubleRegister::kCode_##R}; 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDOUBLE_REGISTERS(DECLARE_REGISTER) 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg}; 191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum Condition { 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // any value < 0 is considered no_condition 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block no_condition = -1, 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block overflow = 0, 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block no_overflow = 1, 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block below = 2, 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block above_equal = 3, 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block equal = 4, 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_equal = 5, 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block below_equal = 6, 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block above = 7, 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block negative = 8, 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block positive = 9, 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parity_even = 10, 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parity_odd = 11, 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block less = 12, 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block greater_equal = 13, 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block less_equal = 14, 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block greater = 15, 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // aliases 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block carry = below, 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_carry = above_equal, 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block zero = equal, 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_zero = not_equal, 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sign = negative, 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_sign = positive 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns the equivalent of !cc. 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Negation of the default no_condition (-1) results in a non-default 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// no_condition value (-2). As long as tests for no_condition check 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for condition < 0, this will work as expected. 2279dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monseninline Condition NegateCondition(Condition cc) { 2289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return static_cast<Condition>(cc ^ 1); 2299dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 2309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Commute a condition such that {a cond b == b cond' a}. 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline Condition CommuteCondition(Condition cc) { 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (cc) { 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case below: 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return above; 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case above: 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return below; 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case above_equal: 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return below_equal; 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case below_equal: 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return above_equal; 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case less: 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return greater; 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case greater: 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return less; 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case greater_equal: 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return less_equal; 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case less_equal: 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return greater_equal; 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return cc; 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2569dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum RoundingMode { 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundToNearest = 0x0, 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundDown = 0x1, 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundUp = 0x2, 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundToZero = 0x3 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Machine instruction Immediates 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Immediate BASE_EMBEDDED { 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline explicit Immediate(int x); 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline explicit Immediate(const ExternalReference& ext); 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline explicit Immediate(Handle<Object> handle); 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline explicit Immediate(Smi* value); 274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch inline explicit Immediate(Address addr); 2753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline explicit Immediate(Address x, RelocInfo::Mode rmode); 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Immediate CodeRelativeOffset(Label* label) { 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Immediate(label); 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_zero() const { return x_ == 0 && RelocInfo::IsNone(rmode_); } 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_int8() const { 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return -128 <= x_ && x_ < 128 && RelocInfo::IsNone(rmode_); 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bool is_uint8() const { 2863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return v8::internal::is_uint8(x_) && RelocInfo::IsNone(rmode_); 2873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_int16() const { 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return -32768 <= x_ && x_ < 32768 && RelocInfo::IsNone(rmode_); 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bool is_uint16() const { 2923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return v8::internal::is_uint16(x_) && RelocInfo::IsNone(rmode_); 2933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline explicit Immediate(Label* value); 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int x_; 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode rmode_; 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class Operand; 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class Assembler; 303053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block friend class MacroAssembler; 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Machine instruction Operands 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum ScaleFactor { 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_1 = 0, 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_2 = 1, 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_4 = 2, 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_8 = 3, 3154515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke times_int_size = times_4, 3164515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke times_half_pointer_size = times_2, 317402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu times_pointer_size = times_4, 318402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu times_twice_pointer_size = times_8 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Operand BASE_EMBEDDED { 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // reg 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(explicit Operand(Register reg)); 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // XMM reg 3286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(explicit Operand(XMMRegister xmm_reg)); 3296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [disp/r] 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INLINE(explicit Operand(int32_t disp, RelocInfo::Mode rmode)); 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [disp/r] 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(explicit Operand(Immediate imm)); 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + disp/r] 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit Operand(Register base, int32_t disp, 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode = RelocInfo::NONE32); 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + index*scale + disp/r] 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit Operand(Register base, 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register index, 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t disp, 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode = RelocInfo::NONE32); 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [index*scale + disp/r] 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit Operand(Register index, 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t disp, 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode = RelocInfo::NONE32); 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Operand JumpTable(Register index, ScaleFactor scale, Label* table) { 354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand(index, scale, reinterpret_cast<int32_t>(table), 355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::INTERNAL_REFERENCE); 356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Operand StaticVariable(const ExternalReference& ext) { 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Operand(reinterpret_cast<int32_t>(ext.address()), 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::EXTERNAL_REFERENCE); 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Operand StaticArray(Register index, 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ExternalReference& arr) { 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()), 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::EXTERNAL_REFERENCE); 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Operand ForCell(Handle<Cell> cell) { 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference embedding_raw_address; 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return Operand(reinterpret_cast<int32_t>(cell.location()), 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::CELL); 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Operand ForRegisterPlusImmediate(Register base, Immediate imm) { 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Operand(base, imm.x_, imm.rmode_); 378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns true if this Operand is a wrapper for the specified register. 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_reg(Register reg) const; 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Returns true if this Operand is a wrapper for one register. 3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool is_reg_only() const; 3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Asserts that this Operand is a wrapper for one register and returns the 3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // register. 3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg() const; 3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the ModRM byte without an encoded 'reg' register. The 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register is encoded later as part of the emit_operand operation. 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_modrm(int mod, Register rm); 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_sib(ScaleFactor scale, Register index, Register base); 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_disp8(int8_t disp); 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_dispr(int32_t disp, RelocInfo::Mode rmode); 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch byte buf_[6]; 4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The number of bytes in buf_. 4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unsigned int len_; 4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Only valid if len_ > 4. 4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo::Mode rmode_; 4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class Assembler; 4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch friend class MacroAssembler; 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A Displacement describes the 32bit immediate field of an instruction which 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// may be used together with a Label in order to refer to a yet unknown code 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// position. Displacements stored in the instruction stream are used to describe 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the instruction and to chain a list of instructions using the same Label. 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A Displacement contains 2 different fields: 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// next field: position of next displacement in the chain (0 = end of list) 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// type field: instruction type 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A next value of null (0) indicates the end of a chain (note that there can 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be no displacement at position zero, because there is always at least one 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instruction byte before the displacement). 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Displacement _data field layout 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// |31.....2|1......0| 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// [ next | type | 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Displacement BASE_EMBEDDED { 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Type { UNCONDITIONAL_JUMP, CODE_RELATIVE, OTHER, CODE_ABSOLUTE }; 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int data() const { return data_; } 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Type type() const { return TypeField::decode(data_); } 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void next(Label* L) const { 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int n = NextField::decode(data_); 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block n > 0 ? L->link_to(n) : L->Unuse(); 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void link_to(Label* L) { init(L, type()); } 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit Displacement(int data) { data_ = data; } 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Displacement(Label* L, Type type) { init(L, type); } 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void print() { 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"), 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NextField::decode(data_)); 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int data_; 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class TypeField: public BitField<Type, 0, 2> {}; 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class NextField: public BitField<int, 2, 32-2> {}; 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void init(Label* L, Type type); 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Assembler : public AssemblerBase { 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We check before assembling an instruction that there is sufficient 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // space to write an instruction and its relocation information. 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The relocation writer's position must be kGap bytes above the end of 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the generated instructions. This leaves enough space for the 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // longest possible ia32 instruction, 15 bytes, and the longest possible 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // relocation information encoding, RelocInfoWriter::kMaxLength == 16. 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // (There is a 15 byte limit on ia32 instruction length that rules out some 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // otherwise valid instructions.) 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This allows for a single, fast space check per instruction. 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kGap = 32; 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create an assembler. Instructions and relocation information are emitted 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // into a buffer, with the instructions starting from the beginning and the 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // relocation information starting from the end of the buffer. See CodeDesc 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // for a detailed comment on the layout (globals.h). 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the provided buffer is NULL, the assembler allocates and grows its own 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // buffer, and buffer_size determines the initial buffer size. The buffer is 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // owned by the assembler and deallocated upon destruction of the assembler. 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the provided buffer is not NULL, the assembler uses the provided buffer 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // for code generation and assumes its size to be buffer_size. If the buffer 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is too small, a fatal error occurs. No deallocation of the buffer is done 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // upon destruction of the assembler. 4878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // TODO(vitalyr): the assembler does not need an isolate. 4888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Assembler(Isolate* isolate, void* buffer, int buffer_size); 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~Assembler() { } 49044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // GetCode emits any pending (non-emitted) code and fills the descriptor 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // desc. GetCode() is idempotent; it returns the same result if no other 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Assembler functions are invoked in between GetCode() calls. 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void GetCode(CodeDesc* desc); 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Read/Modify the code target in the branch/call instruction at pc. 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline static Address target_address_at(Address pc, Address constant_pool); 498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline static void set_target_address_at( 499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address constant_pool, Address target, 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline Address target_address_at(Address pc, Code* code) { 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return target_address_at(pc, constant_pool); 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void set_target_address_at( 506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Code* code, Address target, 507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED) { 508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_target_address_at(isolate, pc, constant_pool, target); 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the code target address at a call site from the return address 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of that call in the instruction stream. 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline static Address target_address_from_return_address(Address pc); 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 516d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This sets the branch destination (which is in the instruction on x86). 517d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This is for calls and branches within generated code. 5183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline static void deserialization_set_special_target_at( 519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address instruction_payload, Code* code, 520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address target) { 521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_target_address_at(isolate, instruction_payload, code, target); 522d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 523d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This sets the internal reference at the pc. 525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline static void deserialization_set_target_internal_reference_at( 526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address target, 527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kSpecialTargetSize = kPointerSize; 530d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Distance between the address of the code target in the call instruction 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and the return address 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kCallTargetAddressOffset = kPointerSize; 5347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 535d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static const int kCallInstructionLength = 5; 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // The debug break slot must be able to contain a call instruction. 5387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static const int kDebugBreakSlotLength = kCallInstructionLength; 5397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Distance between start of patched debug break slot and the emitted address 541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to jump to. 542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kPatchDebugBreakSlotAddressOffset = 1; // JMP imm32. 543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // One byte opcode for test al, 0xXX. 545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const byte kTestAlByte = 0xA8; 546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // One byte opcode for nop. 547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const byte kNopByte = 0x90; 548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // One byte opcode for a short unconditional jump. 550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const byte kJmpShortOpcode = 0xEB; 551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // One byte prefix for a short conditional jump. 552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const byte kJccShortPrefix = 0x70; 553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const byte kJncShortOpcode = kJccShortPrefix | not_carry; 554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const byte kJcShortOpcode = kJccShortPrefix | carry; 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kJnzShortOpcode = kJccShortPrefix | not_zero; 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kJzShortOpcode = kJccShortPrefix | zero; 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Code generation 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - function names correspond one-to-one to ia32 instruction mnemonics 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - unless specified otherwise, instructions operate on 32bit operands 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - instructions on 8bit (byte) operands/registers have a trailing '_b' 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - instructions on 16bit (word) operands/registers have a trailing '_w' 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - naming conflicts with C++ keywords are resolved via a trailing '_' 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // NOTE ON INTERFACE: Currently, the interface is not very consistent 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in the sense that some operations (e.g. mov()) can be called in more 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the one way to generate the same instruction: The Register argument 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // can in some cases be replaced with an Operand(Register) argument. 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This should be cleaned up and made more orthogonal. The questions 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is: should we always use Operands instead of Registers where an 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Operand is possible, or should we have a Register (overloaded) form 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // instead? We must be careful to make sure that the selected instruction 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is obvious from the parameters to avoid hard-to-find code generation 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bugs. 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Insert the smallest number of nop instructions 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // possible to align the pc offset to a multiple 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // of m. m must be a power of 2. 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Align(int m); 583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Insert the smallest number of zero bytes possible to align the pc offset 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to a mulitple of m. m must be a power of 2 (>= 2). 585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DataAlign(int m); 5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Nop(int bytes = 1); 5879dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Aligns code to something that's optimal for a jump target for the platform. 5889dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen void CodeTargetAlign(); 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stack 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void pushad(); 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void popad(); 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void pushfd(); 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void popfd(); 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void push(const Immediate& x); 598b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void push_imm32(int32_t imm32); 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void push(Register src); 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void push(const Operand& src); 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void pop(Register dst); 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void pop(const Operand& dst); 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void enter(const Immediate& size); 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void leave(); 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Moves 6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void mov_b(Register dst, Register src) { mov_b(dst, Operand(src)); } 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mov_b(Register dst, const Operand& src); 6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void mov_b(Register dst, int8_t imm8) { mov_b(Operand(dst), imm8); } 612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mov_b(const Operand& dst, int8_t src) { mov_b(dst, Immediate(src)); } 613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mov_b(const Operand& dst, const Immediate& src); 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mov_b(const Operand& dst, Register src); 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mov_w(Register dst, const Operand& src); 617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mov_w(const Operand& dst, int16_t src) { mov_w(dst, Immediate(src)); } 618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mov_w(const Operand& dst, const Immediate& src); 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mov_w(const Operand& dst, Register src); 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mov(Register dst, int32_t imm32); 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mov(Register dst, const Immediate& x); 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mov(Register dst, Handle<Object> handle); 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mov(Register dst, const Operand& src); 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mov(Register dst, Register src); 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mov(const Operand& dst, const Immediate& x); 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mov(const Operand& dst, Handle<Object> handle); 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mov(const Operand& dst, Register src); 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void movsx_b(Register dst, Register src) { movsx_b(dst, Operand(src)); } 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movsx_b(Register dst, const Operand& src); 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void movsx_w(Register dst, Register src) { movsx_w(dst, Operand(src)); } 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movsx_w(Register dst, const Operand& src); 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void movzx_b(Register dst, Register src) { movzx_b(dst, Operand(src)); } 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movzx_b(Register dst, const Operand& src); 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void movzx_w(Register dst, Register src) { movzx_w(dst, Operand(src)); } 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movzx_w(Register dst, const Operand& src); 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Conditional moves 6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void cmov(Condition cc, Register dst, Register src) { 6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmov(cc, dst, Operand(src)); 6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmov(Condition cc, Register dst, const Operand& src); 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Flag management. 6496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void cld(); 6506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 651e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Repetitive string instructions. 652e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void rep_movs(); 6536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void rep_stos(); 654f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke void stos(); 655e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Exchange 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void xchg(Register dst, Register src); 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xchg(Register dst, const Operand& src); 659bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void xchg_b(Register reg, const Operand& op); 660bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void xchg_w(Register reg, const Operand& op); 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 66213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Lock prefix 66313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void lock(); 66413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 66513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // CompareExchange 66613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void cmpxchg(const Operand& dst, Register src); 66713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void cmpxchg_b(const Operand& dst, Register src); 66813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void cmpxchg_w(const Operand& dst, Register src); 66913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Arithmetics 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void adc(Register dst, int32_t imm32); 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void adc(Register dst, const Operand& src); 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void add(Register dst, Register src) { add(dst, Operand(src)); } 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void add(Register dst, const Operand& src); 6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void add(const Operand& dst, Register src); 6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void add(Register dst, const Immediate& imm) { add(Operand(dst), imm); } 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void add(const Operand& dst, const Immediate& x); 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void and_(Register dst, int32_t imm32); 68159151504615d929945dc59db37bf1166937748c6Steve Block void and_(Register dst, const Immediate& x); 6823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void and_(Register dst, Register src) { and_(dst, Operand(src)); } 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void and_(Register dst, const Operand& src); 6843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void and_(const Operand& dst, Register src); 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void and_(const Operand& dst, const Immediate& x); 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void cmpb(Register reg, Immediate imm8) { cmpb(Operand(reg), imm8); } 6883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void cmpb(const Operand& op, Immediate imm8); 6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void cmpb(Register reg, const Operand& op); 6903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void cmpb(const Operand& op, Register reg); 6913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void cmpb(Register dst, Register src) { cmpb(Operand(dst), src); } 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb_al(const Operand& op); 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw_ax(const Operand& op); 6943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void cmpw(const Operand& dst, Immediate src); 6953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void cmpw(Register dst, Immediate src) { cmpw(Operand(dst), src); } 6963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void cmpw(Register dst, const Operand& src); 6973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void cmpw(Register dst, Register src) { cmpw(Operand(dst), src); } 6983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void cmpw(const Operand& dst, Register src); 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmp(Register reg, int32_t imm32); 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmp(Register reg, Handle<Object> handle); 7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void cmp(Register reg0, Register reg1) { cmp(reg0, Operand(reg1)); } 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmp(Register reg, const Operand& op); 7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void cmp(Register reg, const Immediate& imm) { cmp(Operand(reg), imm); } 704109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void cmp(const Operand& op, Register reg); 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmp(const Operand& op, const Immediate& imm); 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmp(const Operand& op, Handle<Object> handle); 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void dec_b(Register dst); 7090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void dec_b(const Operand& dst); 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void dec(Register dst); 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void dec(const Operand& dst); 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cdq(); 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void idiv(Register src) { idiv(Operand(src)); } 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void idiv(const Operand& src); 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void div(Register src) { div(Operand(src)); } 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void div(const Operand& src); 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Signed multiply instructions. 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void imul(Register src); // edx:eax = eax * src. 7233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void imul(Register dst, Register src) { imul(dst, Operand(src)); } 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void imul(Register dst, const Operand& src); // dst = dst * src. 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void imul(Register dst, Register src, int32_t imm32); // dst = src * imm32. 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void imul(Register dst, const Operand& src, int32_t imm32); 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void inc(Register dst); 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void inc(const Operand& dst); 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void lea(Register dst, const Operand& src); 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Unsigned multiply instruction. 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mul(Register src); // edx:eax = eax * reg. 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void neg(Register dst); 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void neg(const Operand& dst); 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void not_(Register dst); 740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void not_(const Operand& dst); 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void or_(Register dst, int32_t imm32); 7433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void or_(Register dst, Register src) { or_(dst, Operand(src)); } 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void or_(Register dst, const Operand& src); 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void or_(const Operand& dst, Register src); 7463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void or_(Register dst, const Immediate& imm) { or_(Operand(dst), imm); } 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void or_(const Operand& dst, const Immediate& x); 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void rcl(Register dst, uint8_t imm8); 750756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void rcr(Register dst, uint8_t imm8); 751958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ror(Register dst, uint8_t imm8) { ror(Operand(dst), imm8); } 753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ror(const Operand& dst, uint8_t imm8); 754958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ror_cl(Register dst) { ror_cl(Operand(dst)); } 755958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ror_cl(const Operand& dst); 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sar(Register dst, uint8_t imm8) { sar(Operand(dst), imm8); } 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sar(const Operand& dst, uint8_t imm8); 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sar_cl(Register dst) { sar_cl(Operand(dst)); } 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sar_cl(const Operand& dst); 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void sbb(Register dst, const Operand& src); 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shl(Register dst, uint8_t imm8) { shl(Operand(dst), imm8); } 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shl(const Operand& dst, uint8_t imm8); 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shl_cl(Register dst) { shl_cl(Operand(dst)); } 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shl_cl(const Operand& dst); 7683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void shld(Register dst, Register src, uint8_t shift); 7693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void shld_cl(Register dst, Register src); 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shr(Register dst, uint8_t imm8) { shr(Operand(dst), imm8); } 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shr(const Operand& dst, uint8_t imm8); 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shr_cl(Register dst) { shr_cl(Operand(dst)); } 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shr_cl(const Operand& dst); 7753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void shrd(Register dst, Register src, uint8_t shift); 7763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void shrd_cl(Register dst, Register src) { shrd_cl(Operand(dst), src); } 7773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void shrd_cl(const Operand& dst, Register src); 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void sub(Register dst, const Immediate& imm) { sub(Operand(dst), imm); } 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void sub(const Operand& dst, const Immediate& x); 7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void sub(Register dst, Register src) { sub(dst, Operand(src)); } 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void sub(Register dst, const Operand& src); 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void sub(const Operand& dst, Register src); 784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void test(Register reg, const Immediate& imm); 7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void test(Register reg0, Register reg1) { test(reg0, Operand(reg1)); } 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void test(Register reg, const Operand& op); 788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void test(const Operand& op, const Immediate& imm); 7893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void test(const Operand& op, Register reg) { test(reg, op); } 7903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void test_b(Register reg, const Operand& op); 7913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void test_b(Register reg, Immediate imm8); 7923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void test_b(const Operand& op, Immediate imm8); 7933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void test_b(const Operand& op, Register reg) { test_b(reg, op); } 7943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void test_b(Register dst, Register src) { test_b(dst, Operand(src)); } 7953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void test_w(Register reg, const Operand& op); 7963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void test_w(Register reg, Immediate imm16); 7973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void test_w(const Operand& op, Immediate imm16); 7983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void test_w(const Operand& op, Register reg) { test_w(reg, op); } 7993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void test_w(Register dst, Register src) { test_w(dst, Operand(src)); } 800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void xor_(Register dst, int32_t imm32); 8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void xor_(Register dst, Register src) { xor_(dst, Operand(src)); } 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void xor_(Register dst, const Operand& src); 8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void xor_(const Operand& dst, Register src); 8053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void xor_(Register dst, const Immediate& imm) { xor_(Operand(dst), imm); } 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void xor_(const Operand& dst, const Immediate& x); 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bit operations. 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bt(const Operand& dst, Register src); 8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void bts(Register dst, Register src) { bts(Operand(dst), src); } 811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bts(const Operand& dst, Register src); 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bsr(Register dst, Register src) { bsr(dst, Operand(src)); } 813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bsr(Register dst, const Operand& src); 814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsf(Register dst, Register src) { bsf(dst, Operand(src)); } 815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsf(Register dst, const Operand& src); 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Miscellaneous 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void hlt(); 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void int3(); 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void nop(); 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ret(int imm16); 822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ud2(); 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Label operations & relative jumps (PPUM Appendix D) 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Takes a branch opcode (cc) and a label (L) and generates 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // either a backward branch or a forward branch and links it 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to the label fixup chain. Usage: 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Label L; // unbound label 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // j(cc, &L); // forward branch to unbound label 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bind(&L); // bind label to the current pc 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // j(cc, &L); // backward branch to bound label 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bind(&L); // illegal: a label may be bound only once 835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note: The same Label can be used for forward and backward branches 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // but it may be bound only once. 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bind(Label* L); // binds an unbound label L to the current code position 840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calls 842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void call(Label* L); 843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void call(byte* entry, RelocInfo::Mode rmode); 844257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int CallSize(const Operand& adr); 8453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void call(Register reg) { call(Operand(reg)); } 846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void call(const Operand& adr); 847257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int CallSize(Handle<Code> code, RelocInfo::Mode mode); 848257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void call(Handle<Code> code, 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode, 850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId id = TypeFeedbackId::None()); 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Jumps 853257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // unconditional jump to L 854257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void jmp(Label* L, Label::Distance distance = Label::kFar); 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void jmp(byte* entry, RelocInfo::Mode rmode); 8563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void jmp(Register reg) { jmp(Operand(reg)); } 857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void jmp(const Operand& adr); 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void jmp(Handle<Code> code, RelocInfo::Mode rmode); 859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Conditional jumps 861257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void j(Condition cc, 862257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* L, 863257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance distance = Label::kFar); 864257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void j(Condition cc, byte* entry, RelocInfo::Mode rmode); 865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void j(Condition cc, Handle<Code> code, 866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::Mode rmode = RelocInfo::CODE_TARGET); 8670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Floating-point operations 869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld(int i); 870402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void fstp(int i); 871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld1(); 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fldz(); 874402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void fldpi(); 875b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void fldln2(); 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld_s(const Operand& adr); 878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld_d(const Operand& adr); 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fstp_s(const Operand& adr); 881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fst_s(const Operand& adr); 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fstp_d(const Operand& adr); 883402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void fst_d(const Operand& adr); 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fild_s(const Operand& adr); 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fild_d(const Operand& adr); 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fist_s(const Operand& adr); 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fistp_s(const Operand& adr); 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fistp_d(const Operand& adr); 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // The fisttp instructions require SSE3. 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fisttp_s(const Operand& adr); 895e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void fisttp_d(const Operand& adr); 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fabs(); 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fchs(); 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fcos(); 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsin(); 9013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void fptan(); 902b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void fyl2x(); 9033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void f2xm1(); 9043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void fscale(); 9053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void fninit(); 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fadd(int i); 908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fadd_i(int i); 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsub(int i); 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fsub_i(int i); 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fmul(int i); 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fmul_i(int i); 913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fdiv(int i); 914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fdiv_i(int i); 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fisub_s(const Operand& adr); 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void faddp(int i = 1); 919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsubp(int i = 1); 920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsubrp(int i = 1); 921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fmulp(int i = 1); 922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fdivp(int i = 1); 923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fprem(); 924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fprem1(); 925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fxch(int i = 1); 927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fincstp(); 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ffree(int i = 0); 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ftst(); 931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fucomp(int i); 932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fucompp(); 9333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void fucomi(int i); 9343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void fucomip(); 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fcompp(); 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fnstsw_ax(); 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fwait(); 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fnclex(); 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void frndint(); 941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void sahf(); 943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void setcc(Condition cc, Register reg); 944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cpuid(); 946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // SSE instructions 948958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void addss(XMMRegister dst, XMMRegister src) { addss(dst, Operand(src)); } 949958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void addss(XMMRegister dst, const Operand& src); 950958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void subss(XMMRegister dst, XMMRegister src) { subss(dst, Operand(src)); } 951958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void subss(XMMRegister dst, const Operand& src); 952958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mulss(XMMRegister dst, XMMRegister src) { mulss(dst, Operand(src)); } 953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mulss(XMMRegister dst, const Operand& src); 954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void divss(XMMRegister dst, XMMRegister src) { divss(dst, Operand(src)); } 955958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void divss(XMMRegister dst, const Operand& src); 956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sqrtss(XMMRegister dst, XMMRegister src) { sqrtss(dst, Operand(src)); } 957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sqrtss(XMMRegister dst, const Operand& src); 958958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ucomiss(XMMRegister dst, XMMRegister src) { ucomiss(dst, Operand(src)); } 960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ucomiss(XMMRegister dst, const Operand& src); 961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movaps(XMMRegister dst, XMMRegister src); 962f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void movups(XMMRegister dst, XMMRegister src); 963f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void movups(XMMRegister dst, const Operand& src); 964f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void movups(const Operand& dst, XMMRegister src); 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shufps(XMMRegister dst, XMMRegister src, byte imm8); 966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxss(XMMRegister dst, XMMRegister src) { maxss(dst, Operand(src)); } 968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxss(XMMRegister dst, const Operand& src); 969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void minss(XMMRegister dst, XMMRegister src) { minss(dst, Operand(src)); } 970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void minss(XMMRegister dst, const Operand& src); 971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void andps(XMMRegister dst, const Operand& src); 973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void andps(XMMRegister dst, XMMRegister src) { andps(dst, Operand(src)); } 974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xorps(XMMRegister dst, const Operand& src); 975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xorps(XMMRegister dst, XMMRegister src) { xorps(dst, Operand(src)); } 976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void orps(XMMRegister dst, const Operand& src); 977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void orps(XMMRegister dst, XMMRegister src) { orps(dst, Operand(src)); } 978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void addps(XMMRegister dst, const Operand& src); 980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void addps(XMMRegister dst, XMMRegister src) { addps(dst, Operand(src)); } 981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void subps(XMMRegister dst, const Operand& src); 982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void subps(XMMRegister dst, XMMRegister src) { subps(dst, Operand(src)); } 983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mulps(XMMRegister dst, const Operand& src); 984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mulps(XMMRegister dst, XMMRegister src) { mulps(dst, Operand(src)); } 985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void divps(XMMRegister dst, const Operand& src); 986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void divps(XMMRegister dst, XMMRegister src) { divps(dst, Operand(src)); } 987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // SSE2 instructions 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvttss2si(Register dst, const Operand& src); 990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvttss2si(Register dst, XMMRegister src) { 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cvttss2si(dst, Operand(src)); 992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvttsd2si(Register dst, const Operand& src); 994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvttsd2si(Register dst, XMMRegister src) { 995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cvttsd2si(dst, Operand(src)); 996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cvtsd2si(Register dst, XMMRegister src); 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 999109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void cvtsi2ss(XMMRegister dst, Register src) { cvtsi2ss(dst, Operand(src)); } 1000109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void cvtsi2ss(XMMRegister dst, const Operand& src); 10013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void cvtsi2sd(XMMRegister dst, Register src) { cvtsi2sd(dst, Operand(src)); } 1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvtsi2sd(XMMRegister dst, const Operand& src); 1003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cvtss2sd(XMMRegister dst, const Operand& src); 1004958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cvtss2sd(XMMRegister dst, XMMRegister src) { 1005958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cvtss2sd(dst, Operand(src)); 1006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cvtsd2ss(XMMRegister dst, const Operand& src); 1008958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void cvtsd2ss(XMMRegister dst, XMMRegister src) { 1009958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cvtsd2ss(dst, Operand(src)); 1010958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1011958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void addsd(XMMRegister dst, XMMRegister src) { addsd(dst, Operand(src)); } 1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void addsd(XMMRegister dst, const Operand& src); 1013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void subsd(XMMRegister dst, XMMRegister src) { subsd(dst, Operand(src)); } 1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void subsd(XMMRegister dst, const Operand& src); 1015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void mulsd(XMMRegister dst, XMMRegister src) { mulsd(dst, Operand(src)); } 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mulsd(XMMRegister dst, const Operand& src); 1017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void divsd(XMMRegister dst, XMMRegister src) { divsd(dst, Operand(src)); } 1018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void divsd(XMMRegister dst, const Operand& src); 1019e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void xorpd(XMMRegister dst, XMMRegister src); 1020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void sqrtsd(XMMRegister dst, XMMRegister src) { sqrtsd(dst, Operand(src)); } 1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sqrtsd(XMMRegister dst, const Operand& src); 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void andpd(XMMRegister dst, XMMRegister src); 1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void orpd(XMMRegister dst, XMMRegister src); 10250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ucomisd(XMMRegister dst, XMMRegister src) { ucomisd(dst, Operand(src)); } 10273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void ucomisd(XMMRegister dst, const Operand& src); 102869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void roundss(XMMRegister dst, XMMRegister src, RoundingMode mode); 103069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode); 103169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 10326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movmskpd(Register dst, XMMRegister src); 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movmskps(Register dst, XMMRegister src); 1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void cmpltsd(XMMRegister dst, XMMRegister src); 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pcmpeqd(XMMRegister dst, XMMRegister src); 10370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void punpckldq(XMMRegister dst, XMMRegister src); 1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void punpckhdq(XMMRegister dst, XMMRegister src); 1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxsd(XMMRegister dst, XMMRegister src) { maxsd(dst, Operand(src)); } 1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void maxsd(XMMRegister dst, const Operand& src); 1043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void minsd(XMMRegister dst, XMMRegister src) { minsd(dst, Operand(src)); } 1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void minsd(XMMRegister dst, const Operand& src); 1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1046e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void movdqa(XMMRegister dst, const Operand& src); 1047e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void movdqa(const Operand& dst, XMMRegister src); 1048e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void movdqu(XMMRegister dst, const Operand& src); 1049e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void movdqu(const Operand& dst, XMMRegister src); 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movdq(bool aligned, XMMRegister dst, const Operand& src) { 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (aligned) { 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movdqa(dst, src); 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movdqu(dst, src); 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void movd(XMMRegister dst, Register src) { movd(dst, Operand(src)); } 10596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movd(XMMRegister dst, const Operand& src); 10603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void movd(Register dst, XMMRegister src) { movd(Operand(dst), src); } 10613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void movd(const Operand& dst, XMMRegister src); 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movsd(XMMRegister dst, XMMRegister src) { movsd(dst, Operand(src)); } 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movsd(XMMRegister dst, const Operand& src); 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movsd(const Operand& dst, XMMRegister src); 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 106744f0eee88ff00398ff7f715fab053374d808c90dSteve Block void movss(XMMRegister dst, const Operand& src); 10683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void movss(const Operand& dst, XMMRegister src); 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movss(XMMRegister dst, XMMRegister src) { movss(dst, Operand(src)); } 10703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void extractps(Register dst, XMMRegister src, byte imm8); 107144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1072b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void pand(XMMRegister dst, XMMRegister src); 10736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void pxor(XMMRegister dst, XMMRegister src); 1074b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void por(XMMRegister dst, XMMRegister src); 10756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void ptest(XMMRegister dst, XMMRegister src); 10766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void pslld(XMMRegister reg, int8_t shift); 1078958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void psrld(XMMRegister reg, int8_t shift); 1079b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void psllq(XMMRegister reg, int8_t shift); 1080b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void psllq(XMMRegister dst, XMMRegister src); 1081b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void psrlq(XMMRegister reg, int8_t shift); 1082b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void psrlq(XMMRegister dst, XMMRegister src); 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle); 10843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void pextrd(Register dst, XMMRegister src, int8_t offset) { 10853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pextrd(Operand(dst), src, offset); 10863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1087b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void pextrd(const Operand& dst, XMMRegister src, int8_t offset); 10883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void pinsrd(XMMRegister dst, Register src, int8_t offset) { 10893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pinsrd(dst, Operand(src), offset); 10903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void pinsrd(XMMRegister dst, const Operand& src, int8_t offset); 10920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1093958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // AVX instructions 1094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmadd132sd(dst, src1, Operand(src2)); 1096958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1098958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmadd213sd(dst, src1, Operand(src2)); 1099958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmadd231sd(dst, src1, Operand(src2)); 1102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x99, dst, src1, src2); 1105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xa9, dst, src1, src2); 1108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xb9, dst, src1, src2); 1111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmsub132sd(dst, src1, Operand(src2)); 1114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmsub213sd(dst, src1, Operand(src2)); 1117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmsub231sd(dst, src1, Operand(src2)); 1120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9b, dst, src1, src2); 1123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xab, dst, src1, src2); 1126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbb, dst, src1, src2); 1129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfnmadd132sd(dst, src1, Operand(src2)); 1132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfnmadd213sd(dst, src1, Operand(src2)); 1135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfnmadd231sd(dst, src1, Operand(src2)); 1138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9d, dst, src1, src2); 1141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xad, dst, src1, src2); 1144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbd, dst, src1, src2); 1147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfnmsub132sd(dst, src1, Operand(src2)); 1150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfnmsub213sd(dst, src1, Operand(src2)); 1153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfnmsub231sd(dst, src1, Operand(src2)); 1156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0x9f, dst, src1, src2); 1159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xaf, dst, src1, src2); 1162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmasd(0xbf, dst, src1, src2); 1165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmasd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmadd132ss(dst, src1, Operand(src2)); 1170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmadd213ss(dst, src1, Operand(src2)); 1173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmadd231ss(dst, src1, Operand(src2)); 1176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x99, dst, src1, src2); 1179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xa9, dst, src1, src2); 1182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xb9, dst, src1, src2); 1185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmsub132ss(dst, src1, Operand(src2)); 1188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmsub213ss(dst, src1, Operand(src2)); 1191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmsub231ss(dst, src1, Operand(src2)); 1194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9b, dst, src1, src2); 1197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xab, dst, src1, src2); 1200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbb, dst, src1, src2); 1203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfnmadd132ss(dst, src1, Operand(src2)); 1206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfnmadd213ss(dst, src1, Operand(src2)); 1209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfnmadd231ss(dst, src1, Operand(src2)); 1212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9d, dst, src1, src2); 1215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xad, dst, src1, src2); 1218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbd, dst, src1, src2); 1221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfnmsub132ss(dst, src1, Operand(src2)); 1224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfnmsub213ss(dst, src1, Operand(src2)); 1227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfnmsub231ss(dst, src1, Operand(src2)); 1230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0x9f, dst, src1, src2); 1233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xaf, dst, src1, src2); 1236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfnmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vfmass(0xbf, dst, src1, src2); 1239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vfmass(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vaddsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vaddsd(dst, src1, Operand(src2)); 1244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vaddsd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vsd(0x58, dst, src1, src2); 1247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vsubsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vsubsd(dst, src1, Operand(src2)); 1250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vsubsd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vsd(0x5c, dst, src1, src2); 1253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vmulsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vmulsd(dst, src1, Operand(src2)); 1256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vmulsd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vsd(0x59, dst, src1, src2); 1259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vdivsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vdivsd(dst, src1, Operand(src2)); 1262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vdivsd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier vsd(0x5e, dst, src1, src2); 1265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmaxsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmaxsd(dst, src1, Operand(src2)); 1268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmaxsd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x5f, dst, src1, src2); 1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vminsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vminsd(dst, src1, Operand(src2)); 1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vminsd(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsd(0x5d, dst, src1, src2); 1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vaddss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vaddss(dst, src1, Operand(src2)); 1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vaddss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vss(0x58, dst, src1, src2); 1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vsubss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsubss(dst, src1, Operand(src2)); 1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vsubss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vss(0x5c, dst, src1, src2); 1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmulss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmulss(dst, src1, Operand(src2)); 1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmulss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vss(0x59, dst, src1, src2); 1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vdivss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vdivss(dst, src1, Operand(src2)); 1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vdivss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vss(0x5e, dst, src1, src2); 1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmaxss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmaxss(dst, src1, Operand(src2)); 1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vmaxss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vss(0x5f, dst, src1, src2); 1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vminss(XMMRegister dst, XMMRegister src1, XMMRegister src2) { 1311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vminss(dst, src1, Operand(src2)); 1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vminss(XMMRegister dst, XMMRegister src1, const Operand& src2) { 1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vss(0x5d, dst, src1, src2); 1315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vss(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // BMI instruction 1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void andn(Register dst, Register src1, Register src2) { 1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch andn(dst, src1, Operand(src2)); 1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void andn(Register dst, Register src1, const Operand& src2) { 1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1(0xf2, dst, src1, src2); 1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bextr(Register dst, Register src1, Register src2) { 1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bextr(dst, Operand(src1), src2); 1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bextr(Register dst, const Operand& src1, Register src2) { 1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1(0xf7, dst, src2, src1); 1330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsi(Register dst, Register src) { blsi(dst, Operand(src)); } 1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsi(Register dst, const Operand& src) { 1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {3}; 1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1(0xf3, ireg, dst, src); 1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsmsk(Register dst, Register src) { blsmsk(dst, Operand(src)); } 1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsmsk(Register dst, const Operand& src) { 1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {2}; 1339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1(0xf3, ireg, dst, src); 1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsr(Register dst, Register src) { blsr(dst, Operand(src)); } 1342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void blsr(Register dst, const Operand& src) { 1343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register ireg = {1}; 1344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi1(0xf3, ireg, dst, src); 1345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void tzcnt(Register dst, Register src) { tzcnt(dst, Operand(src)); } 1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void tzcnt(Register dst, const Operand& src); 1348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lzcnt(Register dst, Register src) { lzcnt(dst, Operand(src)); } 1350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void lzcnt(Register dst, const Operand& src); 1351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void popcnt(Register dst, Register src) { popcnt(dst, Operand(src)); } 1353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void popcnt(Register dst, const Operand& src); 1354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bzhi(Register dst, Register src1, Register src2) { 1356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bzhi(dst, Operand(src1), src2); 1357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bzhi(Register dst, const Operand& src1, Register src2) { 1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2(kNone, 0xf5, dst, src2, src1); 1360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mulx(Register dst1, Register dst2, Register src) { 1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mulx(dst1, dst2, Operand(src)); 1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mulx(Register dst1, Register dst2, const Operand& src) { 1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2(kF2, 0xf6, dst1, dst2, src); 1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pdep(Register dst, Register src1, Register src2) { 1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pdep(dst, src1, Operand(src2)); 1369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pdep(Register dst, Register src1, const Operand& src2) { 1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2(kF2, 0xf5, dst, src1, src2); 1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pext(Register dst, Register src1, Register src2) { 1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pext(dst, src1, Operand(src2)); 1375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void pext(Register dst, Register src1, const Operand& src2) { 1377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2(kF3, 0xf5, dst, src1, src2); 1378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sarx(Register dst, Register src1, Register src2) { 1380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sarx(dst, Operand(src1), src2); 1381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void sarx(Register dst, const Operand& src1, Register src2) { 1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2(kF3, 0xf7, dst, src2, src1); 1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shlx(Register dst, Register src1, Register src2) { 1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shlx(dst, Operand(src1), src2); 1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shlx(Register dst, const Operand& src1, Register src2) { 1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2(k66, 0xf7, dst, src2, src1); 1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shrx(Register dst, Register src1, Register src2) { 1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shrx(dst, Operand(src1), src2); 1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void shrx(Register dst, const Operand& src1, Register src2) { 1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bmi2(kF2, 0xf7, dst, src2, src1); 1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rorx(Register dst, Register src, byte imm8) { 1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rorx(dst, Operand(src), imm8); 1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void rorx(Register dst, const Operand& src, byte imm8); 1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define PACKED_OP_LIST(V) \ 1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(and, 0x54) \ 1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(xor, 0x57) 1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_PACKED_OP_DECLARE(name, opcode) \ 1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void v##name##ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ 1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vps(opcode, dst, src1, Operand(src2)); \ 1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void v##name##ps(XMMRegister dst, XMMRegister src1, const Operand& src2) { \ 1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vps(opcode, dst, src1, src2); \ 1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void v##name##pd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ 1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vpd(opcode, dst, src1, Operand(src2)); \ 1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void v##name##pd(XMMRegister dst, XMMRegister src1, const Operand& src2) { \ 1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vpd(opcode, dst, src1, src2); \ 1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PACKED_OP_LIST(AVX_PACKED_OP_DECLARE); 1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vps(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vps(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vpd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); 1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void vpd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2); 1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 14267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Prefetch src position into cache level. 14277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Level 1, 2 or 3 specifies CPU cache level. Level 0 specifies a 14287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // non-temporal 14297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch void prefetch(const Operand& src, int level); 14307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // TODO(lrn): Need SFENCE for movnt? 14317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check the code size generated from label to here. 14333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int SizeOfCodeGeneratedSince(Label* label) { 14343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return pc_offset() - label->pos(); 14353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Mark generator continuation. 1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordGeneratorContinuation(); 1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark address of a debug break slot. 1441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordDebugBreakSlot(RelocInfo::Mode mode); 14427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Record a comment relocation entry that can be used by a disassembler. 1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use --code-comments to enable. 1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordComment(const char* msg); 1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Record a deoptimization reason that can be used by a log or cpu profiler. 1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use --trace-deopt to enable. 1449c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position, 1450c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int id); 1451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Writes a single byte or word of data in the code stream. Used for 1453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // inline tables, e.g., jump-tables. 1454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void db(uint8_t data); 1455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void dd(uint32_t data); 1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dq(uint64_t data); 1457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dp(uintptr_t data) { dd(data); } 1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dd(Label* label); 1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if there is less than kGap bytes available in the buffer. 1461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If this is the case, we need to grow the buffer before emitting 1462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // an instruction or relocation information. 1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool buffer_overflow() const { 1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return pc_ >= reloc_info_writer.pos() - kGap; 1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the number of bytes available in the buffer. 1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline int available_space() const { return reloc_info_writer.pos() - pc_; } 1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static bool IsNop(Address addr); 14717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1472e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int relocation_writer_size() { 1473e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return (buffer_ + buffer_size_) - reloc_info_writer.pos(); 1474e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1475e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Avoid overflows for displacements etc. 1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kMaximalBufferSize = 512*MB; 1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte byte_at(int pos) { return buffer_[pos]; } 14803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void set_byte_at(int pos, byte value) { buffer_[pos] = value; } 14813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PatchConstantPoolAccessInstruction(int pc_offset, int offset, 1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access, 1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Type type) { 1485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // No embedded constant pool support. 1486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 1490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_sse_operand(XMMRegister reg, const Operand& adr); 1491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_sse_operand(XMMRegister dst, XMMRegister src); 14926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void emit_sse_operand(Register dst, XMMRegister src); 1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_sse_operand(XMMRegister dst, Register src); 1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 149544f0eee88ff00398ff7f715fab053374d808c90dSteve Block byte* addr_at(int pos) { return buffer_ + pos; } 149644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 14973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 1499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t long_at(int pos) { 1500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *reinterpret_cast<uint32_t*>(addr_at(pos)); 1501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void long_at_put(int pos, uint32_t x) { 1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; 1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // code emission 1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void GrowBuffer(); 1508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit(uint32_t x); 1509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit(Handle<Object> handle); 1510257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch inline void emit(uint32_t x, 1511257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RelocInfo::Mode rmode, 1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId id = TypeFeedbackId::None()); 1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emit(Handle<Code> code, 1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode, 1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId id = TypeFeedbackId::None()); 1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit(const Immediate& x); 15173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline void emit_b(Immediate x); 1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_w(const Immediate& x); 1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void emit_q(uint64_t x); 1520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit the code-object-relative offset of the label's position 1522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_code_relative_offset(Label* label); 1523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // instruction generation 1525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_arith_b(int op1, int op2, Register dst, int imm8); 1526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81) 1528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // with a given destination expression and an immediate operand. It attempts 1529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to use the shortest encoding possible. 1530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // sel specifies the /n in the modrm byte (see the Intel PRM). 1531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_arith(int sel, Operand dst, const Immediate& x); 1532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_operand(Register reg, const Operand& adr); 1534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void emit_label(Label* label); 1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_farith(int b1, int b2, int i); 1538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Emit vex prefix 1540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 }; 1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128, kLZ = kL128 }; 1542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 }; 1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x3 }; 1544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void emit_vex_prefix(XMMRegister v, VectorLength l, SIMDPrefix pp, 1545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LeadingOpcode m, VexW w); 1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void emit_vex_prefix(Register v, VectorLength l, SIMDPrefix pp, 1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LeadingOpcode m, VexW w); 1548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // labels 1550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void print(Label* L); 1551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bind_to(Label* L, int pos); 1552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // displacements 1554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Displacement disp_at(Label* L); 1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void disp_at_put(Label* L, Displacement disp); 1556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_disp(Label* L, Displacement::Type type); 1557257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch inline void emit_near_disp(Label* L); 1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Most BMI instructions are similiar. 1560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi1(byte op, Register reg, Register vreg, const Operand& rm); 1561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bmi2(SIMDPrefix pp, byte op, Register reg, Register vreg, 1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operand& rm); 1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // record reloc info for current pc_ 1565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class CodePatcher; 1568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class EnsureSpace; 1569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Internal reference positions, required for (potential) patching in 1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // GrowBuffer(); contains only those internal references whose labels 1572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // are already bound. 1573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch std::deque<int> internal_reference_positions_; 1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // code generation 1576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfoWriter reloc_info_writer; 1577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 1578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper class that ensures that there is enough space for generating 1581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instructions and relocation information. The constructor makes 1582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// sure that there is enough space and (in debug mode) the destructor 1583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// checks that we did not generate too much. 1584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EnsureSpace BASE_EMBEDDED { 1585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 1586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { 1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (assembler_->buffer_overflow()) assembler_->GrowBuffer(); 1588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 1589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block space_before_ = assembler_->available_space(); 1590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 1594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~EnsureSpace() { 1595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bytes_generated = space_before_ - assembler_->available_space(); 1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(bytes_generated < assembler_->kGap); 1597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 1601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler* assembler_; 1602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 1603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int space_before_; 1604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 1606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 1609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_IA32_ASSEMBLER_IA32_H_ 1611