assembler-x64.h revision bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright (c) 1994-2006 Sun Microsystems Inc.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All Rights Reserved.
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistributions of source code must retain the above copyright notice,
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this list of conditions and the following disclaimer.
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistribution in binary form must reproduce the above copyright
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer in the
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// documentation and/or other materials provided with the distribution.
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Neither the name of Sun Microsystems or the names of contributors may
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be used to endorse or promote products derived from this software without
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// specific prior written permission.
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The original source code covered by the above license above has been
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modified significantly by Google Inc.
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A lightweight X64 Assembler.
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_X64_ASSEMBLER_X64_H_
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_X64_ASSEMBLER_X64_H_
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <deque>
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/assembler.h"
43d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utility functions
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define GENERAL_REGISTERS(V) \
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rax)                     \
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rcx)                     \
52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rdx)                     \
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rbx)                     \
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rsp)                     \
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rbp)                     \
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rsi)                     \
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rdi)                     \
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r8)                      \
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r9)                      \
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r10)                     \
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r11)                     \
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r12)                     \
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r13)                     \
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r14)                     \
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r15)
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_GENERAL_REGISTERS(V) \
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rax)                                 \
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rbx)                                 \
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rdx)                                 \
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rcx)                                 \
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rsi)                                 \
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(rdi)                                 \
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r8)                                  \
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r9)                                  \
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r11)                                 \
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r12)                                 \
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r14)                                 \
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(r15)
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CPU Registers.
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 1) We would prefer to use an enum, but enum values are assignment-
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// compatible with int, which has caused code-generation bugs.
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 2) We would prefer to use a class instead of a struct but we don't like
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the register initialization to depend on the particular initialization
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order (which appears to be different on OS X, Linux, and Windows for the
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// installed versions of C++ we tried). Using a struct permits C-style
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "initialization". Also, the Register objects cannot be const as this
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// forces initialization stubs in MSVC, making us dependent on initialization
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order.
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 3) By not using an enum, we are possibly preventing the compiler from
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// doing certain constant folds, which may significantly reduce the
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// code generated for some assembly instructions (because they boil down
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to a few constants). If this is a problem, we could change the code
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// such that we use an enum in optimized mode, and the struct in debug
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// mode. This way we get the compile-time error checking in debug mode
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and best performance in optimized code.
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct Register {
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum Code {
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R,
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GENERAL_REGISTERS(REGISTER_CODE)
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        kAfterLast,
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kCode_no_reg = -1
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
111b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const int kNumRegisters = Code::kAfterLast;
113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static Register from_code(int code) {
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(code >= 0);
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(code < kNumRegisters);
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register r = {code};
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return r;
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const char* ToString();
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsAllocatable() const;
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is(Register reg) const { return reg_code == reg.reg_code; }
1240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int code() const {
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_valid());
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return reg_code;
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int bit() const {
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(is_valid());
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return 1 << reg_code;
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_byte_register() const { return reg_code <= 3; }
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the high bit of the register code as a 0 or 1.  Used often
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // when constructing the REX prefix byte.
136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int high_bit() const { return reg_code >> 3; }
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the 3 low bits of the register code.  Used when encoding registers
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in modR/M, SIB, and opcode bytes.
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int low_bits() const { return reg_code & 0x7; }
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Unfortunately we can't make this private in a struct when initializing
1423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // by assignment.
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int reg_code;
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochGENERAL_REGISTERS(DECLARE_REGISTER)
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register no_reg = {Register::kCode_no_reg};
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef _WIN64
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Windows calling convention
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_1 = {Register::kCode_rcx};
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_2 = {Register::kCode_rdx};
157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_3 = {Register::kCode_r8};
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_4 = {Register::kCode_r9};
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // AMD64 calling convention
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_1 = {Register::kCode_rdi};
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_2 = {Register::kCode_rsi};
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_3 = {Register::kCode_rdx};
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register arg_reg_4 = {Register::kCode_rcx};
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // _WIN64
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DOUBLE_REGISTERS(V) \
169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm0)                   \
170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm1)                   \
171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm2)                   \
172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm3)                   \
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm4)                   \
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm5)                   \
175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm6)                   \
176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm7)                   \
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm8)                   \
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm9)                   \
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm10)                  \
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm11)                  \
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm12)                  \
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm13)                  \
183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm14)                  \
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm15)
185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
186bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define FLOAT_REGISTERS DOUBLE_REGISTERS
187bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm1)                               \
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm2)                               \
191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm3)                               \
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm4)                               \
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm5)                               \
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm6)                               \
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm7)                               \
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm8)                               \
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm9)                               \
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm10)                              \
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm11)                              \
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm12)                              \
201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm13)                              \
202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm14)                              \
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(xmm15)
204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
205bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochstruct XMMRegister {
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum Code {
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R,
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DOUBLE_REGISTERS(REGISTER_CODE)
209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE
210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        kAfterLast,
211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kCode_no_reg = -1
212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const int kMaxNumRegisters = Code::kAfterLast;
215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
216bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  static XMMRegister from_code(int code) {
217bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    XMMRegister result = {code};
218b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    return result;
219b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
220b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const char* ToString();
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsAllocatable() const;
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
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ASSEMBLER_INSTRUCTION_LIST(V) \
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(add)                              \
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(and)                              \
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(cmp)                              \
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
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shift instructions on operands/registers with kPointerSize, kInt32Size and
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// kInt64Size.
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define SHIFT_INSTRUCTION_LIST(V)       \
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(rol, 0x0)                           \
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ror, 0x1)                           \
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(rcl, 0x2)                           \
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(rcr, 0x3)                           \
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(shl, 0x4)                           \
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(shr, 0x5)                           \
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(sar, 0x7)                           \
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Assembler : public AssemblerBase {
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // We check before assembling an instruction that there is sufficient
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // space to write an instruction and its relocation information.
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The relocation writer's position must be kGap bytes above the end of
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the generated instructions. This leaves enough space for the
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // longest possible x64 instruction, 15 bytes, and the longest possible
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // (There is a 15 byte limit on x64 instruction length that rules out some
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // otherwise valid instructions.)
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This allows for a single, fast space check per instruction.
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kGap = 32;
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Create an assembler. Instructions and relocation information are emitted
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // into a buffer, with the instructions starting from the beginning and the
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // relocation information starting from the end of the buffer. See CodeDesc
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for a detailed comment on the layout (globals.h).
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the provided buffer is NULL, the assembler allocates and grows its own
481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // buffer, and buffer_size determines the initial buffer size. The buffer is
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // owned by the assembler and deallocated upon destruction of the assembler.
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the provided buffer is not NULL, the assembler uses the provided buffer
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for code generation and assumes its size to be buffer_size. If the buffer
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is too small, a fatal error occurs. No deallocation of the buffer is done
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // upon destruction of the assembler.
4888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler(Isolate* isolate, void* buffer, int buffer_size);
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~Assembler() { }
49044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // GetCode emits any pending (non-emitted) code and fills the descriptor
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // desc. GetCode() is idempotent; it returns the same result if no other
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Assembler functions are invoked in between GetCode() calls.
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GetCode(CodeDesc* desc);
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Read/Modify the code target in the relative branch/call instruction at pc.
4973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // On the x64 architecture, we use relative jumps with a 32-bit displacement
4983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // to jump to other Code objects in the Code space in the heap.
4993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Jumps to C functions are done indirectly through a 64-bit register holding
5003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // the absolute address of the target.
5013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // These functions convert between absolute Addresses of Code objects and
5023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // the relative displacements stored in the code.
503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline Address target_address_at(Address pc, Address constant_pool);
504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline void set_target_address_at(
505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Isolate* isolate, Address pc, Address constant_pool, Address target,
506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Address target_address_at(Address pc, Code* code) {
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address constant_pool = code ? code->constant_pool() : NULL;
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return target_address_at(pc, constant_pool);
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline void set_target_address_at(
512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Isolate* isolate, Address pc, Code* code, Address target,
513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED) {
514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Address constant_pool = code ? code->constant_pool() : NULL;
515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_target_address_at(isolate, pc, constant_pool, target,
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          icache_flush_mode);
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Return the code target address at a call site from the return address
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of that call in the instruction stream.
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Address target_address_from_return_address(Address pc);
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
523d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // This sets the branch destination (which is in the instruction on x64).
524d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // This is for calls and branches within generated code.
5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline static void deserialization_set_special_target_at(
526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Isolate* isolate, Address instruction_payload, Code* code,
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Address target) {
528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_target_address_at(isolate, instruction_payload, code, target);
529d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
530d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // This sets the internal reference at the pc.
532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline static void deserialization_set_target_internal_reference_at(
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Isolate* isolate, Address pc, Address target,
534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline RelocInfo::Mode RelocInfoNone() {
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (kPointerSize == kInt64Size) {
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return RelocInfo::NONE64;
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(kPointerSize == kInt32Size);
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return RelocInfo::NONE32;
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
543d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
544d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
5453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline Handle<Object> code_target_object_handle_at(Address pc);
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline Address runtime_entry_at(Address pc);
547d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Number of bytes taken up by the branch target in the code.
5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSpecialTargetSize = 4;  // Use 32-bit displacement.
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Distance between the address of the code target in the call instruction
5503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // and the return address pushed on the stack.
5513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static const int kCallTargetAddressOffset = 4;  // Use 32-bit displacement.
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The length of call(kScratchRegister).
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kCallScratchRegisterInstructionLength = 3;
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The length of call(Immediate32).
5551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kShortCallInstructionLength = 5;
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The length of movq(kScratchRegister, address).
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMoveAddressIntoScratchRegisterInstructionLength =
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      2 + kPointerSize;
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The length of movq(kScratchRegister, address) and call(kScratchRegister).
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kCallSequenceLength =
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kMoveAddressIntoScratchRegisterInstructionLength +
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kCallScratchRegisterInstructionLength;
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The debug break slot must be able to contain an indirect call sequence.
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kDebugBreakSlotLength = kCallSequenceLength;
566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Distance between start of patched debug break slot and the emitted address
567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // to jump to.
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kPatchDebugBreakSlotAddressOffset =
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kMoveAddressIntoScratchRegisterInstructionLength - kPointerSize;
5707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5719fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // One byte opcode for test eax,0xXXXXXXXX.
5729fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  static const byte kTestEaxByte = 0xA9;
5731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // One byte opcode for test al, 0xXX.
5741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kTestAlByte = 0xA8;
5751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // One byte opcode for nop.
5761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kNopByte = 0x90;
5771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // One byte prefix for a short conditional jump.
5791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kJccShortPrefix = 0x70;
5801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
5811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kJcShortOpcode = kJccShortPrefix | carry;
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const byte kJzShortOpcode = kJccShortPrefix | zero;
5841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // VEX prefix encodings.
586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 };
587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128, kLZ = kL128 };
588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 };
589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x3 };
5907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Code generation
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Function names correspond one-to-one to x64 instruction mnemonics.
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Unless specified otherwise, instructions operate on 64-bit operands.
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If we need versions of an assembly instruction that operate on different
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // width arguments, we add a single-letter suffix specifying the width.
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This is done for the following instructions: mov, cmp, inc, dec,
600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // add, sub, and test.
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // There are no versions of these instructions without the suffix.
602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - Instructions on 16-bit (word) operands/registers have a trailing 'w'.
604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - Instructions on 64-bit (quadword) operands/registers use 'q'.
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - Instructions on operands/registers with pointer size use 'p'.
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size);
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARE_INSTRUCTION(instruction)                \
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1>                                    \
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##p(P1 p1) {                          \
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, kPointerSize);               \
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1>                                    \
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##l(P1 p1) {                          \
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, kInt32Size);                 \
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1>                                    \
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##q(P1 p1) {                          \
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, kInt64Size);                 \
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2>                          \
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##p(P1 p1, P2 p2) {                   \
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, p2, kPointerSize);           \
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2>                          \
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##l(P1 p1, P2 p2) {                   \
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, p2, kInt32Size);             \
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2>                          \
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##q(P1 p1, P2 p2) {                   \
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, p2, kInt64Size);             \
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2, class P3>                \
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##p(P1 p1, P2 p2, P3 p3) {            \
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, p2, p3, kPointerSize);       \
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2, class P3>                \
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##l(P1 p1, P2 p2, P3 p3) {            \
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, p2, p3, kInt32Size);         \
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                     \
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        \
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2, class P3>                \
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instruction##q(P1 p1, P2 p2, P3 p3) {            \
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_##instruction(p1, p2, p3, kInt64Size);         \
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION)
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_INSTRUCTION
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Insert the smallest number of nop instructions
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // possible to align the pc offset to a multiple
6601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // of m, where m must be a power of 2.
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Align(int m);
662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Insert the smallest number of zero bytes possible to align the pc offset
663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // to a mulitple of m. m must be a power of 2 (>= 2).
664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DataAlign(int m);
6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Nop(int bytes = 1);
6669dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Aligns code to something that's optimal for a jump target for the platform.
6679dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  void CodeTargetAlign();
668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Stack
670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void pushfq();
671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void popfq();
672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void pushq(Immediate value);
6741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Push a 32 bit integer, and guarantee that it is actually pushed as a
6751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // 32 bit value, the normal push will optimize the 8 bit case.
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void pushq_imm32(int32_t imm32);
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void pushq(Register src);
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void pushq(const Operand& src);
679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void popq(Register dst);
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void popq(const Operand& dst);
682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void enter(Immediate size);
684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void leave();
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Moves
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movb(Register dst, const Operand& src);
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movb(Register dst, Immediate imm);
689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movb(const Operand& dst, Register src);
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movb(const Operand& dst, Immediate imm);
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Move the low 16 bits of a 64-bit register value to a 16-bit
6933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // memory location.
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movw(Register dst, const Operand& src);
6953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void movw(const Operand& dst, Register src);
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movw(const Operand& dst, Immediate imm);
6973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Move the offset of the label location relative to the current
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // position (after the move) to the destination.
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movl(const Operand& dst, Label* src);
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Loads a pointer into a register with a relocation mode.
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movp(Register dst, void* ptr, RelocInfo::Mode rmode);
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Loads a 64-bit immediate into a register.
7063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void movq(Register dst, int64_t value,
7073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            RelocInfo::Mode rmode = RelocInfo::NONE64);
7083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void movq(Register dst, uint64_t value,
7093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            RelocInfo::Mode rmode = RelocInfo::NONE64);
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void movsxbl(Register dst, Register src);
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movsxbl(Register dst, const Operand& 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);
7163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void movsxwq(Register dst, const Operand& src);
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movsxlq(Register dst, Register src);
718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movsxlq(Register dst, const Operand& src);
719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
720d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Repeated moves.
721d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
722d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void repmovsb();
723d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void repmovsw();
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void repmovsp() { emit_repmovs(kPointerSize); }
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void repmovsl() { emit_repmovs(kInt32Size); }
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void repmovsq() { emit_repmovs(kInt64Size); }
727d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
72844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Instruction to load from an immediate 64-bit pointer into RAX.
729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void load_rax(void* ptr, RelocInfo::Mode rmode);
730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void load_rax(ExternalReference ext);
731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Conditional moves.
733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmovq(Condition cc, Register dst, Register src);
734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmovq(Condition cc, Register dst, const Operand& src);
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmovl(Condition cc, Register dst, Register src);
736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmovl(Condition cc, Register dst, const Operand& src);
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(Register dst, Immediate src) {
739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_8(0x7, dst, src);
740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb_al(Immediate src);
743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(Register dst, Register src) {
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op_8(0x3A, dst, src);
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(Register dst, const Operand& src) {
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op_8(0x3A, dst, src);
750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(const Operand& dst, Register src) {
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op_8(0x38, src, dst);
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(const Operand& dst, Immediate src) {
757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_8(0x7, dst, src);
758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(const Operand& dst, Immediate src) {
761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_16(0x7, dst, src);
762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(Register dst, Immediate src) {
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_16(0x7, dst, src);
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(Register dst, const Operand& src) {
769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_16(0x3B, dst, src);
770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(Register dst, Register src) {
773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_16(0x3B, dst, src);
774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(const Operand& dst, Register src) {
777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_16(0x39, src, dst);
778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void testb(Register reg, const Operand& op) { testb(op, reg); }
7813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
7823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void testw(Register reg, const Operand& op) { testw(op, reg); }
7833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
7844515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  void andb(Register dst, Immediate src) {
7854515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke    immediate_arithmetic_op_8(0x4, dst, src);
7864515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  }
7873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
7883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void decb(Register dst);
7893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void decb(const Operand& dst);
790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
791bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void xchgb(Register reg, const Operand& op);
792bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void xchgw(Register reg, const Operand& op);
793bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sign-extends rax into rdx:rax.
795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cqo();
796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sign-extends eax into edx:eax.
797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cdq();
798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
799958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Multiply eax by src, put the result in edx:eax.
800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void mull(Register src);
801958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void mull(const Operand& src);
802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Multiply rax by src, put the result in rdx:rax.
803958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void mulq(Register src);
804958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
805958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode)                       \
806958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##p(Register dst, Immediate imm8) {                         \
807958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    shift(dst, imm8, subcode, kPointerSize);                                  \
808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                                           \
809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##l(Register dst, Immediate imm8) {                         \
811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    shift(dst, imm8, subcode, kInt32Size);                                    \
812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                                           \
813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##q(Register dst, Immediate imm8) {                         \
815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    shift(dst, imm8, subcode, kInt64Size);                                    \
816958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                                           \
817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##p(Operand dst, Immediate imm8) {                          \
819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    shift(dst, imm8, subcode, kPointerSize);                                  \
820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                                           \
821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##l(Operand dst, Immediate imm8) {                          \
823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    shift(dst, imm8, subcode, kInt32Size);                                    \
824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                                           \
825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##q(Operand dst, Immediate imm8) {                          \
827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    shift(dst, imm8, subcode, kInt64Size);                                    \
828958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                                           \
829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##p_cl(Register dst) { shift(dst, subcode, kPointerSize); } \
831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##l_cl(Register dst) { shift(dst, subcode, kInt32Size); }   \
833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##q_cl(Register dst) { shift(dst, subcode, kInt64Size); }   \
835958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##p_cl(Operand dst) { shift(dst, subcode, kPointerSize); }  \
837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##l_cl(Operand dst) { shift(dst, subcode, kInt32Size); }    \
839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                              \
840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void instruction##q_cl(Operand dst) { shift(dst, subcode, kInt64Size); }
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION)
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_SHIFT_INSTRUCTION
843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifts dst:src left by cl bits, affecting only dst.
845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shld(Register dst, Register src);
846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifts src:dst right by cl bits, affecting only dst.
848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shrd(Register dst, Register src);
849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void store_rax(void* dst, RelocInfo::Mode mode);
851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void store_rax(ExternalReference ref);
852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subb(Register dst, Immediate src) {
854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_8(0x5, dst, src);
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void testb(Register dst, Register src);
858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void testb(Register reg, Immediate mask);
859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void testb(const Operand& op, Immediate mask);
860e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void testb(const Operand& op, Register reg);
861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void testw(Register dst, Register src);
8633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void testw(Register reg, Immediate mask);
8643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void testw(const Operand& op, Immediate mask);
8653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void testw(const Operand& op, Register reg);
8663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bit operations.
868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void bt(const Operand& dst, Register src);
869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void bts(const Operand& dst, Register src);
870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsrq(Register dst, Register src);
871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsrq(Register dst, const Operand& src);
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bsrl(Register dst, Register src);
873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsrl(Register dst, const Operand& src);
874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsfq(Register dst, Register src);
875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsfq(Register dst, const Operand& src);
876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsfl(Register dst, Register src);
877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bsfl(Register dst, const Operand& src);
878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Miscellaneous
8803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void clc();
88144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void cld();
882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cpuid();
883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void hlt();
884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void int3();
885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void nop();
886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ret(int imm16);
887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ud2();
888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void setcc(Condition cc, Register reg);
889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Label operations & relative jumps (PPUM Appendix D)
891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Takes a branch opcode (cc) and a label (L) and generates
893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // either a backward branch or a forward branch and links it
894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to the label fixup chain. Usage:
895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Label L;    // unbound label
897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // j(cc, &L);  // forward branch to unbound label
898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // bind(&L);   // bind label to the current pc
899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // j(cc, &L);  // backward branch to bound label
900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // bind(&L);   // illegal: a label may be bound only once
901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Note: The same Label can be used for forward and backward branches
903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // but it may be bound only once.
904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void bind(Label* L);  // binds an unbound label L to the current code position
906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Calls
908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call near relative 32-bit displacement, relative to next instruction.
909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void call(Label* L);
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void call(Address entry, RelocInfo::Mode rmode);
911257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void call(Handle<Code> target,
9123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            TypeFeedbackId ast_id = TypeFeedbackId::None());
914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Calls directly to the given address using a relative offset.
9161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Should only ever be used in Code objects for calls within the
9171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // same Code object. Should not be used when generating new code (use labels),
9181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // but only when patching existing code.
9191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void call(Address target);
9201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call near absolute indirect, address in register
922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void call(Register adr);
923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jumps
925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump short or near relative.
9263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Use a 32-bit signed displacement.
927257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Unconditional jump to L
928257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void jmp(Label* L, Label::Distance distance = Label::kFar);
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void jmp(Address entry, RelocInfo::Mode rmode);
9303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void jmp(Handle<Code> target, RelocInfo::Mode rmode);
931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump near absolute indirect (r64)
933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void jmp(Register adr);
934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void jmp(const Operand& src);
935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Conditional jumps
937257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void j(Condition cc,
938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch         Label* L,
939257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch         Label::Distance distance = Label::kFar);
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void j(Condition cc, Address entry, RelocInfo::Mode rmode);
9413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Floating-point operations
944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fld(int i);
945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fld1();
947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fldz();
9486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void fldpi();
949b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void fldln2();
950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fld_s(const Operand& adr);
952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fld_d(const Operand& adr);
953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fstp_s(const Operand& adr);
955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fstp_d(const Operand& adr);
9563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void fstp(int index);
957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fild_s(const Operand& adr);
959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fild_d(const Operand& adr);
960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fist_s(const Operand& adr);
962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fistp_s(const Operand& adr);
964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fistp_d(const Operand& adr);
965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fisttp_s(const Operand& adr);
967d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void fisttp_d(const Operand& adr);
968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fabs();
970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fchs();
971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fadd(int i);
973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fsub(int i);
974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fmul(int i);
975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fdiv(int i);
976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fisub_s(const Operand& adr);
978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void faddp(int i = 1);
980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fsubp(int i = 1);
981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fsubrp(int i = 1);
982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fmulp(int i = 1);
983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fdivp(int i = 1);
984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fprem();
985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fprem1();
986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fxch(int i = 1);
988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fincstp();
989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ffree(int i = 0);
990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ftst();
992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fucomp(int i);
993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fucompp();
9943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void fucomi(int i);
9953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void fucomip();
9963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fcompp();
998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fnstsw_ax();
999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fwait();
1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fnclex();
1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fsin();
1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fcos();
10043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void fptan();
1005b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void fyl2x();
10063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void f2xm1();
10073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void fscale();
10083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void fninit();
1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void frndint();
1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void sahf();
1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // SSE instructions
1015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void addss(XMMRegister dst, XMMRegister src);
1016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void addss(XMMRegister dst, const Operand& src);
1017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void subss(XMMRegister dst, XMMRegister src);
1018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void subss(XMMRegister dst, const Operand& src);
1019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void mulss(XMMRegister dst, XMMRegister src);
1020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void mulss(XMMRegister dst, const Operand& src);
1021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void divss(XMMRegister dst, XMMRegister src);
1022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void divss(XMMRegister dst, const Operand& src);
1023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void maxss(XMMRegister dst, XMMRegister src);
1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void maxss(XMMRegister dst, const Operand& src);
1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void minss(XMMRegister dst, XMMRegister src);
1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void minss(XMMRegister dst, const Operand& src);
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void sqrtss(XMMRegister dst, XMMRegister src);
1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void sqrtss(XMMRegister dst, const Operand& src);
1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1032958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void ucomiss(XMMRegister dst, XMMRegister src);
1033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void ucomiss(XMMRegister dst, const Operand& src);
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movaps(XMMRegister dst, XMMRegister src);
1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Don't use this unless it's important to keep the
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // top half of the destination register unchanged.
1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Use movaps when moving float values and movd for integer
1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // values in xmm registers.
1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void movss(XMMRegister dst, XMMRegister src);
1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movss(XMMRegister dst, const Operand& src);
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movss(const Operand& dst, XMMRegister src);
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void shufps(XMMRegister dst, XMMRegister src, byte imm8);
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvttss2si(Register dst, const Operand& src);
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvttss2si(Register dst, XMMRegister src);
1048109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void cvtlsi2ss(XMMRegister dst, const Operand& src);
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvtlsi2ss(XMMRegister dst, Register src);
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void andps(XMMRegister dst, XMMRegister src);
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void andps(XMMRegister dst, const Operand& src);
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void orps(XMMRegister dst, XMMRegister src);
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void orps(XMMRegister dst, const Operand& src);
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void xorps(XMMRegister dst, XMMRegister src);
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void xorps(XMMRegister dst, const Operand& src);
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void addps(XMMRegister dst, XMMRegister src);
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void addps(XMMRegister dst, const Operand& src);
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void subps(XMMRegister dst, XMMRegister src);
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void subps(XMMRegister dst, const Operand& src);
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mulps(XMMRegister dst, XMMRegister src);
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mulps(XMMRegister dst, const Operand& src);
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void divps(XMMRegister dst, XMMRegister src);
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void divps(XMMRegister dst, const Operand& src);
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movmskps(Register dst, XMMRegister src);
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // SSE2 instructions
10706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movd(XMMRegister dst, Register src);
1071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void movd(XMMRegister dst, const Operand& src);
10726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movd(Register dst, XMMRegister src);
10736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movq(XMMRegister dst, Register src);
10746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movq(Register dst, XMMRegister src);
1075257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void movq(XMMRegister dst, XMMRegister src);
10766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1077257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Don't use this unless it's important to keep the
1078257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // top half of the destination register unchanged.
1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Use movapd when moving double values and movq for integer
1080257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // values in xmm registers.
1081053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  void movsd(XMMRegister dst, XMMRegister src);
1082257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1083257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void movsd(const Operand& dst, XMMRegister src);
10846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movsd(XMMRegister dst, const Operand& src);
1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void movdqa(const Operand& dst, XMMRegister src);
10871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void movdqa(XMMRegister dst, const Operand& src);
10881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movdqu(const Operand& dst, XMMRegister src);
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movdqu(XMMRegister dst, const Operand& src);
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1092257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void movapd(XMMRegister dst, XMMRegister src);
1093257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void psllq(XMMRegister reg, byte imm8);
1095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void psrlq(XMMRegister reg, byte imm8);
1096958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void pslld(XMMRegister reg, byte imm8);
1097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void psrld(XMMRegister reg, byte imm8);
10988defd9ff6930b4e24729971a61cf7469daf119beSteve Block
1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvttsd2si(Register dst, const Operand& src);
11001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void cvttsd2si(Register dst, XMMRegister src);
1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void cvttss2siq(Register dst, XMMRegister src);
1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void cvttss2siq(Register dst, const Operand& src);
110325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  void cvttsd2siq(Register dst, XMMRegister src);
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvttsd2siq(Register dst, const Operand& src);
1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvtlsi2sd(XMMRegister dst, const Operand& src);
1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvtlsi2sd(XMMRegister dst, Register src);
1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void cvtqsi2ss(XMMRegister dst, const Operand& src);
1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void cvtqsi2ss(XMMRegister dst, Register src);
1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvtqsi2sd(XMMRegister dst, const Operand& src);
1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvtqsi2sd(XMMRegister dst, Register src);
1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11158defd9ff6930b4e24729971a61cf7469daf119beSteve Block
11166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void cvtss2sd(XMMRegister dst, XMMRegister src);
11178defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void cvtss2sd(XMMRegister dst, const Operand& src);
11188defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void cvtsd2ss(XMMRegister dst, XMMRegister src);
1119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void cvtsd2ss(XMMRegister dst, const Operand& src);
11208defd9ff6930b4e24729971a61cf7469daf119beSteve Block
11218defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void cvtsd2si(Register dst, XMMRegister src);
11228defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void cvtsd2siq(Register dst, XMMRegister src);
11236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void addsd(XMMRegister dst, XMMRegister src);
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void addsd(XMMRegister dst, const Operand& src);
1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subsd(XMMRegister dst, XMMRegister src);
1127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void subsd(XMMRegister dst, const Operand& src);
1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void mulsd(XMMRegister dst, XMMRegister src);
1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mulsd(XMMRegister dst, const Operand& src);
1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void divsd(XMMRegister dst, XMMRegister src);
1131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void divsd(XMMRegister dst, const Operand& src);
1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void maxsd(XMMRegister dst, XMMRegister src);
1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void maxsd(XMMRegister dst, const Operand& src);
1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void minsd(XMMRegister dst, XMMRegister src);
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void minsd(XMMRegister dst, const Operand& src);
1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1138e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void andpd(XMMRegister dst, XMMRegister src);
1139e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void orpd(XMMRegister dst, XMMRegister src);
1140402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void xorpd(XMMRegister dst, XMMRegister src);
11416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void sqrtsd(XMMRegister dst, XMMRegister src);
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sqrtsd(XMMRegister dst, const Operand& src);
1143402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1144402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void ucomisd(XMMRegister dst, XMMRegister src);
11458defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void ucomisd(XMMRegister dst, const Operand& src);
1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cmpltsd(XMMRegister dst, XMMRegister src);
1147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void pcmpeqd(XMMRegister dst, XMMRegister src);
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movmskpd(Register dst, XMMRegister src);
1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void punpckldq(XMMRegister dst, XMMRegister src);
1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void punpckhdq(XMMRegister dst, XMMRegister src);
1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // SSE 4.1 instruction
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void extractps(Register dst, XMMRegister src, byte imm8);
1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pextrd(Register dst, XMMRegister src, int8_t imm8);
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pinsrd(XMMRegister dst, Register src, int8_t imm8);
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pinsrd(XMMRegister dst, const Operand& src, int8_t imm8);
1161257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void roundss(XMMRegister dst, XMMRegister src, RoundingMode mode);
1163257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode);
1164257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // AVX instruction
1166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x99, dst, src1, src2);
1168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xa9, dst, src1, src2);
1171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xb9, dst, src1, src2);
1174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x99, dst, src1, src2);
1177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xa9, dst, src1, src2);
1180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xb9, dst, src1, src2);
1183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x9b, dst, src1, src2);
1186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xab, dst, src1, src2);
1189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xbb, dst, src1, src2);
1192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x9b, dst, src1, src2);
1195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xab, dst, src1, src2);
1198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xbb, dst, src1, src2);
1201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x9d, dst, src1, src2);
1204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xad, dst, src1, src2);
1207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xbd, dst, src1, src2);
1210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x9d, dst, src1, src2);
1213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xad, dst, src1, src2);
1216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xbd, dst, src1, src2);
1219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x9f, dst, src1, src2);
1222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xaf, dst, src1, src2);
1225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xbf, dst, src1, src2);
1228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0x9f, dst, src1, src2);
1231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xaf, dst, src1, src2);
1234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmasd(0xbf, dst, src1, src2);
1237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmasd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmasd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x99, dst, src1, src2);
1243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xa9, dst, src1, src2);
1246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xb9, dst, src1, src2);
1249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x99, dst, src1, src2);
1252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xa9, dst, src1, src2);
1255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xb9, dst, src1, src2);
1258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x9b, dst, src1, src2);
1261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xab, dst, src1, src2);
1264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xbb, dst, src1, src2);
1267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x9b, dst, src1, src2);
1270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xab, dst, src1, src2);
1273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xbb, dst, src1, src2);
1276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x9d, dst, src1, src2);
1279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xad, dst, src1, src2);
1282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xbd, dst, src1, src2);
1285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x9d, dst, src1, src2);
1288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xad, dst, src1, src2);
1291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xbd, dst, src1, src2);
1294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x9f, dst, src1, src2);
1297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xaf, dst, src1, src2);
1300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xbf, dst, src1, src2);
1303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0x9f, dst, src1, src2);
1306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xaf, dst, src1, src2);
1309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfnmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    vfmass(0xbf, dst, src1, src2);
1312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmass(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void vfmass(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovd(XMMRegister dst, Register src);
1317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovd(XMMRegister dst, const Operand& src);
1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovd(Register dst, XMMRegister src);
1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovq(XMMRegister dst, Register src);
1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovq(XMMRegister dst, const Operand& src);
1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovq(Register dst, XMMRegister src);
1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x10, dst, src1, src2);
1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovsd(XMMRegister dst, const Operand& src) {
1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x10, dst, xmm0, src);
1328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovsd(const Operand& dst, XMMRegister src) {
1330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x11, src, xmm0, dst);
1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_SP_3(instr, opcode) \
1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_S_3(instr, opcode)        \
1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_P_3(instr, opcode)
1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_S_3(instr, opcode)  \
1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_3(instr##ss, opcode, vss) \
1339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_3(instr##sd, opcode, vsd)
1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_P_3(instr, opcode)  \
1342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_3(instr##ps, opcode, vps) \
1343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_3(instr##pd, opcode, vpd)
1344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AVX_3(instr, opcode, impl)                                     \
1346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) {    \
1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    impl(opcode, dst, src1, src2);                                     \
1348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }                                                                    \
1349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void instr(XMMRegister dst, XMMRegister src1, const Operand& src2) { \
1350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    impl(opcode, dst, src1, src2);                                     \
1351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vsqrt, 0x51);
1354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vadd, 0x58);
1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vsub, 0x5c);
1356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vmul, 0x59);
1357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vdiv, 0x5e);
1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vmin, 0x5d);
1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_SP_3(vmax, 0x5f);
1360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_P_3(vand, 0x54);
1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_P_3(vor, 0x56);
1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_P_3(vxor, 0x57);
1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_3(vpcmpeqd, 0x76, vpd);
1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AVX_3(vcvtsd2ss, 0x5a, vsd);
1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_3
1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_S_3
1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_P_3
1369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef AVX_SP_3
1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vpsrlq(XMMRegister dst, XMMRegister src, byte imm8) {
1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister iop = {2};
1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vpd(0x73, iop, dst, src);
1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    emit(imm8);
1375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vpsllq(XMMRegister dst, XMMRegister src, byte imm8) {
1377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister iop = {6};
1378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vpd(0x73, iop, dst, src);
1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    emit(imm8);
1380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtss2sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x5a, dst, src1, src2, kF3, k0F, kWIG);
1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtss2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x5a, dst, src1, src2, kF3, k0F, kWIG);
1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, Register src2) {
1388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister isrc2 = {src2.code()};
1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2a, dst, src1, isrc2, kF2, k0F, kW0);
1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2a, dst, src1, src2, kF2, k0F, kW0);
1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1394109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, Register src2) {
1395109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    XMMRegister isrc2 = {src2.code()};
1396109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    vsd(0x2a, dst, src1, isrc2, kF3, k0F, kW0);
1397109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1398109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1399109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    vsd(0x2a, dst, src1, src2, kF3, k0F, kW0);
1400109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Register src2) {
1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister isrc2 = {src2.code()};
1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2a, dst, src1, isrc2, kF3, k0F, kW1);
1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2a, dst, src1, src2, kF3, k0F, kW1);
1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, Register src2) {
1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister isrc2 = {src2.code()};
1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2a, dst, src1, isrc2, kF2, k0F, kW1);
1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2a, dst, src1, src2, kF2, k0F, kW1);
1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1415109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void vcvttss2si(Register dst, XMMRegister src) {
1416109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    XMMRegister idst = {dst.code()};
1417109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    vsd(0x2c, idst, xmm0, src, kF3, k0F, kW0);
1418109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1419109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void vcvttss2si(Register dst, const Operand& src) {
1420109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    XMMRegister idst = {dst.code()};
1421109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    vsd(0x2c, idst, xmm0, src, kF3, k0F, kW0);
1422109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvttsd2si(Register dst, XMMRegister src) {
1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2c, idst, xmm0, src, kF2, k0F, kW0);
1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvttsd2si(Register dst, const Operand& src) {
1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2c, idst, xmm0, src, kF2, k0F, kW0);
1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvttss2siq(Register dst, XMMRegister src) {
1432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2c, idst, xmm0, src, kF3, k0F, kW1);
1434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvttss2siq(Register dst, const Operand& src) {
1436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2c, idst, xmm0, src, kF3, k0F, kW1);
1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvttsd2siq(Register dst, XMMRegister src) {
1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2c, idst, xmm0, src, kF2, k0F, kW1);
1442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvttsd2siq(Register dst, const Operand& src) {
1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2c, idst, xmm0, src, kF2, k0F, kW1);
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vcvtsd2si(Register dst, XMMRegister src) {
1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2d, idst, xmm0, src, kF2, k0F, kW0);
1450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vucomisd(XMMRegister dst, XMMRegister src) {
1452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2e, dst, xmm0, src, k66, k0F, kWIG);
1453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vucomisd(XMMRegister dst, const Operand& src) {
1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x2e, dst, xmm0, src, k66, k0F, kWIG);
1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vroundss(XMMRegister dst, XMMRegister src1, XMMRegister src2,
1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                RoundingMode mode) {
1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x0a, dst, src1, src2, k66, k0F3A, kWIG);
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    emit(static_cast<byte>(mode) | 0x8);  // Mask precision exception.
1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vroundsd(XMMRegister dst, XMMRegister src1, XMMRegister src2,
1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                RoundingMode mode) {
1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(0x0b, dst, src1, src2, k66, k0F3A, kWIG);
1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    emit(static_cast<byte>(mode) | 0x8);  // Mask precision exception.
1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vsd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(op, dst, src1, src2, kF2, k0F, kWIG);
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2) {
1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsd(op, dst, src1, src2, kF2, k0F, kWIG);
1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vsd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2,
1475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           SIMDPrefix pp, LeadingOpcode m, VexW w);
1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2,
1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           SIMDPrefix pp, LeadingOpcode m, VexW w);
1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vss(0x10, dst, src1, src2);
1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovss(XMMRegister dst, const Operand& src) {
1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vss(0x10, dst, xmm0, src);
1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovss(const Operand& dst, XMMRegister src) {
1486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vss(0x11, src, xmm0, dst);
1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vucomiss(XMMRegister dst, XMMRegister src);
1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vucomiss(XMMRegister dst, const Operand& src);
1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vss(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vss(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovaps(XMMRegister dst, XMMRegister src) { vps(0x28, dst, xmm0, src); }
1494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovapd(XMMRegister dst, XMMRegister src) { vpd(0x28, dst, xmm0, src); }
1495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vmovmskpd(Register dst, XMMRegister src) {
1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    XMMRegister idst = {dst.code()};
1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vpd(0x50, idst, xmm0, src);
1498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vps(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vps(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vpd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void vpd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // BMI instruction
1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void andnq(Register dst, Register src1, Register src2) {
1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf2, dst, src1, src2);
1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void andnq(Register dst, Register src1, const Operand& src2) {
1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf2, dst, src1, src2);
1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void andnl(Register dst, Register src1, Register src2) {
1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf2, dst, src1, src2);
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void andnl(Register dst, Register src1, const Operand& src2) {
1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf2, dst, src1, src2);
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bextrq(Register dst, Register src1, Register src2) {
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf7, dst, src2, src1);
1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bextrq(Register dst, const Operand& src1, Register src2) {
1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf7, dst, src2, src1);
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bextrl(Register dst, Register src1, Register src2) {
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf7, dst, src2, src1);
1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bextrl(Register dst, const Operand& src1, Register src2) {
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf7, dst, src2, src1);
1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsiq(Register dst, Register src) {
1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {3};
1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf3, ireg, dst, src);
1533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsiq(Register dst, const Operand& src) {
1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {3};
1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf3, ireg, dst, src);
1537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsil(Register dst, Register src) {
1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {3};
1540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf3, ireg, dst, src);
1541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsil(Register dst, const Operand& src) {
1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {3};
1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf3, ireg, dst, src);
1545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsmskq(Register dst, Register src) {
1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {2};
1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf3, ireg, dst, src);
1549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsmskq(Register dst, const Operand& src) {
1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {2};
1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf3, ireg, dst, src);
1553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsmskl(Register dst, Register src) {
1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {2};
1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf3, ireg, dst, src);
1557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsmskl(Register dst, const Operand& src) {
1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {2};
1560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf3, ireg, dst, src);
1561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsrq(Register dst, Register src) {
1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {1};
1564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf3, ireg, dst, src);
1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsrq(Register dst, const Operand& src) {
1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {1};
1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1q(0xf3, ireg, dst, src);
1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsrl(Register dst, Register src) {
1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {1};
1572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf3, ireg, dst, src);
1573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void blsrl(Register dst, const Operand& src) {
1575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register ireg = {1};
1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi1l(0xf3, ireg, dst, src);
1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void tzcntq(Register dst, Register src);
1579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void tzcntq(Register dst, const Operand& src);
1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void tzcntl(Register dst, Register src);
1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void tzcntl(Register dst, const Operand& src);
1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void lzcntq(Register dst, Register src);
1584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void lzcntq(Register dst, const Operand& src);
1585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void lzcntl(Register dst, Register src);
1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void lzcntl(Register dst, const Operand& src);
1587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void popcntq(Register dst, Register src);
1589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void popcntq(Register dst, const Operand& src);
1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void popcntl(Register dst, Register src);
1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void popcntl(Register dst, const Operand& src);
1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bzhiq(Register dst, Register src1, Register src2) {
1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kNone, 0xf5, dst, src2, src1);
1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bzhiq(Register dst, const Operand& src1, Register src2) {
1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kNone, 0xf5, dst, src2, src1);
1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bzhil(Register dst, Register src1, Register src2) {
1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kNone, 0xf5, dst, src2, src1);
1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bzhil(Register dst, const Operand& src1, Register src2) {
1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kNone, 0xf5, dst, src2, src1);
1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void mulxq(Register dst1, Register dst2, Register src) {
1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF2, 0xf6, dst1, dst2, src);
1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void mulxq(Register dst1, Register dst2, const Operand& src) {
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF2, 0xf6, dst1, dst2, src);
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void mulxl(Register dst1, Register dst2, Register src) {
1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF2, 0xf6, dst1, dst2, src);
1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void mulxl(Register dst1, Register dst2, const Operand& src) {
1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF2, 0xf6, dst1, dst2, src);
1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pdepq(Register dst, Register src1, Register src2) {
1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF2, 0xf5, dst, src1, src2);
1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pdepq(Register dst, Register src1, const Operand& src2) {
1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF2, 0xf5, dst, src1, src2);
1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pdepl(Register dst, Register src1, Register src2) {
1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF2, 0xf5, dst, src1, src2);
1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pdepl(Register dst, Register src1, const Operand& src2) {
1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF2, 0xf5, dst, src1, src2);
1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pextq(Register dst, Register src1, Register src2) {
1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF3, 0xf5, dst, src1, src2);
1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pextq(Register dst, Register src1, const Operand& src2) {
1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF3, 0xf5, dst, src1, src2);
1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pextl(Register dst, Register src1, Register src2) {
1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF3, 0xf5, dst, src1, src2);
1637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void pextl(Register dst, Register src1, const Operand& src2) {
1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF3, 0xf5, dst, src1, src2);
1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void sarxq(Register dst, Register src1, Register src2) {
1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF3, 0xf7, dst, src2, src1);
1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void sarxq(Register dst, const Operand& src1, Register src2) {
1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF3, 0xf7, dst, src2, src1);
1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void sarxl(Register dst, Register src1, Register src2) {
1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF3, 0xf7, dst, src2, src1);
1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void sarxl(Register dst, const Operand& src1, Register src2) {
1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF3, 0xf7, dst, src2, src1);
1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shlxq(Register dst, Register src1, Register src2) {
1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(k66, 0xf7, dst, src2, src1);
1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shlxq(Register dst, const Operand& src1, Register src2) {
1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(k66, 0xf7, dst, src2, src1);
1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shlxl(Register dst, Register src1, Register src2) {
1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(k66, 0xf7, dst, src2, src1);
1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shlxl(Register dst, const Operand& src1, Register src2) {
1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(k66, 0xf7, dst, src2, src1);
1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shrxq(Register dst, Register src1, Register src2) {
1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF2, 0xf7, dst, src2, src1);
1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shrxq(Register dst, const Operand& src1, Register src2) {
1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2q(kF2, 0xf7, dst, src2, src1);
1670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shrxl(Register dst, Register src1, Register src2) {
1672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF2, 0xf7, dst, src2, src1);
1673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void shrxl(Register dst, const Operand& src1, Register src2) {
1675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bmi2l(kF2, 0xf7, dst, src2, src1);
1676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void rorxq(Register dst, Register src, byte imm8);
1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void rorxq(Register dst, const Operand& src, byte imm8);
1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void rorxl(Register dst, Register src, byte imm8);
1680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void rorxl(Register dst, const Operand& src, byte imm8);
1681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check the code size generated from label to here.
16833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int SizeOfCodeGeneratedSince(Label* label) {
16843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return pc_offset() - label->pos();
16853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
1686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Mark generator continuation.
1688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void RecordGeneratorContinuation();
1689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
16907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Mark address of a debug break slot.
1691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void RecordDebugBreakSlot(RelocInfo::Mode mode);
16927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Record a comment relocation entry that can be used by a disassembler.
1694b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Use --code-comments to enable.
1695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void RecordComment(const char* msg);
1696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Record a deoptimization reason that can be used by a log or cpu profiler.
1698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Use --trace-deopt to enable.
1699bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void RecordDeoptReason(const int reason, int raw_position, int id);
1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          ConstantPoolEntry::Access access,
1703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          ConstantPoolEntry::Type type) {
1704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // No embedded constant pool support.
1705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNREACHABLE();
1706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Writes a single word of data in the code stream.
1709b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Used for inline tables, e.g., jump-tables.
1710b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void db(uint8_t data);
1711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void dd(uint32_t data);
1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void dq(uint64_t data);
1713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void dp(uintptr_t data) { dq(data); }
1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void dq(Label* label);
1715b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
17163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  AssemblerPositionsRecorder* positions_recorder() {
17173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return &positions_recorder_;
17183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if there is less than kGap bytes available in the buffer.
1721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If this is the case, we need to grow the buffer before emitting
1722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // an instruction or relocation information.
1723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool buffer_overflow() const {
1724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return pc_ >= reloc_info_writer.pos() - kGap;
1725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the number of bytes available in the buffer.
1728d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  inline int available_space() const {
1729d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    return static_cast<int>(reloc_info_writer.pos() - pc_);
1730d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
1731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
17323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static bool IsNop(Address addr);
17337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Avoid overflows for displacements etc.
1735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaximalBufferSize = 512*MB;
1736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
17373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  byte byte_at(int pos)  { return buffer_[pos]; }
17383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
17393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
174044f0eee88ff00398ff7f715fab053374d808c90dSteve Block protected:
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Call near indirect
1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void call(const Operand& operand);
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* addr_at(int pos)  { return buffer_ + pos; }
1746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uint32_t long_at(int pos)  {
1747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return *reinterpret_cast<uint32_t*>(addr_at(pos));
1748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void long_at_put(int pos, uint32_t x)  {
1750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
1751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // code emission
1754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GrowBuffer();
1755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit(byte x) { *pc_++ = x; }
1757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emitl(uint32_t x);
1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void emitp(void* x, RelocInfo::Mode rmode);
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void emitq(uint64_t x);
1760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emitw(uint16_t x);
1761257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void emit_code_target(Handle<Code> target,
1762257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               RelocInfo::Mode rmode,
1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               TypeFeedbackId ast_id = TypeFeedbackId::None());
1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode);
1765bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void emit(Immediate x) {
1766bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (!RelocInfo::IsNone(x.rmode_)) {
1767bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      RecordRelocInfo(x.rmode_);
1768bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
1769bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    emitl(x.value_);
1770bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a REX prefix that encodes a 64-bit operand size and
1773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the top bit of both register codes.
1774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is set.
1776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(XMMRegister reg, Register rm_reg);
17776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void emit_rex_64(Register reg, XMMRegister rm_reg);
17786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void emit_rex_64(Register reg, Register rm_reg);
1779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a REX prefix that encodes a 64-bit operand size and
1781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the top bit of the destination, index, and base register codes.
1782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of reg is used for REX.R, the high bit of op's base
1783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register is used for REX.B, and the high bit of op's index register
1784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is used for REX.X.  REX.W is set.
1785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(Register reg, const Operand& op);
1786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(XMMRegister reg, const Operand& op);
1787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a REX prefix that encodes a 64-bit operand size and
1789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the top bit of the register code.
1790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of register is used for REX.B.
1791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is set and REX.R and REX.X are clear.
1792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(Register rm_reg);
1793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a REX prefix that encodes a 64-bit operand size and
1795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the top bit of the index and base register codes.
1796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of op's base register is used for REX.B, and the high
1797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // bit of op's index register is used for REX.X.
1798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is set and REX.R clear.
1799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(const Operand& op);
1800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size.
1802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_rex_64() { emit(0x48); }
1803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is clear.
1806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_32(Register reg, Register rm_reg);
1807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of reg is used for REX.R, the high bit of op's base
1809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register is used for REX.B, and the high bit of op's index register
1810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is used for REX.X.  REX.W is cleared.
1811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_32(Register reg, const Operand& op);
1812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of rm_reg goes to REX.B.
1814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W, REX.R and REX.X are clear.
1815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_32(Register rm_reg);
1816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of base goes to REX.B and high bit of index to REX.X.
1818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W and REX.R are clear.
1819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_32(const Operand& op);
1820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is cleared.  If no REX bits are set, no byte is emitted.
1823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(Register reg, Register rm_reg);
1824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of reg is used for REX.R, the high bit of op's base
1826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register is used for REX.B, and the high bit of op's index register
1827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is used for REX.X.  REX.W is cleared.  If no REX bits are set, nothing
1828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is emitted.
1829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(Register reg, const Operand& op);
1830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // As for emit_optional_rex_32(Register, Register), except that
1832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the registers are XMM registers.
1833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base);
1834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // As for emit_optional_rex_32(Register, Register), except that
18366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // one of the registers is an XMM registers.
1837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(XMMRegister reg, Register base);
1838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
18396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // As for emit_optional_rex_32(Register, Register), except that
18406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // one of the registers is an XMM registers.
18416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void emit_optional_rex_32(Register reg, XMMRegister base);
18426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // As for emit_optional_rex_32(Register, const Operand&), except that
1844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the register is an XMM register.
1845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(XMMRegister reg, const Operand& op);
1846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Optionally do as emit_rex_32(Register) if the register number has
1848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the high bit set.
1849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(Register rm_reg);
1850958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_optional_rex_32(XMMRegister rm_reg);
1851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Optionally do as emit_rex_32(const Operand&) if the operand register
1853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // numbers have a high bit set.
1854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(const Operand& op);
1855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_rex(int size) {
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (size == kInt64Size) {
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      emit_rex_64();
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(size == kInt32Size);
1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1>
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_rex(P1 p1, int size) {
1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (size == kInt64Size) {
1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      emit_rex_64(p1);
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(size == kInt32Size);
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      emit_optional_rex_32(p1);
1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class P1, class P2>
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_rex(P1 p1, P2 p2, int size) {
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (size == kInt64Size) {
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      emit_rex_64(p1, p2);
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(size == kInt32Size);
1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      emit_optional_rex_32(p1, p2);
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Emit vex prefix
1885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void emit_vex2_byte0() { emit(0xc5); }
1886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l,
1887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              SIMDPrefix pp);
1888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void emit_vex3_byte0() { emit(0xc4); }
1889958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_vex3_byte1(XMMRegister reg, XMMRegister rm, LeadingOpcode m);
1890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_vex3_byte1(XMMRegister reg, const Operand& rm,
1891958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              LeadingOpcode m);
1892958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l,
1893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              SIMDPrefix pp);
1894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, XMMRegister rm,
1895958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1896958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              VexW w);
1897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline void emit_vex_prefix(Register reg, Register v, Register rm,
1898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              VexW w);
1900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, const Operand& rm,
1901958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1902958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              VexW w);
1903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline void emit_vex_prefix(Register reg, Register v, const Operand& rm,
1904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              VexW w);
1906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit the ModR/M byte, and optionally the SIB byte and
1908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // 1- or 4-byte offset for a memory operand.  Also encodes
1909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the second operand of the operation, a register or operation
1910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // subcode, into the reg field of the ModR/M byte.
1911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_operand(Register reg, const Operand& adr) {
1912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit_operand(reg.low_bits(), adr);
1913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit the ModR/M byte, and optionally the SIB byte and
1916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // 1- or 4-byte offset for a memory operand.  Also used to encode
1917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a three-bit opcode extension into the ModR/M byte.
1918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_operand(int rm, const Operand& adr);
1919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
1921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_modrm(Register reg, Register rm_reg) {
1922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
1923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit a ModR/M byte with an operation subcode in the reg field and
1926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a register in the rm_reg field.
1927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_modrm(int code, Register rm_reg) {
1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_uint3(code));
1929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit(0xC0 | code << 3 | rm_reg.low_bits());
1930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit the code-object-relative offset of the label's position
1933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_code_relative_offset(Label* label);
1934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The first argument is the reg field, the second argument is the r/m field.
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sse_operand(XMMRegister dst, XMMRegister src);
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sse_operand(XMMRegister reg, const Operand& adr);
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sse_operand(Register reg, const Operand& adr);
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sse_operand(XMMRegister dst, Register src);
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sse_operand(Register dst, XMMRegister src);
1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit machine code for one of the operations ADD, ADC, SUB, SBC,
1943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // AND, OR, XOR, or CMP.  The encodings of these operations are all
1944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // similar, differing just in the opcode or in the reg field of the
1945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ModR/M byte.
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void arithmetic_op_8(byte opcode, Register reg, Register rm_reg);
1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg);
1948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
1949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size);
1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void arithmetic_op(byte opcode,
1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     Register reg,
1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     const Operand& rm_reg,
1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     int size);
1956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Operate on a byte in memory or register.
1957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_8(byte subcode,
1958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Register dst,
1959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Immediate src);
1960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_8(byte subcode,
1961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 const Operand& dst,
1962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Immediate src);
1963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Operate on a word in memory or register.
1964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_16(byte subcode,
1965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Register dst,
1966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Immediate src);
1967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_16(byte subcode,
1968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  const Operand& dst,
1969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Immediate src);
1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void immediate_arithmetic_op(byte subcode,
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Register dst,
1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Immediate src,
1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               int size);
1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void immediate_arithmetic_op(byte subcode,
1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               const Operand& dst,
1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Immediate src,
1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               int size);
1979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit machine code for a shift operation.
1981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void shift(Operand dst, Immediate shift_amount, int subcode, int size);
1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void shift(Register dst, Immediate shift_amount, int subcode, int size);
1983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shift dst by cl % 64 bits.
1984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void shift(Register dst, int subcode, int size);
1985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void shift(Operand dst, int subcode, int size);
1986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_farith(int b1, int b2, int i);
1988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // labels
1990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // void print(Label* L);
1991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void bind_to(Label* L, int pos);
1992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // record reloc info for current pc_
1994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Arithmetics
1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_add(Register dst, Register src, int size) {
1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x03, dst, src, size);
1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_add(Register dst, Immediate src, int size) {
2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x0, dst, src, size);
2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_add(Register dst, const Operand& src, int size) {
2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x03, dst, src, size);
2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_add(const Operand& dst, Register src, int size) {
2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x1, src, dst, size);
2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_add(const Operand& dst, Immediate src, int size) {
2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x0, dst, src, size);
2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_and(Register dst, Register src, int size) {
2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x23, dst, src, size);
2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_and(Register dst, const Operand& src, int size) {
2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x23, dst, src, size);
2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_and(const Operand& dst, Register src, int size) {
2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x21, src, dst, size);
2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_and(Register dst, Immediate src, int size) {
2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x4, dst, src, size);
2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_and(const Operand& dst, Immediate src, int size) {
2034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x4, dst, src, size);
2035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_cmp(Register dst, Register src, int size) {
2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x3B, dst, src, size);
2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_cmp(Register dst, const Operand& src, int size) {
2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x3B, dst, src, size);
2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_cmp(const Operand& dst, Register src, int size) {
2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x39, src, dst, size);
2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_cmp(Register dst, Immediate src, int size) {
2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x7, dst, src, size);
2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_cmp(const Operand& dst, Immediate src, int size) {
2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x7, dst, src, size);
2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_dec(Register dst, int size);
2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_dec(const Operand& dst, int size);
2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Divide rdx:rax by src.  Quotient in rax, remainder in rdx when size is 64.
2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Divide edx:eax by lower 32 bits of src.  Quotient in eax, remainder in edx
2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // when size is 32.
2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_idiv(Register src, int size);
2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_div(Register src, int size);
2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Signed multiply instructions.
2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32.
2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_imul(Register src, int size);
2069958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void emit_imul(const Operand& src, int size);
2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_imul(Register dst, Register src, int size);
2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_imul(Register dst, const Operand& src, int size);
2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_imul(Register dst, Register src, Immediate imm, int size);
2073958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void emit_imul(Register dst, const Operand& src, Immediate imm, int size);
2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_inc(Register dst, int size);
2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_inc(const Operand& dst, int size);
2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_lea(Register dst, const Operand& src, int size);
2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_mov(Register dst, const Operand& src, int size);
2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_mov(Register dst, Register src, int size);
2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_mov(const Operand& dst, Register src, int size);
2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_mov(Register dst, Immediate value, int size);
2084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_mov(const Operand& dst, Immediate value, int size);
2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_movzxb(Register dst, const Operand& src, int size);
2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_movzxb(Register dst, Register src, int size);
2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_movzxw(Register dst, const Operand& src, int size);
2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_movzxw(Register dst, Register src, int size);
2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_neg(Register dst, int size);
2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_neg(const Operand& dst, int size);
2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_not(Register dst, int size);
2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_not(const Operand& dst, int size);
2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_or(Register dst, Register src, int size) {
2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x0B, dst, src, size);
2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_or(Register dst, const Operand& src, int size) {
2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x0B, dst, src, size);
2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_or(const Operand& dst, Register src, int size) {
2106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x9, src, dst, size);
2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_or(Register dst, Immediate src, int size) {
2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x1, dst, src, size);
2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_or(const Operand& dst, Immediate src, int size) {
2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x1, dst, src, size);
2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_repmovs(int size);
2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sbb(Register dst, Register src, int size) {
2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x1b, dst, src, size);
2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sub(Register dst, Register src, int size) {
2124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x2B, dst, src, size);
2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sub(Register dst, Immediate src, int size) {
2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x5, dst, src, size);
2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sub(Register dst, const Operand& src, int size) {
2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x2B, dst, src, size);
2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sub(const Operand& dst, Register src, int size) {
2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x29, src, dst, size);
2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_sub(const Operand& dst, Immediate src, int size) {
2140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x5, dst, src, size);
2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_test(Register dst, Register src, int size);
2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_test(Register reg, Immediate mask, int size);
2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_test(const Operand& op, Register reg, int size);
2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_test(const Operand& op, Immediate mask, int size);
2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_test(Register reg, const Operand& op, int size) {
2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return emit_test(op, reg, size);
2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xchg(Register dst, Register src, int size);
2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xchg(Register dst, const Operand& src, int size);
2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xor(Register dst, Register src, int size) {
2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (size == kInt64Size && dst.code() == src.code()) {
2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // there is no need to make this a 64 bit operation.
2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arithmetic_op(0x33, dst, src, kInt32Size);
2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arithmetic_op(0x33, dst, src, size);
2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xor(Register dst, const Operand& src, int size) {
2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x33, dst, src, size);
2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xor(Register dst, Immediate src, int size) {
2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x6, dst, src, size);
2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xor(const Operand& dst, Immediate src, int size) {
2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediate_arithmetic_op(0x6, dst, src, size);
2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_xor(const Operand& dst, Register src, int size) {
2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arithmetic_op(0x31, src, dst, size);
2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Most BMI instructions are similiar.
2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi1q(byte op, Register reg, Register vreg, Register rm);
2182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi1q(byte op, Register reg, Register vreg, const Operand& rm);
2183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi1l(byte op, Register reg, Register vreg, Register rm);
2184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi1l(byte op, Register reg, Register vreg, const Operand& rm);
2185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm);
2186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg,
2187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             const Operand& rm);
2188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm);
2189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg,
2190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             const Operand& rm);
2191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class CodePatcher;
2193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class EnsureSpace;
2194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class RegExpMacroAssemblerX64;
2195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // code generation
2197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RelocInfoWriter reloc_info_writer;
2198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Internal reference positions, required for (potential) patching in
2200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // GrowBuffer(); contains only those internal references whose labels
2201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // are already bound.
2202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::deque<int> internal_reference_positions_;
2203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
22043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  List< Handle<Code> > code_targets_;
2205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
22063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  AssemblerPositionsRecorder positions_recorder_;
22073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  friend class AssemblerPositionsRecorder;
2208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper class that ensures that there is enough space for generating
2212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instructions and relocation information.  The constructor makes
2213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// sure that there is enough space and (in debug mode) the destructor
2214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// checks that we did not generate too much.
2215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EnsureSpace BASE_EMBEDDED {
2216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
2218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
2219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
2220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    space_before_ = assembler_->available_space();
2221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
2222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
2225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ~EnsureSpace() {
2226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int bytes_generated = space_before_ - assembler_->available_space();
2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(bytes_generated < assembler_->kGap);
2228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
2230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
2232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Assembler* assembler_;
2233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
2234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int space_before_;
2235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
2236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
2239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
2240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_X64_ASSEMBLER_X64_H_
2242