1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright (c) 1994-2006 Sun Microsystems Inc.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All Rights Reserved.
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistributions of source code must retain the above copyright notice,
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this list of conditions and the following disclaimer.
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistribution in binary form must reproduce the above copyright
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer in the
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// documentation and/or other materials provided with the distribution.
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Neither the name of Sun Microsystems or the names of contributors may
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be used to endorse or promote products derived from this software without
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// specific prior written permission.
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The original source code covered by the above license above has been
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modified significantly by Google Inc.
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A lightweight X64 Assembler.
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_X64_ASSEMBLER_X64_H_
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_X64_ASSEMBLER_X64_H_
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <deque>
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/assembler.h"
43f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/x64/sse-instr.h"
44d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utility functions
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define GENERAL_REGISTERS(V) \
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rax)                     \
52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rcx)                     \
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rdx)                     \
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rbx)                     \
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rsp)                     \
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rbp)                     \
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rsi)                     \
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rdi)                     \
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r8)                      \
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r9)                      \
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r10)                     \
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r11)                     \
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r12)                     \
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r13)                     \
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r14)                     \
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r15)
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_GENERAL_REGISTERS(V) \
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rax)                                 \
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rbx)                                 \
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rdx)                                 \
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rcx)                                 \
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rsi)                                 \
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rdi)                                 \
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r8)                                  \
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r9)                                  \
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r11)                                 \
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r12)                                 \
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r14)                                 \
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r15)
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
8262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// The length of pushq(rbp), movp(rbp, rsp), Push(rsi) and Push(rdi).
8362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstatic const int kNoCodeAgeSequenceLength = kPointerSize == kInt64Size ? 6 : 17;
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CPU Registers.
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 1) We would prefer to use an enum, but enum values are assignment-
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// compatible with int, which has caused code-generation bugs.
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 2) We would prefer to use a class instead of a struct but we don't like
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the register initialization to depend on the particular initialization
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order (which appears to be different on OS X, Linux, and Windows for the
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// installed versions of C++ we tried). Using a struct permits C-style
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "initialization". Also, the Register objects cannot be const as this
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// forces initialization stubs in MSVC, making us dependent on initialization
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order.
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 3) By not using an enum, we are possibly preventing the compiler from
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// doing certain constant folds, which may significantly reduce the
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// code generated for some assembly instructions (because they boil down
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to a few constants). If this is a problem, we could change the code
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// such that we use an enum in optimized mode, and the struct in debug
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// mode. This way we get the compile-time error checking in debug mode
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and best performance in optimized code.
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct Register {
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum Code {
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R,
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GENERAL_REGISTERS(REGISTER_CODE)
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        kAfterLast,
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kCode_no_reg = -1
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
114b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const int kNumRegisters = Code::kAfterLast;
116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static Register from_code(int code) {
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(code >= 0);
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(code < kNumRegisters);
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register r = {code};
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return r;
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is(Register reg) const { return reg_code == reg.reg_code; }
1250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int code() const {
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_valid());
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return reg_code;
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int bit() const {
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(is_valid());
131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return 1 << reg_code;
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_byte_register() const { return reg_code <= 3; }
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the high bit of the register code as a 0 or 1.  Used often
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // when constructing the REX prefix byte.
137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int high_bit() const { return reg_code >> 3; }
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the 3 low bits of the register code.  Used when encoding registers
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in modR/M, SIB, and opcode bytes.
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int low_bits() const { return reg_code & 0x7; }
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Unfortunately we can't make this private in a struct when initializing
1433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // by assignment.
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int reg_code;
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochGENERAL_REGISTERS(DECLARE_REGISTER)
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register no_reg = {Register::kCode_no_reg};
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef _WIN64
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Windows calling convention
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_1 = {Register::kCode_rcx};
157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_2 = {Register::kCode_rdx};
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_3 = {Register::kCode_r8};
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_4 = {Register::kCode_r9};
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // AMD64 calling convention
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_1 = {Register::kCode_rdi};
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_2 = {Register::kCode_rsi};
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_3 = {Register::kCode_rdx};
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_4 = {Register::kCode_rcx};
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // _WIN64
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DOUBLE_REGISTERS(V) \
170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm0)                   \
171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm1)                   \
172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm2)                   \
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm3)                   \
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm4)                   \
175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm5)                   \
176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm6)                   \
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm7)                   \
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm8)                   \
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm9)                   \
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm10)                  \
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm11)                  \
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm12)                  \
183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm13)                  \
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm14)                  \
185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm15)
186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
187bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define FLOAT_REGISTERS DOUBLE_REGISTERS
188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define SIMD128_REGISTERS DOUBLE_REGISTERS
189bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
19113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  V(xmm0)                               \
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm1)                               \
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm2)                               \
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm3)                               \
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm4)                               \
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm5)                               \
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm6)                               \
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm7)                               \
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm8)                               \
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm9)                               \
201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm10)                              \
202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm11)                              \
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm12)                              \
204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm13)                              \
20513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  V(xmm14)
20613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
20713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochstatic const bool kSimpleFPAliasing = true;
20862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstatic const bool kSimdMaskRegisters = false;
209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
210bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochstruct XMMRegister {
211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum Code {
212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R,
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DOUBLE_REGISTERS(REGISTER_CODE)
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE
215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        kAfterLast,
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kCode_no_reg = -1
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const int kMaxNumRegisters = Code::kAfterLast;
220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
221bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  static XMMRegister from_code(int code) {
222bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    XMMRegister result = {code};
223b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    return result;
224b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
225b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
227bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  bool is(XMMRegister reg) const { return reg_code == reg.reg_code; }
2280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int code() const {
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_valid());
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return reg_code;
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the high bit of the register code as a 0 or 1.  Used often
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // when constructing the REX prefix byte.
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int high_bit() const { return reg_code >> 3; }
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the 3 low bits of the register code.  Used when encoding registers
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in modR/M, SIB, and opcode bytes.
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int low_bits() const { return reg_code & 0x7; }
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Unfortunately we can't make this private in a struct when initializing
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // by assignment.
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int reg_code;
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
245bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtypedef XMMRegister FloatRegister;
246bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
247bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtypedef XMMRegister DoubleRegister;
248bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
249bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtypedef XMMRegister Simd128Register;
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) \
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const DoubleRegister R = {DoubleRegister::kCode_##R};
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDOUBLE_REGISTERS(DECLARE_REGISTER)
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum Condition {
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // any value < 0 is considered no_condition
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  no_condition  = -1,
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  overflow      =  0,
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  no_overflow   =  1,
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  below         =  2,
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  above_equal   =  3,
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  equal         =  4,
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  not_equal     =  5,
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  below_equal   =  6,
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  above         =  7,
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  negative      =  8,
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  positive      =  9,
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  parity_even   = 10,
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  parity_odd    = 11,
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  less          = 12,
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  greater_equal = 13,
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  less_equal    = 14,
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  greater       = 15,
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Fake conditions that are handled by the
2793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // opcodes using them.
2803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  always        = 16,
2813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  never         = 17,
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // aliases
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  carry         = below,
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  not_carry     = above_equal,
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  zero          = equal,
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  not_zero      = not_equal,
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  sign          = negative,
2883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  not_sign      = positive,
2893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  last_condition = greater
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns the equivalent of !cc.
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Negation of the default no_condition (-1) results in a non-default
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// no_condition value (-2). As long as tests for no_condition check
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for condition < 0, this will work as expected.
2979dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monseninline Condition NegateCondition(Condition cc) {
2989dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return static_cast<Condition>(cc ^ 1);
2999dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
3009dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Commute a condition such that {a cond b == b cond' a}.
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline Condition CommuteCondition(Condition cc) {
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  switch (cc) {
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case below:
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return above;
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case above:
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return below;
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case above_equal:
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return below_equal;
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case below_equal:
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return above_equal;
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case less:
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return greater;
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case greater:
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return less;
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case greater_equal:
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return less_equal;
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case less_equal:
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return greater_equal;
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    default:
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return cc;
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3269dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum RoundingMode {
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  kRoundToNearest = 0x0,
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  kRoundDown = 0x1,
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  kRoundUp = 0x2,
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  kRoundToZero = 0x3
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Machine instruction Immediates
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Immediate BASE_EMBEDDED {
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit Immediate(int32_t value) : value_(value) {}
341bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  explicit Immediate(int32_t value, RelocInfo::Mode rmode)
342bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      : value_(value), rmode_(rmode) {}
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit Immediate(Smi* value) {
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());  // Only available for 31-bit SMI.
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ = static_cast<int32_t>(reinterpret_cast<intptr_t>(value));
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int32_t value_;
350bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RelocInfo::Mode rmode_ = RelocInfo::NONE32;
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class Assembler;
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Machine instruction Operands
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum ScaleFactor {
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  times_1 = 0,
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  times_2 = 1,
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  times_4 = 2,
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  times_8 = 3,
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  times_int_size = times_4,
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  times_pointer_size = (kPointerSize == 8) ? times_8 : times_4
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Operand BASE_EMBEDDED {
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [base + disp/r]
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Operand(Register base, int32_t disp);
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [base + index*scale + disp/r]
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Operand(Register base,
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          Register index,
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          ScaleFactor scale,
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          int32_t disp);
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [index*scale + disp/r]
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Operand(Register index,
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          ScaleFactor scale,
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          int32_t disp);
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
385f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Offset from existing memory operand.
386f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Offset is added to existing displacement as 32-bit signed values and
387f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // this must not overflow.
388f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Operand(const Operand& base, int32_t offset);
389f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // [rip + disp/r]
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit Operand(Label* label);
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Checks whether either base or index register is the given register.
3941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Does not check the "reg" part of the Operand.
3951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool AddressUsesRegister(Register reg) const;
3961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
39744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Queries related to the size of the generated instruction.
39844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Whether the generated instruction will have a REX prefix.
39944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool requires_rex() const { return rex_ != 0; }
40044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Size of the ModR/M, SIB and displacement parts of the generated
40144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // instruction.
40244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int operand_size() const { return len_; }
40344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte rex_;
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  byte buf_[9];
4071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // The number of bytes of buf_ in use.
4081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  byte len_;
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the ModR/M byte without an encoded 'reg' register. The
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register is encoded later as part of the emit_operand operation.
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // set_modrm can be called before or after set_sib and set_disp*.
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_modrm(int mod, Register rm);
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the SIB byte if one is needed. Sets the length to 2 rather than 1.
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_sib(ScaleFactor scale, Register index, Register base);
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Adds operand displacement fields (offsets added to the memory address).
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Needs to be called after set_sib, not before it.
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_disp8(int disp);
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_disp32(int disp);
422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline void set_disp64(int64_t disp);  // for labels.
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class Assembler;
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ASSEMBLER_INSTRUCTION_LIST(V) \
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(add)                              \
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(and)                              \
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(cmp)                              \
43113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  V(cmpxchg)                          \
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(dec)                              \
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(idiv)                             \
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(div)                              \
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(imul)                             \
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(inc)                              \
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(lea)                              \
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(mov)                              \
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(movzxb)                           \
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(movzxw)                           \
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(neg)                              \
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(not)                              \
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(or)                               \
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(repmovs)                          \
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(sbb)                              \
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(sub)                              \
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(test)                             \
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(xchg)                             \
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(xor)
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shift instructions on operands/registers with kPointerSize, kInt32Size and
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// kInt64Size.
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define SHIFT_INSTRUCTION_LIST(V)       \
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(rol, 0x0)                           \
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ror, 0x1)                           \
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(rcl, 0x2)                           \
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(rcr, 0x3)                           \
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(shl, 0x4)                           \
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(shr, 0x5)                           \
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(sar, 0x7)                           \
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Assembler : public AssemblerBase {
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // We check before assembling an instruction that there is sufficient
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // space to write an instruction and its relocation information.
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The relocation writer's position must be kGap bytes above the end of
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the generated instructions. This leaves enough space for the
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // longest possible x64 instruction, 15 bytes, and the longest possible
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // (There is a 15 byte limit on x64 instruction length that rules out some
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // otherwise valid instructions.)
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This allows for a single, fast space check per instruction.
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kGap = 32;
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Create an assembler. Instructions and relocation information are emitted
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // into a buffer, with the instructions starting from the beginning and the
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // relocation information starting from the end of the buffer. See CodeDesc
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for a detailed comment on the layout (globals.h).
481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the provided buffer is NULL, the assembler allocates and grows its own
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // buffer, and buffer_size determines the initial buffer size. The buffer is
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // owned by the assembler and deallocated upon destruction of the assembler.
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the provided buffer is not NULL, the assembler uses the provided buffer
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for code generation and assumes its size to be buffer_size. If the buffer
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is too small, a fatal error occurs. No deallocation of the buffer is done
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // upon destruction of the assembler.
4908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler(Isolate* isolate, void* buffer, int buffer_size);
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~Assembler() { }
49244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // GetCode emits any pending (non-emitted) code and fills the descriptor
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // desc. GetCode() is idempotent; it returns the same result if no other
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Assembler functions are invoked in between GetCode() calls.
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GetCode(CodeDesc* desc);
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Read/Modify the code target in the relative branch/call instruction at pc.
4993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // On the x64 architecture, we use relative jumps with a 32-bit displacement
5003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // to jump to other Code objects in the Code space in the heap.
5013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Jumps to C functions are done indirectly through a 64-bit register holding
5023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // the absolute address of the target.
5033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // These functions convert between absolute Addresses of Code objects and
5043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // the relative displacements stored in the code.
505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline Address target_address_at(Address pc, Address constant_pool);
506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline void set_target_address_at(
507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Isolate* isolate, Address pc, Address constant_pool, Address target,
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
50962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static inline Address target_address_at(Address pc, Code* code);
510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline void set_target_address_at(
511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Isolate* isolate, Address pc, Code* code, Address target,
51262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Return the code target address at a call site from the return address
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of that call in the instruction stream.
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Address target_address_from_return_address(Address pc);
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
518d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // This sets the branch destination (which is in the instruction on x64).
519d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // This is for calls and branches within generated code.
5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline static void deserialization_set_special_target_at(
521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Isolate* isolate, Address instruction_payload, Code* code,
52262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Address target);
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
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline RelocInfo::Mode RelocInfoNone() {
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (kPointerSize == kInt64Size) {
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return RelocInfo::NONE64;
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(kPointerSize == kInt32Size);
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return RelocInfo::NONE32;
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
536d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
537d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
5383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline Handle<Object> code_target_object_handle_at(Address pc);
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline Address runtime_entry_at(Address pc);
540d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Number of bytes taken up by the branch target in the code.
5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSpecialTargetSize = 4;  // Use 32-bit displacement.
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Distance between the address of the code target in the call instruction
5433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // and the return address pushed on the stack.
5443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static const int kCallTargetAddressOffset = 4;  // Use 32-bit displacement.
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The length of call(kScratchRegister).
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kCallScratchRegisterInstructionLength = 3;
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The length of call(Immediate32).
5481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kShortCallInstructionLength = 5;
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The length of movq(kScratchRegister, address).
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMoveAddressIntoScratchRegisterInstructionLength =
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      2 + kPointerSize;
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The length of movq(kScratchRegister, address) and call(kScratchRegister).
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kCallSequenceLength =
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kMoveAddressIntoScratchRegisterInstructionLength +
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kCallScratchRegisterInstructionLength;
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The debug break slot must be able to contain an indirect call sequence.
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kDebugBreakSlotLength = kCallSequenceLength;
559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Distance between start of patched debug break slot and the emitted address
560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // to jump to.
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kPatchDebugBreakSlotAddressOffset =
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kMoveAddressIntoScratchRegisterInstructionLength - kPointerSize;
5637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5649fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // One byte opcode for test eax,0xXXXXXXXX.
5659fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  static const byte kTestEaxByte = 0xA9;
5661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // One byte opcode for test al, 0xXX.
5671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kTestAlByte = 0xA8;
5681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // One byte opcode for nop.
5691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kNopByte = 0x90;
5701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // One byte prefix for a short conditional jump.
5721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kJccShortPrefix = 0x70;
5731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
5741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kJcShortOpcode = kJccShortPrefix | carry;
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const byte kJzShortOpcode = kJccShortPrefix | zero;
5771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // VEX prefix encodings.
579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 };
580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128, kLZ = kL128 };
581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 };
582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x3 };
5837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Code generation
586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Function names correspond one-to-one to x64 instruction mnemonics.
588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Unless specified otherwise, instructions operate on 64-bit operands.
589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If we need versions of an assembly instruction that operate on different
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // width arguments, we add a single-letter suffix specifying the width.
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This is done for the following instructions: mov, cmp, inc, dec,
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // add, sub, and test.
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // There are no versions of these instructions without the suffix.
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - Instructions on 16-bit (word) operands/registers have a trailing 'w'.
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - Instructions on 64-bit (quadword) operands/registers use 'q'.
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - Instructions on operands/registers with pointer size use 'p'.
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size);
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARE_INSTRUCTION(instruction)                \
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1>                                    \
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##p(P1 p1) {                          \
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, kPointerSize);               \
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1>                                    \
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##l(P1 p1) {                          \
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, kInt32Size);                 \
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1>                                    \
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##q(P1 p1) {                          \
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, kInt64Size);                 \
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2>                          \
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##p(P1 p1, P2 p2) {                   \
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, p2, kPointerSize);           \
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2>                          \
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##l(P1 p1, P2 p2) {                   \
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, p2, kInt32Size);             \
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2>                          \
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##q(P1 p1, P2 p2) {                   \
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, p2, kInt64Size);             \
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2, class P3>                \
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##p(P1 p1, P2 p2, P3 p3) {            \
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, p2, p3, kPointerSize);       \
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2, class P3>                \
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##l(P1 p1, P2 p2, P3 p3) {            \
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, p2, p3, kInt32Size);         \
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2, class P3>                \
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##q(P1 p1, P2 p2, P3 p3) {            \
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, p2, p3, kInt64Size);         \
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION)
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_INSTRUCTION
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Insert the smallest number of nop instructions
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // possible to align the pc offset to a multiple
6531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // of m, where m must be a power of 2.
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Align(int m);
655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Insert the smallest number of zero bytes possible to align the pc offset
656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // to a mulitple of m. m must be a power of 2 (>= 2).
657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DataAlign(int m);
6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Nop(int bytes = 1);
6599dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Aligns code to something that's optimal for a jump target for the platform.
6609dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  void CodeTargetAlign();
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Stack
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void pushfq();
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void popfq();
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void pushq(Immediate value);
6671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Push a 32 bit integer, and guarantee that it is actually pushed as a
6681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // 32 bit value, the normal push will optimize the 8 bit case.
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void pushq_imm32(int32_t imm32);
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void pushq(Register src);
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void pushq(const Operand& src);
672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void popq(Register dst);
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void popq(const Operand& dst);
675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void enter(Immediate size);
677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void leave();
678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Moves
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movb(Register dst, const Operand& src);
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movb(Register dst, Immediate imm);
682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movb(const Operand& dst, Register src);
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movb(const Operand& dst, Immediate imm);
684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Move the low 16 bits of a 64-bit register value to a 16-bit
6863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // memory location.
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movw(Register dst, const Operand& src);
6883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void movw(const Operand& dst, Register src);
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movw(const Operand& dst, Immediate imm);
6903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Move the offset of the label location relative to the current
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // position (after the move) to the destination.
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movl(const Operand& dst, Label* src);
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Loads a pointer into a register with a relocation mode.
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movp(Register dst, void* ptr, RelocInfo::Mode rmode);
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Loads a 64-bit immediate into a register.
6993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void movq(Register dst, int64_t value,
7003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            RelocInfo::Mode rmode = RelocInfo::NONE64);
7013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void movq(Register dst, uint64_t value,
7023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            RelocInfo::Mode rmode = RelocInfo::NONE64);
703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void movsxbl(Register dst, Register src);
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movsxbl(Register dst, const Operand& src);
706f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void movsxbq(Register dst, Register src);
7073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void movsxbq(Register dst, const Operand& src);
708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void movsxwl(Register dst, Register src);
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movsxwl(Register dst, const Operand& src);
710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void movsxwq(Register dst, Register src);
7113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void movsxwq(Register dst, const Operand& src);
712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movsxlq(Register dst, Register src);
713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movsxlq(Register dst, const Operand& src);
714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
715d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Repeated moves.
716d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
717d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void repmovsb();
718d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void repmovsw();
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void repmovsp() { emit_repmovs(kPointerSize); }
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void repmovsl() { emit_repmovs(kInt32Size); }
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void repmovsq() { emit_repmovs(kInt64Size); }
722d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
72344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Instruction to load from an immediate 64-bit pointer into RAX.
724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void load_rax(void* ptr, RelocInfo::Mode rmode);
725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void load_rax(ExternalReference ext);
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Conditional moves.
728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmovq(Condition cc, Register dst, Register src);
729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmovq(Condition cc, Register dst, const Operand& src);
730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmovl(Condition cc, Register dst, Register src);
731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmovl(Condition cc, Register dst, const Operand& src);
732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(Register dst, Immediate src) {
734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_8(0x7, dst, src);
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb_al(Immediate src);
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(Register dst, Register src) {
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op_8(0x3A, dst, src);
741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(Register dst, const Operand& src) {
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op_8(0x3A, dst, src);
745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(const Operand& dst, Register src) {
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op_8(0x38, src, dst);
749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(const Operand& dst, Immediate src) {
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_8(0x7, dst, src);
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(const Operand& dst, Immediate src) {
756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_16(0x7, dst, src);
757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(Register dst, Immediate src) {
760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_16(0x7, dst, src);
761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(Register dst, const Operand& src) {
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_16(0x3B, dst, src);
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(Register dst, Register src) {
768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_16(0x3B, dst, src);
769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(const Operand& dst, Register src) {
772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_16(0x39, src, dst);
773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void testb(Register reg, const Operand& op) { testb(op, reg); }
7763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
7773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void testw(Register reg, const Operand& op) { testw(op, reg); }
7783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
7794515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  void andb(Register dst, Immediate src) {
7804515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke    immediate_arithmetic_op_8(0x4, dst, src);
7814515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  }
7823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
7833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void decb(Register dst);
7843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void decb(const Operand& dst);
785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
78613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Lock prefix.
78713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void lock();
78813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
789bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void xchgb(Register reg, const Operand& op);
790bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void xchgw(Register reg, const Operand& op);
791bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
79213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void cmpxchgb(const Operand& dst, Register src);
79313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void cmpxchgw(const Operand& dst, Register src);
79413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sign-extends rax into rdx:rax.
796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cqo();
797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sign-extends eax into edx:eax.
798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cdq();
799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Multiply eax by src, put the result in edx:eax.
801958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void mull(Register src);
802958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void mull(const Operand& src);
803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Multiply rax by src, put the result in rdx:rax.
804958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void mulq(Register src);
805958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
806958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode)                       \
807958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##p(Register dst, Immediate imm8) {                         \
808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    shift(dst, imm8, subcode, kPointerSize);                                  \
809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                                           \
810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##l(Register dst, Immediate imm8) {                         \
812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    shift(dst, imm8, subcode, kInt32Size);                                    \
813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                                           \
814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##q(Register dst, Immediate imm8) {                         \
816958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    shift(dst, imm8, subcode, kInt64Size);                                    \
817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                                           \
818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##p(Operand dst, Immediate imm8) {                          \
820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    shift(dst, imm8, subcode, kPointerSize);                                  \
821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                                           \
822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##l(Operand dst, Immediate imm8) {                          \
824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    shift(dst, imm8, subcode, kInt32Size);                                    \
825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                                           \
826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##q(Operand dst, Immediate imm8) {                          \
828958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    shift(dst, imm8, subcode, kInt64Size);                                    \
829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                                           \
830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##p_cl(Register dst) { shift(dst, subcode, kPointerSize); } \
832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##l_cl(Register dst) { shift(dst, subcode, kInt32Size); }   \
834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
835958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##q_cl(Register dst) { shift(dst, subcode, kInt64Size); }   \
836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##p_cl(Operand dst) { shift(dst, subcode, kPointerSize); }  \
838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##l_cl(Operand dst) { shift(dst, subcode, kInt32Size); }    \
840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##q_cl(Operand dst) { shift(dst, subcode, kInt64Size); }
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION)
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_SHIFT_INSTRUCTION
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifts dst:src left by cl bits, affecting only dst.
846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shld(Register dst, Register src);
847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifts src:dst right by cl bits, affecting only dst.
849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shrd(Register dst, Register src);
850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void store_rax(void* dst, RelocInfo::Mode mode);
852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void store_rax(ExternalReference ref);
853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subb(Register dst, Immediate src) {
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_8(0x5, dst, src);
856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void testb(Register dst, Register src);
859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void testb(Register reg, Immediate mask);
860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void testb(const Operand& op, Immediate mask);
861e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void testb(const Operand& op, Register reg);
862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void testw(Register dst, Register src);
8643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void testw(Register reg, Immediate mask);
8653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void testw(const Operand& op, Immediate mask);
8663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void testw(const Operand& op, Register reg);
8673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bit operations.
869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void bt(const Operand& dst, Register src);
870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void bts(const Operand& dst, Register src);
871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsrq(Register dst, Register src);
872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsrq(Register dst, const Operand& src);
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bsrl(Register dst, Register src);
874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsrl(Register dst, const Operand& src);
875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsfq(Register dst, Register src);
876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsfq(Register dst, const Operand& src);
877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsfl(Register dst, Register src);
878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsfl(Register dst, const Operand& src);
879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Miscellaneous
8813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void clc();
88244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void cld();
883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cpuid();
884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void hlt();
885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void int3();
886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void nop();
887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ret(int imm16);
888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ud2();
889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void setcc(Condition cc, Register reg);
890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Label operations & relative jumps (PPUM Appendix D)
892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Takes a branch opcode (cc) and a label (L) and generates
894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // either a backward branch or a forward branch and links it
895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to the label fixup chain. Usage:
896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Label L;    // unbound label
898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // j(cc, &L);  // forward branch to unbound label
899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // bind(&L);   // bind label to the current pc
900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // j(cc, &L);  // backward branch to bound label
901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // bind(&L);   // illegal: a label may be bound only once
902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Note: The same Label can be used for forward and backward branches
904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // but it may be bound only once.
905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void bind(Label* L);  // binds an unbound label L to the current code position
907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Calls
909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call near relative 32-bit displacement, relative to next instruction.
910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void call(Label* L);
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void call(Address entry, RelocInfo::Mode rmode);
912257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void call(Handle<Code> target,
9133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            TypeFeedbackId ast_id = TypeFeedbackId::None());
915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Calls directly to the given address using a relative offset.
9171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Should only ever be used in Code objects for calls within the
9181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // same Code object. Should not be used when generating new code (use labels),
9191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // but only when patching existing code.
9201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void call(Address target);
9211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call near absolute indirect, address in register
923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void call(Register adr);
924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jumps
926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump short or near relative.
9273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Use a 32-bit signed displacement.
928257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Unconditional jump to L
929257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void jmp(Label* L, Label::Distance distance = Label::kFar);
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void jmp(Address entry, RelocInfo::Mode rmode);
9313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void jmp(Handle<Code> target, RelocInfo::Mode rmode);
932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump near absolute indirect (r64)
934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void jmp(Register adr);
935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void jmp(const Operand& src);
936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Conditional jumps
938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void j(Condition cc,
939257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch         Label* L,
940257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch         Label::Distance distance = Label::kFar);
941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void j(Condition cc, Address entry, RelocInfo::Mode rmode);
9423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Floating-point operations
945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fld(int i);
946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fld1();
948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fldz();
9496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void fldpi();
950b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void fldln2();
951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fld_s(const Operand& adr);
953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fld_d(const Operand& adr);
954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fstp_s(const Operand& adr);
956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fstp_d(const Operand& adr);
9573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void fstp(int index);
958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fild_s(const Operand& adr);
960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fild_d(const Operand& adr);
961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fist_s(const Operand& adr);
963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fistp_s(const Operand& adr);
965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fistp_d(const Operand& adr);
966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fisttp_s(const Operand& adr);
968d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void fisttp_d(const Operand& adr);
969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fabs();
971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fchs();
972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fadd(int i);
974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fsub(int i);
975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fmul(int i);
976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fdiv(int i);
977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fisub_s(const Operand& adr);
979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void faddp(int i = 1);
981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fsubp(int i = 1);
982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fsubrp(int i = 1);
983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fmulp(int i = 1);
984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fdivp(int i = 1);
985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fprem();
986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fprem1();
987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fxch(int i = 1);
989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fincstp();
990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ffree(int i = 0);
991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ftst();
993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fucomp(int i);
994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fucompp();
9953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void fucomi(int i);
9963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void fucomip();
9973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fcompp();
999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fnstsw_ax();
1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fwait();
1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fnclex();
1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fsin();
1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fcos();
10053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void fptan();
1006b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void fyl2x();
10073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void f2xm1();
10083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void fscale();
10093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void fninit();
1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void frndint();
1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void sahf();
1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // SSE instructions
1016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void addss(XMMRegister dst, XMMRegister src);
1017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void addss(XMMRegister dst, const Operand& src);
1018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void subss(XMMRegister dst, XMMRegister src);
1019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void subss(XMMRegister dst, const Operand& src);
1020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void mulss(XMMRegister dst, XMMRegister src);
1021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void mulss(XMMRegister dst, const Operand& src);
1022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void divss(XMMRegister dst, XMMRegister src);
1023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void divss(XMMRegister dst, const Operand& src);
1024958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void maxss(XMMRegister dst, XMMRegister src);
1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void maxss(XMMRegister dst, const Operand& src);
1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void minss(XMMRegister dst, XMMRegister src);
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void minss(XMMRegister dst, const Operand& src);
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void sqrtss(XMMRegister dst, XMMRegister src);
1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void sqrtss(XMMRegister dst, const Operand& src);
1032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void ucomiss(XMMRegister dst, XMMRegister src);
1034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void ucomiss(XMMRegister dst, const Operand& src);
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movaps(XMMRegister dst, XMMRegister src);
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Don't use this unless it's important to keep the
1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // top half of the destination register unchanged.
1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Use movaps when moving float values and movd for integer
1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // values in xmm registers.
1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void movss(XMMRegister dst, XMMRegister src);
1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movss(XMMRegister dst, const Operand& src);
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movss(const Operand& dst, XMMRegister src);
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void shufps(XMMRegister dst, XMMRegister src, byte imm8);
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvttss2si(Register dst, const Operand& src);
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvttss2si(Register dst, XMMRegister src);
1049109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void cvtlsi2ss(XMMRegister dst, const Operand& src);
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvtlsi2ss(XMMRegister dst, Register src);
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void andps(XMMRegister dst, XMMRegister src);
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void andps(XMMRegister dst, const Operand& src);
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void orps(XMMRegister dst, XMMRegister src);
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void orps(XMMRegister dst, const Operand& src);
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void xorps(XMMRegister dst, XMMRegister src);
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void xorps(XMMRegister dst, const Operand& src);
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void addps(XMMRegister dst, XMMRegister src);
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void addps(XMMRegister dst, const Operand& src);
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void subps(XMMRegister dst, XMMRegister src);
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void subps(XMMRegister dst, const Operand& src);
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mulps(XMMRegister dst, XMMRegister src);
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mulps(XMMRegister dst, const Operand& src);
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void divps(XMMRegister dst, XMMRegister src);
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void divps(XMMRegister dst, const Operand& src);
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movmskps(Register dst, XMMRegister src);
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1070f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vinstr(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2,
1071f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              SIMDPrefix pp, LeadingOpcode m, VexW w);
1072f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vinstr(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2,
1073f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              SIMDPrefix pp, LeadingOpcode m, VexW w);
1074f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // SSE2 instructions
1076f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void sse2_instr(XMMRegister dst, XMMRegister src, byte prefix, byte escape,
1077f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  byte opcode);
1078f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void sse2_instr(XMMRegister dst, const Operand& src, byte prefix, byte escape,
1079f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  byte opcode);
1080f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define DECLARE_SSE2_INSTRUCTION(instruction, prefix, escape, opcode) \
1081f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void instruction(XMMRegister dst, XMMRegister src) {                \
1082f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    sse2_instr(dst, src, 0x##prefix, 0x##escape, 0x##opcode);         \
1083f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }                                                                   \
1084f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void instruction(XMMRegister dst, const Operand& src) {             \
1085f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    sse2_instr(dst, src, 0x##prefix, 0x##escape, 0x##opcode);         \
1086f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1087f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1088f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  SSE2_INSTRUCTION_LIST(DECLARE_SSE2_INSTRUCTION)
1089f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef DECLARE_SSE2_INSTRUCTION
1090f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1091f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define DECLARE_SSE2_AVX_INSTRUCTION(instruction, prefix, escape, opcode)    \
1092f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void v##instruction(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
1093f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0);          \
1094f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }                                                                          \
1095f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void v##instruction(XMMRegister dst, XMMRegister src1,                     \
1096f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                      const Operand& src2) {                                 \
1097f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0);          \
1098f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1099f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1100f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  SSE2_INSTRUCTION_LIST(DECLARE_SSE2_AVX_INSTRUCTION)
1101f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef DECLARE_SSE2_AVX_INSTRUCTION
1102f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1103f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // SSE3
1104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void lddqu(XMMRegister dst, const Operand& src);
1105f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1106f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // SSSE3
1107f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ssse3_instr(XMMRegister dst, XMMRegister src, byte prefix, byte escape1,
1108f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                   byte escape2, byte opcode);
1109f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void ssse3_instr(XMMRegister dst, const Operand& src, byte prefix,
1110f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                   byte escape1, byte escape2, byte opcode);
1111f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1112f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define DECLARE_SSSE3_INSTRUCTION(instruction, prefix, escape1, escape2,     \
1113f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  opcode)                                    \
1114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void instruction(XMMRegister dst, XMMRegister src) {                       \
1115f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ssse3_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
1116f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }                                                                          \
1117f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void instruction(XMMRegister dst, const Operand& src) {                    \
1118f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ssse3_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
1119f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1120f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1121f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  SSSE3_INSTRUCTION_LIST(DECLARE_SSSE3_INSTRUCTION)
1122f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef DECLARE_SSSE3_INSTRUCTION
1123f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1124f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // SSE4
1125f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void sse4_instr(XMMRegister dst, XMMRegister src, byte prefix, byte escape1,
1126f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  byte escape2, byte opcode);
1127f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void sse4_instr(XMMRegister dst, const Operand& src, byte prefix,
1128f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  byte escape1, byte escape2, byte opcode);
1129f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define DECLARE_SSE4_INSTRUCTION(instruction, prefix, escape1, escape2,     \
1130f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 opcode)                                    \
1131f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void instruction(XMMRegister dst, XMMRegister src) {                      \
1132f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
1133f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }                                                                         \
1134f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void instruction(XMMRegister dst, const Operand& src) {                   \
1135f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
1136f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1137f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1138f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  SSE4_INSTRUCTION_LIST(DECLARE_SSE4_INSTRUCTION)
1139f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef DECLARE_SSE4_INSTRUCTION
1140f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1141f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define DECLARE_SSE34_AVX_INSTRUCTION(instruction, prefix, escape1, escape2,  \
1142f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                      opcode)                                 \
1143f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void v##instruction(XMMRegister dst, XMMRegister src1, XMMRegister src2) {  \
1144f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0); \
1145f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }                                                                           \
1146f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void v##instruction(XMMRegister dst, XMMRegister src1,                      \
1147f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                      const Operand& src2) {                                  \
1148f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0); \
1149f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1150f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1151f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  SSSE3_INSTRUCTION_LIST(DECLARE_SSE34_AVX_INSTRUCTION)
1152f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  SSE4_INSTRUCTION_LIST(DECLARE_SSE34_AVX_INSTRUCTION)
1153f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef DECLARE_SSE34_AVX_INSTRUCTION
1154f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
11556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movd(XMMRegister dst, Register src);
1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void movd(XMMRegister dst, const Operand& src);
11576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movd(Register dst, XMMRegister src);
11586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movq(XMMRegister dst, Register src);
11596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movq(Register dst, XMMRegister src);
1160257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void movq(XMMRegister dst, XMMRegister src);
11616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1162257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Don't use this unless it's important to keep the
1163257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // top half of the destination register unchanged.
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Use movapd when moving double values and movq for integer
1165257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // values in xmm registers.
1166053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  void movsd(XMMRegister dst, XMMRegister src);
1167257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1168257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void movsd(const Operand& dst, XMMRegister src);
11696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movsd(XMMRegister dst, const Operand& src);
1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void movdqa(const Operand& dst, XMMRegister src);
11721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void movdqa(XMMRegister dst, const Operand& src);
11731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movdqu(const Operand& dst, XMMRegister src);
1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movdqu(XMMRegister dst, const Operand& src);
1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1177257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void movapd(XMMRegister dst, XMMRegister src);
1178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void movupd(XMMRegister dst, const Operand& src);
1179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void movupd(const Operand& dst, XMMRegister src);
1180257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void psllq(XMMRegister reg, byte imm8);
1182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void psrlq(XMMRegister reg, byte imm8);
1183f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void psllw(XMMRegister reg, byte imm8);
1184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void pslld(XMMRegister reg, byte imm8);
1185f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void psrlw(XMMRegister reg, byte imm8);
1186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void psrld(XMMRegister reg, byte imm8);
1187f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void psraw(XMMRegister reg, byte imm8);
1188f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void psrad(XMMRegister reg, byte imm8);
11898defd9ff6930b4e24729971a61cf7469daf119beSteve Block
1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvttsd2si(Register dst, const Operand& src);
11911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void cvttsd2si(Register dst, XMMRegister src);
1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void cvttss2siq(Register dst, XMMRegister src);
1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void cvttss2siq(Register dst, const Operand& src);
119425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  void cvttsd2siq(Register dst, XMMRegister src);
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvttsd2siq(Register dst, const Operand& src);
1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvtlsi2sd(XMMRegister dst, const Operand& src);
1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvtlsi2sd(XMMRegister dst, Register src);
1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void cvtqsi2ss(XMMRegister dst, const Operand& src);
1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void cvtqsi2ss(XMMRegister dst, Register src);
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvtqsi2sd(XMMRegister dst, const Operand& src);
1204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvtqsi2sd(XMMRegister dst, Register src);
1205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12068defd9ff6930b4e24729971a61cf7469daf119beSteve Block
12076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void cvtss2sd(XMMRegister dst, XMMRegister src);
12088defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void cvtss2sd(XMMRegister dst, const Operand& src);
12098defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void cvtsd2ss(XMMRegister dst, XMMRegister src);
1210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void cvtsd2ss(XMMRegister dst, const Operand& src);
12118defd9ff6930b4e24729971a61cf7469daf119beSteve Block
12128defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void cvtsd2si(Register dst, XMMRegister src);
12138defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void cvtsd2siq(Register dst, XMMRegister src);
12146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void addsd(XMMRegister dst, XMMRegister src);
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void addsd(XMMRegister dst, const Operand& src);
1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subsd(XMMRegister dst, XMMRegister src);
1218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void subsd(XMMRegister dst, const Operand& src);
1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void mulsd(XMMRegister dst, XMMRegister src);
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mulsd(XMMRegister dst, const Operand& src);
1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void divsd(XMMRegister dst, XMMRegister src);
1222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void divsd(XMMRegister dst, const Operand& src);
1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void maxsd(XMMRegister dst, XMMRegister src);
1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void maxsd(XMMRegister dst, const Operand& src);
1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void minsd(XMMRegister dst, XMMRegister src);
1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void minsd(XMMRegister dst, const Operand& src);
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1229e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void andpd(XMMRegister dst, XMMRegister src);
1230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void andpd(XMMRegister dst, const Operand& src);
1231e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void orpd(XMMRegister dst, XMMRegister src);
1232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void orpd(XMMRegister dst, const Operand& src);
1233402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void xorpd(XMMRegister dst, XMMRegister src);
1234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void xorpd(XMMRegister dst, const Operand& src);
12356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void sqrtsd(XMMRegister dst, XMMRegister src);
1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sqrtsd(XMMRegister dst, const Operand& src);
1237402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1238402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void ucomisd(XMMRegister dst, XMMRegister src);
12398defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void ucomisd(XMMRegister dst, const Operand& src);
1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cmpltsd(XMMRegister dst, XMMRegister src);
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movmskpd(Register dst, XMMRegister src);
1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void punpckldq(XMMRegister dst, XMMRegister src);
124513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void punpckldq(XMMRegister dst, const Operand& src);
1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void punpckhdq(XMMRegister dst, XMMRegister src);
1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // SSE 4.1 instruction
124913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void insertps(XMMRegister dst, XMMRegister src, byte imm8);
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void extractps(Register dst, XMMRegister src, byte imm8);
1251f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void pextrb(Register dst, XMMRegister src, int8_t imm8);
1252f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void pextrb(const Operand& dst, XMMRegister src, int8_t imm8);
1253f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void pextrw(Register dst, XMMRegister src, int8_t imm8);
1254f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void pextrw(const Operand& dst, XMMRegister src, int8_t imm8);
1255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pextrd(Register dst, XMMRegister src, int8_t imm8);
1256f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void pextrd(const Operand& dst, XMMRegister src, int8_t imm8);
1257f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void pinsrb(XMMRegister dst, Register src, int8_t imm8);
1258f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void pinsrb(XMMRegister dst, const Operand& src, int8_t imm8);
1259f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void pinsrw(XMMRegister dst, Register src, int8_t imm8);
1260f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void pinsrw(XMMRegister dst, const Operand& src, int8_t imm8);
1261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pinsrd(XMMRegister dst, Register src, int8_t imm8);
1262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pinsrd(XMMRegister dst, const Operand& src, int8_t imm8);
1263257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void roundss(XMMRegister dst, XMMRegister src, RoundingMode mode);
1265257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode);
1266257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
126713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void cmpps(XMMRegister dst, XMMRegister src, int8_t cmp);
1268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void cmpps(XMMRegister dst, const Operand& src, int8_t cmp);
1269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void cmppd(XMMRegister dst, XMMRegister src, int8_t cmp);
1270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void cmppd(XMMRegister dst, const Operand& src, int8_t cmp);
1271f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define SSE_CMP_P(instr, imm8)                                                \
1273f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void instr##ps(XMMRegister dst, XMMRegister src) { cmpps(dst, src, imm8); } \
1274f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void instr##ps(XMMRegister dst, const Operand& src) {                       \
1275f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    cmpps(dst, src, imm8);                                                    \
1276f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }                                                                           \
1277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void instr##pd(XMMRegister dst, XMMRegister src) { cmppd(dst, src, imm8); } \
1278f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void instr##pd(XMMRegister dst, const Operand& src) { cmppd(dst, src, imm8); }
1279f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1280f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SSE_CMP_P(cmpeq, 0x0);
1281f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SSE_CMP_P(cmplt, 0x1);
1282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SSE_CMP_P(cmple, 0x2);
1283f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SSE_CMP_P(cmpneq, 0x4);
1284f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SSE_CMP_P(cmpnlt, 0x5);
1285f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SSE_CMP_P(cmpnle, 0x6);
1286f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1287f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#undef SSE_CMP_P
128813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
128913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void minps(XMMRegister dst, XMMRegister src);
129013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void minps(XMMRegister dst, const Operand& src);
129113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void maxps(XMMRegister dst, XMMRegister src);
129213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void maxps(XMMRegister dst, const Operand& src);
129313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void rcpps(XMMRegister dst, XMMRegister src);
129413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void rcpps(XMMRegister dst, const Operand& src);
129513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void rsqrtps(XMMRegister dst, XMMRegister src);
129613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void rsqrtps(XMMRegister dst, const Operand& src);
129713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void sqrtps(XMMRegister dst, XMMRegister src);
129813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void sqrtps(XMMRegister dst, const Operand& src);
129913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void movups(XMMRegister dst, XMMRegister src);
130013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void movups(XMMRegister dst, const Operand& src);
130113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void movups(const Operand& dst, XMMRegister src);
130213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void psrldq(XMMRegister dst, uint8_t shift);
130313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle);
1304f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void pshufd(XMMRegister dst, const Operand& src, uint8_t shuffle);
130513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void cvtdq2ps(XMMRegister dst, XMMRegister src);
130613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void cvtdq2ps(XMMRegister dst, const Operand& src);
130713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // AVX instruction
1309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x99, dst, src1, src2);
1311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xa9, dst, src1, src2);
1314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xb9, dst, src1, src2);
1317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x99, dst, src1, src2);
1320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xa9, dst, src1, src2);
1323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xb9, dst, src1, src2);
1326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x9b, dst, src1, src2);
1329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xab, dst, src1, src2);
1332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xbb, dst, src1, src2);
1335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x9b, dst, src1, src2);
1338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xab, dst, src1, src2);
1341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xbb, dst, src1, src2);
1344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x9d, dst, src1, src2);
1347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xad, dst, src1, src2);
1350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xbd, dst, src1, src2);
1353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x9d, dst, src1, src2);
1356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xad, dst, src1, src2);
1359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xbd, dst, src1, src2);
1362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x9f, dst, src1, src2);
1365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xaf, dst, src1, src2);
1368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xbf, dst, src1, src2);
1371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x9f, dst, src1, src2);
1374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xaf, dst, src1, src2);
1377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xbf, dst, src1, src2);
1380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmasd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmasd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x99, dst, src1, src2);
1386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xa9, dst, src1, src2);
1389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xb9, dst, src1, src2);
1392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x99, dst, src1, src2);
1395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xa9, dst, src1, src2);
1398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xb9, dst, src1, src2);
1401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x9b, dst, src1, src2);
1404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xab, dst, src1, src2);
1407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xbb, dst, src1, src2);
1410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x9b, dst, src1, src2);
1413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xab, dst, src1, src2);
1416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xbb, dst, src1, src2);
1419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x9d, dst, src1, src2);
1422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xad, dst, src1, src2);
1425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xbd, dst, src1, src2);
1428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x9d, dst, src1, src2);
1431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xad, dst, src1, src2);
1434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xbd, dst, src1, src2);
1437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x9f, dst, src1, src2);
1440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xaf, dst, src1, src2);
1443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xbf, dst, src1, src2);
1446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x9f, dst, src1, src2);
1449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xaf, dst, src1, src2);
1452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xbf, dst, src1, src2);
1455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmass(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmass(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovd(XMMRegister dst, Register src);
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovd(XMMRegister dst, const Operand& src);
1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovd(Register dst, XMMRegister src);
1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovq(XMMRegister dst, Register src);
1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovq(XMMRegister dst, const Operand& src);
1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovq(Register dst, XMMRegister src);
1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x10, dst, src1, src2);
1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovsd(XMMRegister dst, const Operand& src) {
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x10, dst, xmm0, src);
1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovsd(const Operand& dst, XMMRegister src) {
1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x11, src, xmm0, dst);
1474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_SP_3(instr, opcode) \
1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_S_3(instr, opcode)        \
1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_P_3(instr, opcode)
1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_S_3(instr, opcode)  \
1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_3(instr##ss, opcode, vss) \
1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_3(instr##sd, opcode, vsd)
1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_P_3(instr, opcode)  \
1485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_3(instr##ps, opcode, vps) \
1486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_3(instr##pd, opcode, vpd)
1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_3(instr, opcode, impl)                                     \
1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) {    \
1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    impl(opcode, dst, src1, src2);                                     \
1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }                                                                    \
1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void instr(XMMRegister dst, XMMRegister src1, const Operand& src2) { \
1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    impl(opcode, dst, src1, src2);                                     \
1494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vsqrt, 0x51);
1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vadd, 0x58);
1498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vsub, 0x5c);
1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vmul, 0x59);
1500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vdiv, 0x5e);
1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vmin, 0x5d);
1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vmax, 0x5f);
1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_P_3(vand, 0x54);
1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_P_3(vor, 0x56);
1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_P_3(vxor, 0x57);
1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_3(vcvtsd2ss, 0x5a, vsd);
1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_3
1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_S_3
1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_P_3
1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_SP_3
1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vpsrlq(XMMRegister dst, XMMRegister src, byte imm8) {
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister iop = {2};
1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vpd(0x73, iop, dst, src);
1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    emit(imm8);
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vpsllq(XMMRegister dst, XMMRegister src, byte imm8) {
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister iop = {6};
1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vpd(0x73, iop, dst, src);
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    emit(imm8);
1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtss2sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1524f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x5a, dst, src1, src2, kF3, k0F, kWIG);
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtss2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1527f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x5a, dst, src1, src2, kF3, k0F, kWIG);
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, Register src2) {
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister isrc2 = {src2.code()};
1531f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2a, dst, src1, isrc2, kF2, k0F, kW0);
1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1534f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2a, dst, src1, src2, kF2, k0F, kW0);
1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1536109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, Register src2) {
1537109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    XMMRegister isrc2 = {src2.code()};
1538f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2a, dst, src1, isrc2, kF3, k0F, kW0);
1539109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1540109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1541f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2a, dst, src1, src2, kF3, k0F, kW0);
1542109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Register src2) {
1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister isrc2 = {src2.code()};
1545f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2a, dst, src1, isrc2, kF3, k0F, kW1);
1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1548f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2a, dst, src1, src2, kF3, k0F, kW1);
1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, Register src2) {
1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister isrc2 = {src2.code()};
1552f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2a, dst, src1, isrc2, kF2, k0F, kW1);
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1555f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2a, dst, src1, src2, kF2, k0F, kW1);
1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1557109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void vcvttss2si(Register dst, XMMRegister src) {
1558109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    XMMRegister idst = {dst.code()};
1559f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW0);
1560109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void vcvttss2si(Register dst, const Operand& src) {
1562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    XMMRegister idst = {dst.code()};
1563f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW0);
1564109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvttsd2si(Register dst, XMMRegister src) {
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1567f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW0);
1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvttsd2si(Register dst, const Operand& src) {
1570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1571f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW0);
1572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvttss2siq(Register dst, XMMRegister src) {
1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1575f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW1);
1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvttss2siq(Register dst, const Operand& src) {
1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1579f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW1);
1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvttsd2siq(Register dst, XMMRegister src) {
1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1583f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW1);
1584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvttsd2siq(Register dst, const Operand& src) {
1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1587f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW1);
1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtsd2si(Register dst, XMMRegister src) {
1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1591f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2d, idst, xmm0, src, kF2, k0F, kW0);
1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vucomisd(XMMRegister dst, XMMRegister src) {
1594f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2e, dst, xmm0, src, k66, k0F, kWIG);
1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vucomisd(XMMRegister dst, const Operand& src) {
1597f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x2e, dst, xmm0, src, k66, k0F, kWIG);
1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vroundss(XMMRegister dst, XMMRegister src1, XMMRegister src2,
1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                RoundingMode mode) {
1601f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x0a, dst, src1, src2, k66, k0F3A, kWIG);
1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    emit(static_cast<byte>(mode) | 0x8);  // Mask precision exception.
1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vroundsd(XMMRegister dst, XMMRegister src1, XMMRegister src2,
1605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                RoundingMode mode) {
1606f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x0b, dst, src1, src2, k66, k0F3A, kWIG);
1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    emit(static_cast<byte>(mode) | 0x8);  // Mask precision exception.
1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vsd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1611f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(op, dst, src1, src2, kF2, k0F, kWIG);
1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2) {
1614f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(op, dst, src1, src2, kF2, k0F, kWIG);
1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vss(0x10, dst, src1, src2);
1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovss(XMMRegister dst, const Operand& src) {
1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vss(0x10, dst, xmm0, src);
1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovss(const Operand& dst, XMMRegister src) {
1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vss(0x11, src, xmm0, dst);
1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vucomiss(XMMRegister dst, XMMRegister src);
1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vucomiss(XMMRegister dst, const Operand& src);
1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vss(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vss(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovaps(XMMRegister dst, XMMRegister src) { vps(0x28, dst, xmm0, src); }
1632f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void vmovups(XMMRegister dst, XMMRegister src) { vps(0x10, dst, xmm0, src); }
1633f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void vmovups(XMMRegister dst, const Operand& src) {
1634f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vps(0x10, dst, xmm0, src);
1635f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1636f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void vmovups(const Operand& dst, XMMRegister src) {
1637f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vps(0x11, src, xmm0, dst);
1638f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovapd(XMMRegister dst, XMMRegister src) { vpd(0x28, dst, xmm0, src); }
1640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void vmovupd(XMMRegister dst, const Operand& src) {
1641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vpd(0x10, dst, xmm0, src);
1642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void vmovupd(const Operand& dst, XMMRegister src) {
1644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vpd(0x11, src, xmm0, dst);
1645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void vmovmskps(Register dst, XMMRegister src) {
1647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    XMMRegister idst = {dst.code()};
1648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vps(0x50, idst, xmm0, src);
1649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovmskpd(Register dst, XMMRegister src) {
1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vpd(0x50, idst, xmm0, src);
1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void vcmpps(XMMRegister dst, XMMRegister src1, XMMRegister src2, int8_t cmp) {
1655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vps(0xC2, dst, src1, src2);
1656f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    emit(cmp);
1657f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1658f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void vcmpps(XMMRegister dst, XMMRegister src1, const Operand& src2,
1659f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              int8_t cmp) {
1660f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vps(0xC2, dst, src1, src2);
1661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    emit(cmp);
1662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1663f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void vcmppd(XMMRegister dst, XMMRegister src1, XMMRegister src2, int8_t cmp) {
1664f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vpd(0xC2, dst, src1, src2);
1665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    emit(cmp);
1666f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void vcmppd(XMMRegister dst, XMMRegister src1, const Operand& src2,
1668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              int8_t cmp) {
1669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vpd(0xC2, dst, src1, src2);
1670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    emit(cmp);
1671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define AVX_CMP_P(instr, imm8)                                             \
1674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void instr##ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) {    \
1675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vcmpps(dst, src1, src2, imm8);                                         \
1676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }                                                                        \
1677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void instr##ps(XMMRegister dst, XMMRegister src1, const Operand& src2) { \
1678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vcmpps(dst, src1, src2, imm8);                                         \
1679f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }                                                                        \
1680f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void instr##pd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {    \
1681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vcmppd(dst, src1, src2, imm8);                                         \
1682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }                                                                        \
1683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void instr##pd(XMMRegister dst, XMMRegister src1, const Operand& src2) { \
1684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vcmppd(dst, src1, src2, imm8);                                         \
1685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1686f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1687f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AVX_CMP_P(vcmpeq, 0x0);
1688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AVX_CMP_P(vcmplt, 0x1);
1689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AVX_CMP_P(vcmple, 0x2);
1690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AVX_CMP_P(vcmpneq, 0x4);
1691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AVX_CMP_P(vcmpnlt, 0x5);
1692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AVX_CMP_P(vcmpnle, 0x6);
1693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#undef AVX_CMP_P
1695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1696f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vlddqu(XMMRegister dst, const Operand& src) {
1697f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0xF0, dst, xmm0, src, kF2, k0F, kWIG);
1698f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1699f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpsllw(XMMRegister dst, XMMRegister src, int8_t imm8) {
1700f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    XMMRegister iop = {6};
1701f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x71, iop, dst, src, k66, k0F, kWIG);
1702f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1703f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1704f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpsrlw(XMMRegister dst, XMMRegister src, int8_t imm8) {
1705f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    XMMRegister iop = {2};
1706f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x71, iop, dst, src, k66, k0F, kWIG);
1707f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1708f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1709f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpsraw(XMMRegister dst, XMMRegister src, int8_t imm8) {
1710f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    XMMRegister iop = {4};
1711f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x71, iop, dst, src, k66, k0F, kWIG);
1712f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1713f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1714f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpslld(XMMRegister dst, XMMRegister src, int8_t imm8) {
1715f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    XMMRegister iop = {6};
1716f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x72, iop, dst, src, k66, k0F, kWIG);
1717f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1718f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1719f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpsrld(XMMRegister dst, XMMRegister src, int8_t imm8) {
1720f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    XMMRegister iop = {2};
1721f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x72, iop, dst, src, k66, k0F, kWIG);
1722f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1723f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1724f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpsrad(XMMRegister dst, XMMRegister src, int8_t imm8) {
1725f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    XMMRegister iop = {4};
1726f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x72, iop, dst, src, k66, k0F, kWIG);
1727f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1728f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1729f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpextrb(Register dst, XMMRegister src, int8_t imm8) {
1730f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    XMMRegister idst = {dst.code()};
1731f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x14, src, xmm0, idst, k66, k0F3A, kW0);
1732f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1733f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1734f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpextrb(const Operand& dst, XMMRegister src, int8_t imm8) {
1735f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x14, src, xmm0, dst, k66, k0F3A, kW0);
1736f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1737f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1738f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpextrw(Register dst, XMMRegister src, int8_t imm8) {
1739f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    XMMRegister idst = {dst.code()};
1740f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0xc5, idst, xmm0, src, k66, k0F, kW0);
1741f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1742f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1743f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpextrw(const Operand& dst, XMMRegister src, int8_t imm8) {
1744f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x15, src, xmm0, dst, k66, k0F3A, kW0);
1745f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1746f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1747f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpextrd(Register dst, XMMRegister src, int8_t imm8) {
1748f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    XMMRegister idst = {dst.code()};
1749f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x16, src, xmm0, idst, k66, k0F3A, kW0);
1750f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1751f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1752f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpextrd(const Operand& dst, XMMRegister src, int8_t imm8) {
1753f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x16, src, xmm0, dst, k66, k0F3A, kW0);
1754f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1755f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1756f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpinsrb(XMMRegister dst, XMMRegister src1, Register src2, int8_t imm8) {
1757f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    XMMRegister isrc = {src2.code()};
1758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x20, dst, src1, isrc, k66, k0F3A, kW0);
1759f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1760f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1761f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpinsrb(XMMRegister dst, XMMRegister src1, const Operand& src2,
1762f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch               int8_t imm8) {
1763f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x20, dst, src1, src2, k66, k0F3A, kW0);
1764f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1765f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1766f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpinsrw(XMMRegister dst, XMMRegister src1, Register src2, int8_t imm8) {
1767f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    XMMRegister isrc = {src2.code()};
1768f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0xc4, dst, src1, isrc, k66, k0F, kW0);
1769f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1770f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1771f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpinsrw(XMMRegister dst, XMMRegister src1, const Operand& src2,
1772f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch               int8_t imm8) {
1773f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0xc4, dst, src1, src2, k66, k0F, kW0);
1774f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1775f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1776f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpinsrd(XMMRegister dst, XMMRegister src1, Register src2, int8_t imm8) {
1777f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    XMMRegister isrc = {src2.code()};
1778f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x22, dst, src1, isrc, k66, k0F3A, kW0);
1779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1780f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1781f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpinsrd(XMMRegister dst, XMMRegister src1, const Operand& src2,
1782f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch               int8_t imm8) {
1783f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x22, dst, src1, src2, k66, k0F3A, kW0);
1784f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1785f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1786f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void vpshufd(XMMRegister dst, XMMRegister src, int8_t imm8) {
1787f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vinstr(0x70, dst, xmm0, src, k66, k0F, kWIG);
1788f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    emit(imm8);
1789f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1790f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vps(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vps(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vpd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vpd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // BMI instruction
1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void andnq(Register dst, Register src1, Register src2) {
1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf2, dst, src1, src2);
1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void andnq(Register dst, Register src1, const Operand& src2) {
1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf2, dst, src1, src2);
1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void andnl(Register dst, Register src1, Register src2) {
1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf2, dst, src1, src2);
1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void andnl(Register dst, Register src1, const Operand& src2) {
1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf2, dst, src1, src2);
1808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bextrq(Register dst, Register src1, Register src2) {
1810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf7, dst, src2, src1);
1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bextrq(Register dst, const Operand& src1, Register src2) {
1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf7, dst, src2, src1);
1814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bextrl(Register dst, Register src1, Register src2) {
1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf7, dst, src2, src1);
1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bextrl(Register dst, const Operand& src1, Register src2) {
1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf7, dst, src2, src1);
1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsiq(Register dst, Register src) {
1822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {3};
1823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf3, ireg, dst, src);
1824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsiq(Register dst, const Operand& src) {
1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {3};
1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf3, ireg, dst, src);
1828958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsil(Register dst, Register src) {
1830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {3};
1831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf3, ireg, dst, src);
1832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsil(Register dst, const Operand& src) {
1834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {3};
1835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf3, ireg, dst, src);
1836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsmskq(Register dst, Register src) {
1838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {2};
1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf3, ireg, dst, src);
1840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsmskq(Register dst, const Operand& src) {
1842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {2};
1843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf3, ireg, dst, src);
1844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsmskl(Register dst, Register src) {
1846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {2};
1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf3, ireg, dst, src);
1848958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsmskl(Register dst, const Operand& src) {
1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {2};
1851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf3, ireg, dst, src);
1852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsrq(Register dst, Register src) {
1854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {1};
1855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf3, ireg, dst, src);
1856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsrq(Register dst, const Operand& src) {
1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {1};
1859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf3, ireg, dst, src);
1860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsrl(Register dst, Register src) {
1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {1};
1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf3, ireg, dst, src);
1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsrl(Register dst, const Operand& src) {
1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {1};
1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf3, ireg, dst, src);
1868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void tzcntq(Register dst, Register src);
1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void tzcntq(Register dst, const Operand& src);
1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void tzcntl(Register dst, Register src);
1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void tzcntl(Register dst, const Operand& src);
1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void lzcntq(Register dst, Register src);
1875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void lzcntq(Register dst, const Operand& src);
1876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void lzcntl(Register dst, Register src);
1877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void lzcntl(Register dst, const Operand& src);
1878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void popcntq(Register dst, Register src);
1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void popcntq(Register dst, const Operand& src);
1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void popcntl(Register dst, Register src);
1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void popcntl(Register dst, const Operand& src);
1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bzhiq(Register dst, Register src1, Register src2) {
1885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kNone, 0xf5, dst, src2, src1);
1886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bzhiq(Register dst, const Operand& src1, Register src2) {
1888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kNone, 0xf5, dst, src2, src1);
1889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bzhil(Register dst, Register src1, Register src2) {
1891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kNone, 0xf5, dst, src2, src1);
1892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bzhil(Register dst, const Operand& src1, Register src2) {
1894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kNone, 0xf5, dst, src2, src1);
1895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void mulxq(Register dst1, Register dst2, Register src) {
1897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF2, 0xf6, dst1, dst2, src);
1898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void mulxq(Register dst1, Register dst2, const Operand& src) {
1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF2, 0xf6, dst1, dst2, src);
1901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void mulxl(Register dst1, Register dst2, Register src) {
1903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF2, 0xf6, dst1, dst2, src);
1904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void mulxl(Register dst1, Register dst2, const Operand& src) {
1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF2, 0xf6, dst1, dst2, src);
1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pdepq(Register dst, Register src1, Register src2) {
1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF2, 0xf5, dst, src1, src2);
1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pdepq(Register dst, Register src1, const Operand& src2) {
1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF2, 0xf5, dst, src1, src2);
1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pdepl(Register dst, Register src1, Register src2) {
1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF2, 0xf5, dst, src1, src2);
1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pdepl(Register dst, Register src1, const Operand& src2) {
1918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF2, 0xf5, dst, src1, src2);
1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pextq(Register dst, Register src1, Register src2) {
1921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF3, 0xf5, dst, src1, src2);
1922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pextq(Register dst, Register src1, const Operand& src2) {
1924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF3, 0xf5, dst, src1, src2);
1925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pextl(Register dst, Register src1, Register src2) {
1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF3, 0xf5, dst, src1, src2);
1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pextl(Register dst, Register src1, const Operand& src2) {
1930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF3, 0xf5, dst, src1, src2);
1931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void sarxq(Register dst, Register src1, Register src2) {
1933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF3, 0xf7, dst, src2, src1);
1934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void sarxq(Register dst, const Operand& src1, Register src2) {
1936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF3, 0xf7, dst, src2, src1);
1937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void sarxl(Register dst, Register src1, Register src2) {
1939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF3, 0xf7, dst, src2, src1);
1940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void sarxl(Register dst, const Operand& src1, Register src2) {
1942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF3, 0xf7, dst, src2, src1);
1943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shlxq(Register dst, Register src1, Register src2) {
1945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(k66, 0xf7, dst, src2, src1);
1946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shlxq(Register dst, const Operand& src1, Register src2) {
1948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(k66, 0xf7, dst, src2, src1);
1949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shlxl(Register dst, Register src1, Register src2) {
1951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(k66, 0xf7, dst, src2, src1);
1952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shlxl(Register dst, const Operand& src1, Register src2) {
1954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(k66, 0xf7, dst, src2, src1);
1955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shrxq(Register dst, Register src1, Register src2) {
1957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF2, 0xf7, dst, src2, src1);
1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shrxq(Register dst, const Operand& src1, Register src2) {
1960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF2, 0xf7, dst, src2, src1);
1961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shrxl(Register dst, Register src1, Register src2) {
1963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF2, 0xf7, dst, src2, src1);
1964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shrxl(Register dst, const Operand& src1, Register src2) {
1966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF2, 0xf7, dst, src2, src1);
1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void rorxq(Register dst, Register src, byte imm8);
1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void rorxq(Register dst, const Operand& src, byte imm8);
1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void rorxl(Register dst, Register src, byte imm8);
1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void rorxl(Register dst, const Operand& src, byte imm8);
1972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check the code size generated from label to here.
19743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int SizeOfCodeGeneratedSince(Label* label) {
19753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return pc_offset() - label->pos();
19763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
1977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
19787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Mark address of a debug break slot.
1979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void RecordDebugBreakSlot(RelocInfo::Mode mode);
19807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Record a comment relocation entry that can be used by a disassembler.
1982b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Use --code-comments to enable.
1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void RecordComment(const char* msg);
1984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Record a deoptimization reason that can be used by a log or cpu profiler.
1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Use --trace-deopt to enable.
1987c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
1988c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         int id);
1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          ConstantPoolEntry::Access access,
1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          ConstantPoolEntry::Type type) {
1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // No embedded constant pool support.
1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNREACHABLE();
1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
199762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void RecordProtectedInstructionLanding(int pc_offset);
199862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1999b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Writes a single word of data in the code stream.
2000b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Used for inline tables, e.g., jump-tables.
2001b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void db(uint8_t data);
2002b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void dd(uint32_t data);
2003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void dq(uint64_t data);
2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void dp(uintptr_t data) { dq(data); }
2005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void dq(Label* label);
2006b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if there is less than kGap bytes available in the buffer.
2008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If this is the case, we need to grow the buffer before emitting
2009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // an instruction or relocation information.
2010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool buffer_overflow() const {
2011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return pc_ >= reloc_info_writer.pos() - kGap;
2012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the number of bytes available in the buffer.
2015d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  inline int available_space() const {
2016d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    return static_cast<int>(reloc_info_writer.pos() - pc_);
2017d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
2018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
20193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static bool IsNop(Address addr);
20207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Avoid overflows for displacements etc.
2022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaximalBufferSize = 512*MB;
2023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
20243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  byte byte_at(int pos)  { return buffer_[pos]; }
20253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
20263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2027f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Address pc() const { return pc_; }
2028f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
202944f0eee88ff00398ff7f715fab053374d808c90dSteve Block protected:
2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Call near indirect
2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void call(const Operand& operand);
2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
2034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* addr_at(int pos)  { return buffer_ + pos; }
2035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uint32_t long_at(int pos)  {
2036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return *reinterpret_cast<uint32_t*>(addr_at(pos));
2037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void long_at_put(int pos, uint32_t x)  {
2039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
2040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // code emission
2043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GrowBuffer();
2044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit(byte x) { *pc_++ = x; }
2046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emitl(uint32_t x);
2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void emitp(void* x, RelocInfo::Mode rmode);
2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void emitq(uint64_t x);
2049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emitw(uint16_t x);
2050257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void emit_code_target(Handle<Code> target,
2051257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               RelocInfo::Mode rmode,
2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               TypeFeedbackId ast_id = TypeFeedbackId::None());
2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode);
205462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  inline void emit(Immediate x);
2055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a REX prefix that encodes a 64-bit operand size and
2057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the top bit of both register codes.
2058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
2059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is set.
2060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(XMMRegister reg, Register rm_reg);
20616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void emit_rex_64(Register reg, XMMRegister rm_reg);
20626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void emit_rex_64(Register reg, Register rm_reg);
2063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a REX prefix that encodes a 64-bit operand size and
2065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the top bit of the destination, index, and base register codes.
2066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of reg is used for REX.R, the high bit of op's base
2067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register is used for REX.B, and the high bit of op's index register
2068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is used for REX.X.  REX.W is set.
2069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(Register reg, const Operand& op);
2070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(XMMRegister reg, const Operand& op);
2071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a REX prefix that encodes a 64-bit operand size and
2073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the top bit of the register code.
2074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of register is used for REX.B.
2075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is set and REX.R and REX.X are clear.
2076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(Register rm_reg);
2077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a REX prefix that encodes a 64-bit operand size and
2079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the top bit of the index and base register codes.
2080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of op's base register is used for REX.B, and the high
2081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // bit of op's index register is used for REX.X.
2082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is set and REX.R clear.
2083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(const Operand& op);
2084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size.
2086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_rex_64() { emit(0x48); }
2087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
2089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is clear.
2090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_32(Register reg, Register rm_reg);
2091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of reg is used for REX.R, the high bit of op's base
2093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register is used for REX.B, and the high bit of op's index register
2094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is used for REX.X.  REX.W is cleared.
2095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_32(Register reg, const Operand& op);
2096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of rm_reg goes to REX.B.
2098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W, REX.R and REX.X are clear.
2099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_32(Register rm_reg);
2100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of base goes to REX.B and high bit of index to REX.X.
2102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W and REX.R are clear.
2103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_32(const Operand& op);
2104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
2106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is cleared.  If no REX bits are set, no byte is emitted.
2107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(Register reg, Register rm_reg);
2108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of reg is used for REX.R, the high bit of op's base
2110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register is used for REX.B, and the high bit of op's index register
2111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is used for REX.X.  REX.W is cleared.  If no REX bits are set, nothing
2112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is emitted.
2113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(Register reg, const Operand& op);
2114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // As for emit_optional_rex_32(Register, Register), except that
2116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the registers are XMM registers.
2117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base);
2118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // As for emit_optional_rex_32(Register, Register), except that
21206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // one of the registers is an XMM registers.
2121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(XMMRegister reg, Register base);
2122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
21236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // As for emit_optional_rex_32(Register, Register), except that
21246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // one of the registers is an XMM registers.
21256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void emit_optional_rex_32(Register reg, XMMRegister base);
21266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // As for emit_optional_rex_32(Register, const Operand&), except that
2128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the register is an XMM register.
2129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(XMMRegister reg, const Operand& op);
2130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Optionally do as emit_rex_32(Register) if the register number has
2132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the high bit set.
2133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(Register rm_reg);
2134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_optional_rex_32(XMMRegister rm_reg);
2135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Optionally do as emit_rex_32(const Operand&) if the operand register
2137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // numbers have a high bit set.
2138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(const Operand& op);
2139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_rex(int size) {
2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (size == kInt64Size) {
2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      emit_rex_64();
2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(size == kInt32Size);
2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1>
2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_rex(P1 p1, int size) {
2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (size == kInt64Size) {
2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      emit_rex_64(p1);
2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(size == kInt32Size);
2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      emit_optional_rex_32(p1);
2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2>
2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_rex(P1 p1, P2 p2, int size) {
2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (size == kInt64Size) {
2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      emit_rex_64(p1, p2);
2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(size == kInt32Size);
2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      emit_optional_rex_32(p1, p2);
2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Emit vex prefix
2169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void emit_vex2_byte0() { emit(0xc5); }
2170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l,
2171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              SIMDPrefix pp);
2172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void emit_vex3_byte0() { emit(0xc4); }
2173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_vex3_byte1(XMMRegister reg, XMMRegister rm, LeadingOpcode m);
2174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_vex3_byte1(XMMRegister reg, const Operand& rm,
2175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              LeadingOpcode m);
2176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l,
2177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              SIMDPrefix pp);
2178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, XMMRegister rm,
2179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              VectorLength l, SIMDPrefix pp, LeadingOpcode m,
2180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              VexW w);
2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline void emit_vex_prefix(Register reg, Register v, Register rm,
2182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              VectorLength l, SIMDPrefix pp, LeadingOpcode m,
2183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              VexW w);
2184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, const Operand& rm,
2185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              VectorLength l, SIMDPrefix pp, LeadingOpcode m,
2186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              VexW w);
2187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline void emit_vex_prefix(Register reg, Register v, const Operand& rm,
2188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              VectorLength l, SIMDPrefix pp, LeadingOpcode m,
2189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              VexW w);
2190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit the ModR/M byte, and optionally the SIB byte and
2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // 1- or 4-byte offset for a memory operand.  Also encodes
2193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the second operand of the operation, a register or operation
2194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // subcode, into the reg field of the ModR/M byte.
2195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_operand(Register reg, const Operand& adr) {
2196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit_operand(reg.low_bits(), adr);
2197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit the ModR/M byte, and optionally the SIB byte and
2200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // 1- or 4-byte offset for a memory operand.  Also used to encode
2201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a three-bit opcode extension into the ModR/M byte.
2202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_operand(int rm, const Operand& adr);
2203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
2205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_modrm(Register reg, Register rm_reg) {
2206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
2207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit a ModR/M byte with an operation subcode in the reg field and
2210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a register in the rm_reg field.
2211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_modrm(int code, Register rm_reg) {
2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_uint3(code));
2213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit(0xC0 | code << 3 | rm_reg.low_bits());
2214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit the code-object-relative offset of the label's position
2217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_code_relative_offset(Label* label);
2218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The first argument is the reg field, the second argument is the r/m field.
2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sse_operand(XMMRegister dst, XMMRegister src);
2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sse_operand(XMMRegister reg, const Operand& adr);
2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sse_operand(Register reg, const Operand& adr);
2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sse_operand(XMMRegister dst, Register src);
2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sse_operand(Register dst, XMMRegister src);
222513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void emit_sse_operand(XMMRegister dst);
2226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit machine code for one of the operations ADD, ADC, SUB, SBC,
2228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // AND, OR, XOR, or CMP.  The encodings of these operations are all
2229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // similar, differing just in the opcode or in the reg field of the
2230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ModR/M byte.
2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void arithmetic_op_8(byte opcode, Register reg, Register rm_reg);
2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg);
2233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
2234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size);
2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void arithmetic_op(byte opcode,
2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     Register reg,
2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     const Operand& rm_reg,
2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     int size);
2241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Operate on a byte in memory or register.
2242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_8(byte subcode,
2243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Register dst,
2244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Immediate src);
2245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_8(byte subcode,
2246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 const Operand& dst,
2247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Immediate src);
2248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Operate on a word in memory or register.
2249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_16(byte subcode,
2250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Register dst,
2251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Immediate src);
2252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_16(byte subcode,
2253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  const Operand& dst,
2254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Immediate src);
2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void immediate_arithmetic_op(byte subcode,
2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Register dst,
2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Immediate src,
2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               int size);
2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void immediate_arithmetic_op(byte subcode,
2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               const Operand& dst,
2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Immediate src,
2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               int size);
2264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit machine code for a shift operation.
2266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void shift(Operand dst, Immediate shift_amount, int subcode, int size);
2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void shift(Register dst, Immediate shift_amount, int subcode, int size);
2268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shift dst by cl % 64 bits.
2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void shift(Register dst, int subcode, int size);
2270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void shift(Operand dst, int subcode, int size);
2271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_farith(int b1, int b2, int i);
2273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // labels
2275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // void print(Label* L);
2276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void bind_to(Label* L, int pos);
2277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // record reloc info for current pc_
2279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
2280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Arithmetics
2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_add(Register dst, Register src, int size) {
2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x03, dst, src, size);
2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_add(Register dst, Immediate src, int size) {
2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x0, dst, src, size);
2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_add(Register dst, const Operand& src, int size) {
2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x03, dst, src, size);
2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_add(const Operand& dst, Register src, int size) {
2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x1, src, dst, size);
2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_add(const Operand& dst, Immediate src, int size) {
2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x0, dst, src, size);
2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_and(Register dst, Register src, int size) {
2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x23, dst, src, size);
2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_and(Register dst, const Operand& src, int size) {
2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x23, dst, src, size);
2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_and(const Operand& dst, Register src, int size) {
2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x21, src, dst, size);
2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_and(Register dst, Immediate src, int size) {
2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x4, dst, src, size);
2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_and(const Operand& dst, Immediate src, int size) {
2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x4, dst, src, size);
2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_cmp(Register dst, Register src, int size) {
2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x3B, dst, src, size);
2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_cmp(Register dst, const Operand& src, int size) {
2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x3B, dst, src, size);
2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_cmp(const Operand& dst, Register src, int size) {
2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x39, src, dst, size);
2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_cmp(Register dst, Immediate src, int size) {
2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x7, dst, src, size);
2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_cmp(const Operand& dst, Immediate src, int size) {
2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x7, dst, src, size);
2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
234213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Compare {al,ax,eax,rax} with src.  If equal, set ZF and write dst into
234313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // src. Otherwise clear ZF and write src into {al,ax,eax,rax}.  This
234413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // operation is only atomic if prefixed by the lock instruction.
234513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void emit_cmpxchg(const Operand& dst, Register src, int size);
234613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_dec(Register dst, int size);
2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_dec(const Operand& dst, int size);
2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Divide rdx:rax by src.  Quotient in rax, remainder in rdx when size is 64.
2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Divide edx:eax by lower 32 bits of src.  Quotient in eax, remainder in edx
2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // when size is 32.
2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_idiv(Register src, int size);
2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_div(Register src, int size);
2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Signed multiply instructions.
2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32.
2358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_imul(Register src, int size);
2359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void emit_imul(const Operand& src, int size);
2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_imul(Register dst, Register src, int size);
2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_imul(Register dst, const Operand& src, int size);
2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_imul(Register dst, Register src, Immediate imm, int size);
2363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void emit_imul(Register dst, const Operand& src, Immediate imm, int size);
2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_inc(Register dst, int size);
2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_inc(const Operand& dst, int size);
2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_lea(Register dst, const Operand& src, int size);
2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_mov(Register dst, const Operand& src, int size);
2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_mov(Register dst, Register src, int size);
2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_mov(const Operand& dst, Register src, int size);
2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_mov(Register dst, Immediate value, int size);
2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_mov(const Operand& dst, Immediate value, int size);
2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_movzxb(Register dst, const Operand& src, int size);
2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_movzxb(Register dst, Register src, int size);
2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_movzxw(Register dst, const Operand& src, int size);
2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_movzxw(Register dst, Register src, int size);
2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_neg(Register dst, int size);
2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_neg(const Operand& dst, int size);
2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_not(Register dst, int size);
2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_not(const Operand& dst, int size);
2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_or(Register dst, Register src, int size) {
2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x0B, dst, src, size);
2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_or(Register dst, const Operand& src, int size) {
2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x0B, dst, src, size);
2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_or(const Operand& dst, Register src, int size) {
2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x9, src, dst, size);
2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_or(Register dst, Immediate src, int size) {
2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x1, dst, src, size);
2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_or(const Operand& dst, Immediate src, int size) {
2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x1, dst, src, size);
2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_repmovs(int size);
2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sbb(Register dst, Register src, int size) {
2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x1b, dst, src, size);
2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sub(Register dst, Register src, int size) {
2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x2B, dst, src, size);
2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sub(Register dst, Immediate src, int size) {
2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x5, dst, src, size);
2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sub(Register dst, const Operand& src, int size) {
2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x2B, dst, src, size);
2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sub(const Operand& dst, Register src, int size) {
2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x29, src, dst, size);
2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sub(const Operand& dst, Immediate src, int size) {
2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x5, dst, src, size);
2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_test(Register dst, Register src, int size);
2434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_test(Register reg, Immediate mask, int size);
2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_test(const Operand& op, Register reg, int size);
2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_test(const Operand& op, Immediate mask, int size);
2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_test(Register reg, const Operand& op, int size) {
2438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return emit_test(op, reg, size);
2439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xchg(Register dst, Register src, int size);
2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xchg(Register dst, const Operand& src, int size);
2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xor(Register dst, Register src, int size) {
2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (size == kInt64Size && dst.code() == src.code()) {
2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // there is no need to make this a 64 bit operation.
2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arithmetic_op(0x33, dst, src, kInt32Size);
2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arithmetic_op(0x33, dst, src, size);
2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xor(Register dst, const Operand& src, int size) {
2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x33, dst, src, size);
2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xor(Register dst, Immediate src, int size) {
2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x6, dst, src, size);
2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xor(const Operand& dst, Immediate src, int size) {
2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x6, dst, src, size);
2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xor(const Operand& dst, Register src, int size) {
2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x31, src, dst, size);
2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Most BMI instructions are similiar.
2471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi1q(byte op, Register reg, Register vreg, Register rm);
2472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi1q(byte op, Register reg, Register vreg, const Operand& rm);
2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi1l(byte op, Register reg, Register vreg, Register rm);
2474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi1l(byte op, Register reg, Register vreg, const Operand& rm);
2475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm);
2476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg,
2477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             const Operand& rm);
2478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm);
2479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg,
2480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             const Operand& rm);
2481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class CodePatcher;
2483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class EnsureSpace;
2484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class RegExpMacroAssemblerX64;
2485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // code generation
2487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RelocInfoWriter reloc_info_writer;
2488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Internal reference positions, required for (potential) patching in
2490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // GrowBuffer(); contains only those internal references whose labels
2491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // are already bound.
2492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::deque<int> internal_reference_positions_;
2493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
24943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  List< Handle<Code> > code_targets_;
2495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper class that ensures that there is enough space for generating
2499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instructions and relocation information.  The constructor makes
2500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// sure that there is enough space and (in debug mode) the destructor
2501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// checks that we did not generate too much.
2502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EnsureSpace BASE_EMBEDDED {
2503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
2505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
2506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
2507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    space_before_ = assembler_->available_space();
2508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
2509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
2512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ~EnsureSpace() {
2513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int bytes_generated = space_before_ - assembler_->available_space();
2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(bytes_generated < assembler_->kGap);
2515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
2517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
2519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Assembler* assembler_;
2520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
2521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int space_before_;
2522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
2523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
2526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
2527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_X64_ASSEMBLER_X64_H_
2529