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