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