assembler-x64.h revision 053d10c438f14580aaf4ab1b2aad93a5a4fe8b82
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.
33e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Copyright 2011 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
40d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "serialize.h"
41d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utility functions
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test whether a 64-bit value is in a specific range.
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uint32(int64_t x) {
498defd9ff6930b4e24729971a61cf7469daf119beSteve Block  static const uint64_t kMaxUInt32 = V8_UINT64_C(0xffffffff);
508defd9ff6930b4e24729971a61cf7469daf119beSteve Block  return static_cast<uint64_t>(x) <= kMaxUInt32;
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_int32(int64_t x) {
548defd9ff6930b4e24729971a61cf7469daf119beSteve Block  static const int64_t kMinInt32 = -V8_INT64_C(0x80000000);
558defd9ff6930b4e24729971a61cf7469daf119beSteve Block  return is_uint32(x - kMinInt32);
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool uint_is_int32(uint64_t x) {
598defd9ff6930b4e24729971a61cf7469daf119beSteve Block  static const uint64_t kMaxInt32 = V8_UINT64_C(0x7fffffff);
608defd9ff6930b4e24729971a61cf7469daf119beSteve Block  return x <= kMaxInt32;
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uint32(uint64_t x) {
648defd9ff6930b4e24729971a61cf7469daf119beSteve Block  static const uint64_t kMaxUInt32 = V8_UINT64_C(0xffffffff);
658defd9ff6930b4e24729971a61cf7469daf119beSteve Block  return x <= kMaxUInt32;
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CPU Registers.
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 1) We would prefer to use an enum, but enum values are assignment-
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// compatible with int, which has caused code-generation bugs.
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 2) We would prefer to use a class instead of a struct but we don't like
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the register initialization to depend on the particular initialization
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order (which appears to be different on OS X, Linux, and Windows for the
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// installed versions of C++ we tried). Using a struct permits C-style
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "initialization". Also, the Register objects cannot be const as this
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// forces initialization stubs in MSVC, making us dependent on initialization
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order.
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 3) By not using an enum, we are possibly preventing the compiler from
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// doing certain constant folds, which may significantly reduce the
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// code generated for some assembly instructions (because they boil down
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to a few constants). If this is a problem, we could change the code
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// such that we use an enum in optimized mode, and the struct in debug
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// mode. This way we get the compile-time error checking in debug mode
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and best performance in optimized code.
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct Register {
91b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // The non-allocatable registers are:
92b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  //  rsp - stack pointer
93b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  //  rbp - frame pointer
94b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  //  rsi - context register
95b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  //  r10 - fixed scratch register
9644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  //  r12 - smi constant register
97b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  //  r13 - root register
98b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kNumRegisters = 16;
99b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kNumAllocatableRegisters = 10;
100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
101b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  static int ToAllocationIndex(Register reg) {
102e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return kAllocationIndexByRegisterCode[reg.code()];
103b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
104b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
105b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  static Register FromAllocationIndex(int index) {
106b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    ASSERT(index >= 0 && index < kNumAllocatableRegisters);
107e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    Register result = { kRegisterCodeByAllocationIndex[index] };
108b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    return result;
109b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
110b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const char* AllocationIndexToString(int index) {
112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(index >= 0 && index < kNumAllocatableRegisters);
113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    const char* const names[] = {
114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "rax",
115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "rbx",
116b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      "rdx",
117b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      "rcx",
118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "rdi",
119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "r8",
120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "r9",
121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "r11",
122b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      "r14",
12344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      "r15"
124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    };
125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return names[index];
126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static Register toRegister(int code) {
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Register r = { code };
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return r;
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
1330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  bool is(Register reg) const { return code_ == reg.code_; }
1340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int code() const {
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(is_valid());
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return code_;
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int bit() const {
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return 1 << code_;
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the high bit of the register code as a 0 or 1.  Used often
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // when constructing the REX prefix byte.
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int high_bit() const {
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return code_ >> 3;
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the 3 low bits of the register code.  Used when encoding registers
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in modR/M, SIB, and opcode bytes.
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int low_bits() const {
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return code_ & 0x7;
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Unfortunately we can't make this private in a struct when initializing
1543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // by assignment.
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int code_;
1561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
157b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private:
158e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static const int kRegisterCodeByAllocationIndex[kNumAllocatableRegisters];
159e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static const int kAllocationIndexByRegisterCode[kNumRegisters];
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
162402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rax = { 0 };
163402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rcx = { 1 };
164402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rdx = { 2 };
165402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rbx = { 3 };
166402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rsp = { 4 };
167402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rbp = { 5 };
168402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rsi = { 6 };
169402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rdi = { 7 };
170402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r8 = { 8 };
171402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r9 = { 9 };
172402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r10 = { 10 };
173402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r11 = { 11 };
174402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r12 = { 12 };
175402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r13 = { 13 };
176402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r14 = { 14 };
177402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r15 = { 15 };
178402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register no_reg = { -1 };
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct XMMRegister {
182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kNumRegisters = 16;
183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kNumAllocatableRegisters = 15;
184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int ToAllocationIndex(XMMRegister reg) {
186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(reg.code() != 0);
187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return reg.code() - 1;
188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
190b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  static XMMRegister FromAllocationIndex(int index) {
191b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    ASSERT(0 <= index && index < kNumAllocatableRegisters);
192b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    XMMRegister result = { index + 1 };
193b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    return result;
194b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
195b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const char* AllocationIndexToString(int index) {
197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(index >= 0 && index < kNumAllocatableRegisters);
198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    const char* const names[] = {
199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm1",
200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm2",
201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm3",
202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm4",
203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm5",
204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm6",
205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm7",
206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm8",
207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm9",
208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm10",
209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm11",
210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm12",
211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm13",
212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm14",
213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      "xmm15"
214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    };
215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return names[index];
216b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
219b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  bool is(XMMRegister reg) const { return code_ == reg.code_; }
2200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int code() const {
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(is_valid());
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return code_;
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the high bit of the register code as a 0 or 1.  Used often
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // when constructing the REX prefix byte.
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int high_bit() const {
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return code_ >> 3;
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the 3 low bits of the register code.  Used when encoding registers
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in modR/M, SIB, and opcode bytes.
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int low_bits() const {
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return code_ & 0x7;
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int code_;
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
239402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm0 = { 0 };
240402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm1 = { 1 };
241402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm2 = { 2 };
242402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm3 = { 3 };
243402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm4 = { 4 };
244402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm5 = { 5 };
245402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm6 = { 6 };
246402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm7 = { 7 };
247402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm8 = { 8 };
248402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm9 = { 9 };
249402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm10 = { 10 };
250402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm11 = { 11 };
251402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm12 = { 12 };
252402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm13 = { 13 };
253402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm14 = { 14 };
254402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm15 = { 15 };
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochtypedef XMMRegister DoubleRegister;
258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum Condition {
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // any value < 0 is considered no_condition
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  no_condition  = -1,
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  overflow      =  0,
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  no_overflow   =  1,
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  below         =  2,
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  above_equal   =  3,
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  equal         =  4,
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  not_equal     =  5,
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  below_equal   =  6,
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  above         =  7,
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  negative      =  8,
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  positive      =  9,
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  parity_even   = 10,
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  parity_odd    = 11,
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  less          = 12,
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  greater_equal = 13,
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  less_equal    = 14,
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  greater       = 15,
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Fake conditions that are handled by the
2823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // opcodes using them.
2833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  always        = 16,
2843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  never         = 17,
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // aliases
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  carry         = below,
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  not_carry     = above_equal,
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  zero          = equal,
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  not_zero      = not_equal,
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  sign          = negative,
2913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  not_sign      = positive,
2923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  last_condition = greater
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns the equivalent of !cc.
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Negation of the default no_condition (-1) results in a non-default
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// no_condition value (-2). As long as tests for no_condition check
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for condition < 0, this will work as expected.
3009dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monseninline Condition NegateCondition(Condition cc) {
3019dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return static_cast<Condition>(cc ^ 1);
3029dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
3039dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Corresponds to transposing the operands of a comparison.
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockinline Condition ReverseCondition(Condition cc) {
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  switch (cc) {
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case below:
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return above;
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case above:
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return below;
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case above_equal:
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return below_equal;
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case below_equal:
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return above_equal;
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case less:
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return greater;
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case greater:
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return less;
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case greater_equal:
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return less_equal;
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case less_equal:
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return greater_equal;
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    default:
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return cc;
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3299dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum Hint {
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  no_hint = 0,
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  not_taken = 0x2e,
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  taken = 0x3e
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The result of negating a hint is as if the corresponding condition
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// were negated by NegateCondition.  That is, no_hint is mapped to
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// itself and not_taken and taken are mapped to each other.
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockinline Hint NegateHint(Hint hint) {
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return (hint == no_hint)
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ? no_hint
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : ((hint == not_taken) ? taken : not_taken);
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Machine instruction Immediates
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Immediate BASE_EMBEDDED {
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit Immediate(int32_t value) : value_(value) {}
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int32_t value_;
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class Assembler;
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Machine instruction Operands
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum ScaleFactor {
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  times_1 = 0,
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  times_2 = 1,
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  times_4 = 2,
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  times_8 = 3,
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  times_int_size = times_4,
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  times_pointer_size = times_8
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Operand BASE_EMBEDDED {
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [base + disp/r]
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Operand(Register base, int32_t disp);
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [base + index*scale + disp/r]
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Operand(Register base,
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          Register index,
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          ScaleFactor scale,
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          int32_t disp);
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [index*scale + disp/r]
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Operand(Register index,
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          ScaleFactor scale,
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          int32_t disp);
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
389f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Offset from existing memory operand.
390f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Offset is added to existing displacement as 32-bit signed values and
391f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // this must not overflow.
392f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Operand(const Operand& base, int32_t offset);
393f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
3941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Checks whether either base or index register is the given register.
3951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Does not check the "reg" part of the Operand.
3961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool AddressUsesRegister(Register reg) const;
3971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
39844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Queries related to the size of the generated instruction.
39944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Whether the generated instruction will have a REX prefix.
40044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool requires_rex() const { return rex_ != 0; }
40144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Size of the ModR/M, SIB and displacement parts of the generated
40244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // instruction.
40344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int operand_size() const { return len_; }
40444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte rex_;
4077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  byte buf_[6];
4081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // The number of bytes of buf_ in use.
4091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  byte len_;
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the ModR/M byte without an encoded 'reg' register. The
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register is encoded later as part of the emit_operand operation.
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // set_modrm can be called before or after set_sib and set_disp*.
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_modrm(int mod, Register rm);
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the SIB byte if one is needed. Sets the length to 2 rather than 1.
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_sib(ScaleFactor scale, Register index, Register base);
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Adds operand displacement fields (offsets added to the memory address).
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Needs to be called after set_sib, not before it.
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_disp8(int disp);
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_disp32(int disp);
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class Assembler;
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CpuFeatures keeps track of which features are supported by the target CPU.
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Supported features must be enabled by a Scope before use.
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Example:
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   if (CpuFeatures::IsSupported(SSE3)) {
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     CpuFeatures::Scope fscope(SSE3);
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     // Generate SSE3 floating point code.
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   } else {
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     // Generate standard x87 or SSE2 floating point code.
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   }
4378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochclass CpuFeatures : public AllStatic {
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Detect features of the target CPU. Set safe defaults if the serializer
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is enabled (snapshots must be portable).
4418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static void Probe();
44244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check whether a feature is supported by the target CPU.
4448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static bool IsSupported(CpuFeature f) {
4458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    ASSERT(initialized_);
4463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    if (f == SSE2 && !FLAG_enable_sse2) return false;
4473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    if (f == SSE3 && !FLAG_enable_sse3) return false;
4483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    if (f == CMOV && !FLAG_enable_cmov) return false;
4493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    if (f == RDTSC && !FLAG_enable_rdtsc) return false;
4503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    if (f == SAHF && !FLAG_enable_sahf) return false;
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return (supported_ & (V8_UINT64_C(1) << f)) != 0;
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
4548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#ifdef DEBUG
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check whether a feature is currently enabled.
4568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static bool IsEnabled(CpuFeature f) {
4578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    ASSERT(initialized_);
4588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Isolate* isolate = Isolate::UncheckedCurrent();
4598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    if (isolate == NULL) {
4608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      // When no isolate is available, work as if we're running in
4618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      // release mode.
4628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      return IsSupported(f);
4638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
4648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    uint64_t enabled = isolate->enabled_cpu_features();
4658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return (enabled & (V8_UINT64_C(1) << f)) != 0;
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#endif
4688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Enable a specified feature within a scope.
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  class Scope BASE_EMBEDDED {
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   public:
4738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    explicit Scope(CpuFeature f) {
4748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      uint64_t mask = V8_UINT64_C(1) << f;
4758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      ASSERT(CpuFeatures::IsSupported(f));
47644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      ASSERT(!Serializer::enabled() ||
4778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch             (CpuFeatures::found_by_runtime_probing_ & mask) == 0);
4788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      isolate_ = Isolate::UncheckedCurrent();
4798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      old_enabled_ = 0;
4808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      if (isolate_ != NULL) {
4818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        old_enabled_ = isolate_->enabled_cpu_features();
4828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        isolate_->set_enabled_cpu_features(old_enabled_ | mask);
4838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      }
48444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
48544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ~Scope() {
4868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      ASSERT_EQ(Isolate::UncheckedCurrent(), isolate_);
4878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      if (isolate_ != NULL) {
4888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        isolate_->set_enabled_cpu_features(old_enabled_);
4898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      }
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   private:
49244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Isolate* isolate_;
4938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    uint64_t old_enabled_;
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   public:
496d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    explicit Scope(CpuFeature f) {}
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
49944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch private:
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Safe defaults include SSE2 and CMOV for X64. It is always available, if
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // anyone checks, but they shouldn't need to check.
50344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // The required user mode extensions in X64 are (from AMD64 ABI Table A.1):
50444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  //   fpu, tsc, cx8, cmov, mmx, sse, sse2, fxsr, syscall
505d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static const uint64_t kDefaultCpuFeatures = (1 << SSE2 | 1 << CMOV);
50644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#ifdef DEBUG
5088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static bool initialized_;
5098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#endif
5108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static uint64_t supported_;
5118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static uint64_t found_by_runtime_probing_;
51244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
51344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
51744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Assembler : public AssemblerBase {
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // We check before assembling an instruction that there is sufficient
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // space to write an instruction and its relocation information.
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The relocation writer's position must be kGap bytes above the end of
522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the generated instructions. This leaves enough space for the
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // longest possible x64 instruction, 15 bytes, and the longest possible
524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // (There is a 15 byte limit on x64 instruction length that rules out some
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // otherwise valid instructions.)
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This allows for a single, fast space check per instruction.
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kGap = 32;
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Create an assembler. Instructions and relocation information are emitted
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // into a buffer, with the instructions starting from the beginning and the
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // relocation information starting from the end of the buffer. See CodeDesc
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for a detailed comment on the layout (globals.h).
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the provided buffer is NULL, the assembler allocates and grows its own
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // buffer, and buffer_size determines the initial buffer size. The buffer is
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // owned by the assembler and deallocated upon destruction of the assembler.
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the provided buffer is not NULL, the assembler uses the provided buffer
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for code generation and assumes its size to be buffer_size. If the buffer
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is too small, a fatal error occurs. No deallocation of the buffer is done
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // upon destruction of the assembler.
5448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Assembler(Isolate* isolate, void* buffer, int buffer_size);
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ~Assembler();
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
54744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Overrides the default provided by FLAG_debug_code.
54844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void set_emit_debug_code(bool value) { emit_debug_code_ = value; }
54944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // GetCode emits any pending (non-emitted) code and fills the descriptor
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // desc. GetCode() is idempotent; it returns the same result if no other
552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Assembler functions are invoked in between GetCode() calls.
553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GetCode(CodeDesc* desc);
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Read/Modify the code target in the relative branch/call instruction at pc.
5563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // On the x64 architecture, we use relative jumps with a 32-bit displacement
5573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // to jump to other Code objects in the Code space in the heap.
5583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Jumps to C functions are done indirectly through a 64-bit register holding
5593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // the absolute address of the target.
5603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // These functions convert between absolute Addresses of Code objects and
5613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // the relative displacements stored in the code.
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Address target_address_at(Address pc);
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline void set_target_address_at(Address pc, Address target);
564d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
565d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // This sets the branch destination (which is in the instruction on x64).
566d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // This is for calls and branches within generated code.
567d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  inline static void set_target_at(Address instruction_payload,
568d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                   Address target) {
569d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    set_target_address_at(instruction_payload, target);
570d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
571d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
572d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // This sets the branch destination (which is a load instruction on x64).
573d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // This is for calls and branches to runtime code.
574d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  inline static void set_external_target_at(Address instruction_payload,
575d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                            Address target) {
576d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    *reinterpret_cast<Address*>(instruction_payload) = target;
577d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
578d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
5793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline Handle<Object> code_target_object_handle_at(Address pc);
580d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Number of bytes taken up by the branch target in the code.
581d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static const int kCallTargetSize = 4;      // Use 32-bit displacement.
582d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static const int kExternalTargetSize = 8;  // Use 64-bit absolute.
583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Distance between the address of the code target in the call instruction
5843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // and the return address pushed on the stack.
5853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static const int kCallTargetAddressOffset = 4;  // Use 32-bit displacement.
5863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Distance between the start of the JS return sequence and where the
5873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // 32-bit displacement of a near call would be, relative to the pushed
5883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // return address.  TODO: Use return sequence length instead.
5893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset;
5903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static const int kPatchReturnSequenceAddressOffset = 13 - 4;
5917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Distance between start of patched debug break slot and where the
5927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // 32-bit displacement of a near call would be, relative to the pushed
5937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // return address.  TODO: Use return sequence length instead.
5947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset;
5957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kPatchDebugBreakSlotAddressOffset = 13 - 4;
5963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // TODO(X64): Rename this, removing the "Real", after changing the above.
5973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static const int kRealPatchReturnSequenceAddressOffset = 2;
598d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
5991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Some x64 JS code is padded with int3 to make it large
6001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // enough to hold an instruction when the debugger patches it.
6011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kJumpInstructionLength = 13;
602d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static const int kCallInstructionLength = 13;
603d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static const int kJSReturnSequenceLength = 13;
6041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kShortCallInstructionLength = 5;
605d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
6067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // The debug break slot must be able to contain a call instruction.
6077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kDebugBreakSlotLength = kCallInstructionLength;
6087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6099fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // One byte opcode for test eax,0xXXXXXXXX.
6109fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  static const byte kTestEaxByte = 0xA9;
6111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // One byte opcode for test al, 0xXX.
6121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kTestAlByte = 0xA8;
6131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // One byte opcode for nop.
6141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kNopByte = 0x90;
6151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // One byte prefix for a short conditional jump.
6171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kJccShortPrefix = 0x70;
6181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
6191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const byte kJcShortOpcode = kJccShortPrefix | carry;
6201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Code generation
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Function names correspond one-to-one to x64 instruction mnemonics.
627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Unless specified otherwise, instructions operate on 64-bit operands.
628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If we need versions of an assembly instruction that operate on different
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // width arguments, we add a single-letter suffix specifying the width.
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This is done for the following instructions: mov, cmp, inc, dec,
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // add, sub, and test.
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // There are no versions of these instructions without the suffix.
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - Instructions on 16-bit (word) operands/registers have a trailing 'w'.
636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - Instructions on 64-bit (quadword) operands/registers use 'q'.
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Some mnemonics, such as "and", are the same as C++ keywords.
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Naming conflicts with C++ keywords are resolved by adding a trailing '_'.
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Insert the smallest number of nop instructions
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // possible to align the pc offset to a multiple
6441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // of m, where m must be a power of 2.
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Align(int m);
6469dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Aligns code to something that's optimal for a jump target for the platform.
6479dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  void CodeTargetAlign();
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Stack
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void pushfq();
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void popfq();
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void push(Immediate value);
6541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Push a 32 bit integer, and guarantee that it is actually pushed as a
6551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // 32 bit value, the normal push will optimize the 8 bit case.
6561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void push_imm32(int32_t imm32);
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void push(Register src);
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void push(const Operand& src);
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void pop(Register dst);
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void pop(const Operand& dst);
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void enter(Immediate size);
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void leave();
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Moves
667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movb(Register dst, const Operand& src);
668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movb(Register dst, Immediate imm);
669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movb(const Operand& dst, Register src);
670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Move the low 16 bits of a 64-bit register value to a 16-bit
6723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // memory location.
6733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void movw(const Operand& dst, Register src);
6743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movl(Register dst, Register src);
676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movl(Register dst, const Operand& src);
677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movl(const Operand& dst, Register src);
678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movl(const Operand& dst, Immediate imm);
679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Load a 32-bit immediate value, zero-extended to 64 bits.
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movl(Register dst, Immediate imm32);
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Move 64 bit register value to 64-bit memory location.
683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movq(const Operand& dst, Register src);
684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Move 64 bit memory location to 64-bit register value.
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movq(Register dst, const Operand& src);
686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movq(Register dst, Register src);
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sign extends immediate 32-bit value to 64 bits.
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movq(Register dst, Immediate x);
689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Move the offset of the label location relative to the current
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // position (after the move) to the destination.
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movl(const Operand& dst, Label* src);
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Move sign extended immediate to memory location.
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movq(const Operand& dst, Immediate value);
69544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Instructions to load a 64-bit immediate into a register.
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // All 64-bit immediates must have a relocation mode.
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movq(Register dst, void* ptr, RelocInfo::Mode rmode);
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movq(Register dst, int64_t value, RelocInfo::Mode rmode);
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movq(Register dst, const char* s, RelocInfo::Mode rmode);
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Moves the address of the external reference into the register.
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movq(Register dst, ExternalReference ext);
702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode);
703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void movsxbq(Register dst, const Operand& src);
7053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void movsxwq(Register dst, const Operand& src);
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movsxlq(Register dst, Register src);
707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movsxlq(Register dst, const Operand& src);
708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movzxbq(Register dst, const Operand& src);
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movzxbl(Register dst, const Operand& src);
7103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void movzxwq(Register dst, const Operand& src);
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void movzxwl(Register dst, const Operand& src);
712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
713d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Repeated moves.
714d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
715d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void repmovsb();
716d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void repmovsw();
717d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void repmovsl();
718d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void repmovsq();
719d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
72044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Instruction to load from an immediate 64-bit pointer into RAX.
721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void load_rax(void* ptr, RelocInfo::Mode rmode);
722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void load_rax(ExternalReference ext);
723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Conditional moves.
725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmovq(Condition cc, Register dst, Register src);
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmovq(Condition cc, Register dst, const Operand& src);
727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmovl(Condition cc, Register dst, Register src);
728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmovl(Condition cc, Register dst, const Operand& src);
729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Exchange two registers
731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void xchg(Register dst, Register src);
732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Arithmetics
734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void addl(Register dst, Register src) {
735f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    arithmetic_op_32(0x03, dst, src);
736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void addl(Register dst, Immediate src) {
739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_32(0x0, dst, src);
740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void addl(Register dst, const Operand& src) {
743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_32(0x03, dst, src);
744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void addl(const Operand& dst, Immediate src) {
747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_32(0x0, dst, src);
748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void addq(Register dst, Register src) {
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x03, dst, src);
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void addq(Register dst, const Operand& src) {
755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x03, dst, src);
756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void addq(const Operand& dst, Register src) {
759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x01, src, dst);
760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void addq(Register dst, Immediate src) {
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op(0x0, dst, src);
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void addq(const Operand& dst, Immediate src) {
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op(0x0, dst, src);
768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
77025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  void sbbl(Register dst, Register src) {
771f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    arithmetic_op_32(0x1b, dst, src);
77225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  }
77325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
7741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void sbbq(Register dst, Register src) {
7751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    arithmetic_op(0x1b, dst, src);
7761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
7771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(Register dst, Immediate src) {
779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_8(0x7, dst, src);
780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb_al(Immediate src);
783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(Register dst, Register src) {
785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x3A, dst, src);
786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(Register dst, const Operand& src) {
789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x3A, dst, src);
790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(const Operand& dst, Register src) {
793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x38, src, dst);
794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpb(const Operand& dst, Immediate src) {
797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_8(0x7, dst, src);
798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(const Operand& dst, Immediate src) {
801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_16(0x7, dst, src);
802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(Register dst, Immediate src) {
805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_16(0x7, dst, src);
806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(Register dst, const Operand& src) {
809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_16(0x3B, dst, src);
810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(Register dst, Register src) {
813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_16(0x3B, dst, src);
814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpw(const Operand& dst, Register src) {
817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_16(0x39, src, dst);
818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpl(Register dst, Register src) {
821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_32(0x3B, dst, src);
822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpl(Register dst, const Operand& src) {
825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_32(0x3B, dst, src);
826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpl(const Operand& dst, Register src) {
829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_32(0x39, src, dst);
830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpl(Register dst, Immediate src) {
833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_32(0x7, dst, src);
834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpl(const Operand& dst, Immediate src) {
837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_32(0x7, dst, src);
838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpq(Register dst, Register src) {
841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x3B, dst, src);
842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpq(Register dst, const Operand& src) {
845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x3B, dst, src);
846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpq(const Operand& dst, Register src) {
849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x39, src, dst);
850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpq(Register dst, Immediate src) {
853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op(0x7, dst, src);
854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cmpq(const Operand& dst, Immediate src) {
857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op(0x7, dst, src);
858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void and_(Register dst, Register src) {
861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x23, dst, src);
862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void and_(Register dst, const Operand& src) {
865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x23, dst, src);
866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void and_(const Operand& dst, Register src) {
869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x21, src, dst);
870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void and_(Register dst, Immediate src) {
873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op(0x4, dst, src);
874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void and_(const Operand& dst, Immediate src) {
877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op(0x4, dst, src);
878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void andl(Register dst, Immediate src) {
881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_32(0x4, dst, src);
882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void andl(Register dst, Register src) {
8853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    arithmetic_op_32(0x23, dst, src);
8863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
8873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
8881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void andl(Register dst, const Operand& src) {
8891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    arithmetic_op_32(0x23, dst, src);
8901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
8911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
8924515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  void andb(Register dst, Immediate src) {
8934515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke    immediate_arithmetic_op_8(0x4, dst, src);
8944515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  }
8953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void decq(Register dst);
897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void decq(const Operand& dst);
898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void decl(Register dst);
899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void decl(const Operand& dst);
9003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void decb(Register dst);
9013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void decb(const Operand& dst);
902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sign-extends rax into rdx:rax.
904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cqo();
905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sign-extends eax into edx:eax.
906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cdq();
907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Divide rdx:rax by src.  Quotient in rax, remainder in rdx.
909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void idivq(Register src);
910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Divide edx:eax by lower 32 bits of src.  Quotient in eax, rem. in edx.
911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void idivl(Register src);
912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Signed multiply instructions.
914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void imul(Register src);                               // rdx:rax = rax * src.
915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void imul(Register dst, Register src);                 // dst = dst * src.
916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void imul(Register dst, const Operand& src);           // dst = dst * src.
917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void imul(Register dst, Register src, Immediate imm);  // dst = src * imm.
9186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Signed 32-bit multiply instructions.
9196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void imull(Register dst, Register src);                 // dst = dst * src.
9201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void imull(Register dst, const Operand& src);           // dst = dst * src.
9216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void imull(Register dst, Register src, Immediate imm);  // dst = src * imm.
922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void incq(Register dst);
924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void incq(const Operand& dst);
9259dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  void incl(Register dst);
926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void incl(const Operand& dst);
927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void lea(Register dst, const Operand& src);
9296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void leal(Register dst, const Operand& src);
930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Multiply rax by src, put the result in rdx:rax.
932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void mul(Register src);
933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void neg(Register dst);
935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void neg(const Operand& dst);
936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void negl(Register dst);
937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void not_(Register dst);
939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void not_(const Operand& dst);
9406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void notl(Register dst);
941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void or_(Register dst, Register src) {
943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x0B, dst, src);
944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void orl(Register dst, Register src) {
947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_32(0x0B, dst, src);
948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void or_(Register dst, const Operand& src) {
951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x0B, dst, src);
952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void orl(Register dst, const Operand& src) {
9551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    arithmetic_op_32(0x0B, dst, src);
9561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
9571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void or_(const Operand& dst, Register src) {
959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x09, src, dst);
960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void or_(Register dst, Immediate src) {
963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op(0x1, dst, src);
964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void orl(Register dst, Immediate src) {
9673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    immediate_arithmetic_op_32(0x1, dst, src);
9683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
9693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void or_(const Operand& dst, Immediate src) {
971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op(0x1, dst, src);
972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void orl(const Operand& dst, Immediate src) {
9753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    immediate_arithmetic_op_32(0x1, dst, src);
9763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
9773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void rcl(Register dst, Immediate imm8) {
9803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    shift(dst, imm8, 0x2);
9813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
9823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
9833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void rol(Register dst, Immediate imm8) {
9843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    shift(dst, imm8, 0x0);
9853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
9863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
9873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void rcr(Register dst, Immediate imm8) {
9883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    shift(dst, imm8, 0x3);
9893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
9903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
9913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void ror(Register dst, Immediate imm8) {
9923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    shift(dst, imm8, 0x1);
9933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifts dst:src left by cl bits, affecting only dst.
996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shld(Register dst, Register src);
997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifts src:dst right by cl bits, affecting only dst.
999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shrd(Register dst, Register src);
1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifts dst right, duplicating sign bit, by shift_amount bits.
1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifting by 1 is handled efficiently.
1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void sar(Register dst, Immediate shift_amount) {
1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    shift(dst, shift_amount, 0x7);
1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifts dst right, duplicating sign bit, by shift_amount bits.
1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifting by 1 is handled efficiently.
1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void sarl(Register dst, Immediate shift_amount) {
1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    shift_32(dst, shift_amount, 0x7);
1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifts dst right, duplicating sign bit, by cl % 64 bits.
1014d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void sar_cl(Register dst) {
1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    shift(dst, 0x7);
1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifts dst right, duplicating sign bit, by cl % 64 bits.
1019d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void sarl_cl(Register dst) {
1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    shift_32(dst, 0x7);
1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shl(Register dst, Immediate shift_amount) {
1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    shift(dst, shift_amount, 0x4);
1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1027d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void shl_cl(Register dst) {
1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    shift(dst, 0x4);
1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1031d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void shll_cl(Register dst) {
1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    shift_32(dst, 0x4);
1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shll(Register dst, Immediate shift_amount) {
1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    shift_32(dst, shift_amount, 0x4);
1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shr(Register dst, Immediate shift_amount) {
1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    shift(dst, shift_amount, 0x5);
1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1043d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void shr_cl(Register dst) {
1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    shift(dst, 0x5);
1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1047d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void shrl_cl(Register dst) {
1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    shift_32(dst, 0x5);
1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shrl(Register dst, Immediate shift_amount) {
1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    shift_32(dst, shift_amount, 0x5);
1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void store_rax(void* dst, RelocInfo::Mode mode);
1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void store_rax(ExternalReference ref);
1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subq(Register dst, Register src) {
1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x2B, dst, src);
1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subq(Register dst, const Operand& src) {
1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x2B, dst, src);
1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subq(const Operand& dst, Register src) {
1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x29, src, dst);
1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subq(Register dst, Immediate src) {
1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op(0x5, dst, src);
1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subq(const Operand& dst, Immediate src) {
1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op(0x5, dst, src);
1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subl(Register dst, Register src) {
1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_32(0x2B, dst, src);
1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1082e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void subl(Register dst, const Operand& src) {
1083e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    arithmetic_op_32(0x2B, dst, src);
1084e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
1085e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subl(const Operand& dst, Immediate src) {
1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_32(0x5, dst, src);
1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subl(Register dst, Immediate src) {
1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_32(0x5, dst, src);
1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subb(Register dst, Immediate src) {
1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op_8(0x5, dst, src);
1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void testb(Register dst, Register src);
1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void testb(Register reg, Immediate mask);
1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void testb(const Operand& op, Immediate mask);
1101e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void testb(const Operand& op, Register reg);
1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void testl(Register dst, Register src);
1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void testl(Register reg, Immediate mask);
1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void testl(const Operand& op, Immediate mask);
1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void testq(const Operand& op, Register reg);
1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void testq(Register dst, Register src);
1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void testq(Register dst, Immediate mask);
1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void xor_(Register dst, Register src) {
1110d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    if (dst.code() == src.code()) {
1111d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      arithmetic_op_32(0x33, dst, src);
1112d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    } else {
1113d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      arithmetic_op(0x33, dst, src);
1114d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void xorl(Register dst, Register src) {
1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op_32(0x33, dst, src);
1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void xorl(Register dst, const Operand& src) {
11221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    arithmetic_op_32(0x33, dst, src);
11231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
11241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
11251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void xorl(Register dst, Immediate src) {
11261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    immediate_arithmetic_op_32(0x6, dst, src);
11271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
11281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
11291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void xorl(const Operand& dst, Immediate src) {
11301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    immediate_arithmetic_op_32(0x6, dst, src);
11311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
11321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void xor_(Register dst, const Operand& src) {
1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x33, dst, src);
1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void xor_(const Operand& dst, Register src) {
1138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arithmetic_op(0x31, src, dst);
1139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void xor_(Register dst, Immediate src) {
1142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op(0x6, dst, src);
1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void xor_(const Operand& dst, Immediate src) {
1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    immediate_arithmetic_op(0x6, dst, src);
1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bit operations.
1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void bt(const Operand& dst, Register src);
1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void bts(const Operand& dst, Register src);
1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Miscellaneous
11543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void clc();
115544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void cld();
1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cpuid();
1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void hlt();
1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void int3();
1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void nop();
1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void nop(int n);
1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void rdtsc();
1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ret(int imm16);
1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void setcc(Condition cc, Register reg);
1164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Label operations & relative jumps (PPUM Appendix D)
1166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
1167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Takes a branch opcode (cc) and a label (L) and generates
1168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // either a backward branch or a forward branch and links it
1169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to the label fixup chain. Usage:
1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Label L;    // unbound label
1172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // j(cc, &L);  // forward branch to unbound label
1173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // bind(&L);   // bind label to the current pc
1174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // j(cc, &L);  // backward branch to bound label
1175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // bind(&L);   // illegal: a label may be bound only once
1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Note: The same Label can be used for forward and backward branches
1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // but it may be bound only once.
1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void bind(Label* L);  // binds an unbound label L to the current code position
11810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void bind(NearLabel* L);
1182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Calls
1184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call near relative 32-bit displacement, relative to next instruction.
1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void call(Label* L);
11863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void call(Handle<Code> target, RelocInfo::Mode rmode);
1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Calls directly to the given address using a relative offset.
11891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Should only ever be used in Code objects for calls within the
11901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // same Code object. Should not be used when generating new code (use labels),
11911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // but only when patching existing code.
11921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void call(Address target);
11931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call near absolute indirect, address in register
1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void call(Register adr);
1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call near indirect
1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void call(const Operand& operand);
1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jumps
1201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump short or near relative.
12023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Use a 32-bit signed displacement.
1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void jmp(Label* L);  // unconditional jump to L
12043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void jmp(Handle<Code> target, RelocInfo::Mode rmode);
1205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump near absolute indirect (r64)
1207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void jmp(Register adr);
1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump near absolute indirect (m64)
1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void jmp(const Operand& src);
1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Short jump
12130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void jmp(NearLabel* L);
12140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
1215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Conditional jumps
1216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void j(Condition cc, Label* L);
12173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Conditional short jump
12200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void j(Condition cc, NearLabel* L, Hint hint = no_hint);
12210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Floating-point operations
1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fld(int i);
1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fld1();
1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fldz();
12276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void fldpi();
1228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void fldln2();
1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fld_s(const Operand& adr);
1231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fld_d(const Operand& adr);
1232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fstp_s(const Operand& adr);
1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fstp_d(const Operand& adr);
12353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void fstp(int index);
1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fild_s(const Operand& adr);
1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fild_d(const Operand& adr);
1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fist_s(const Operand& adr);
1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fistp_s(const Operand& adr);
1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fistp_d(const Operand& adr);
1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fisttp_s(const Operand& adr);
1246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void fisttp_d(const Operand& adr);
1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fabs();
1249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fchs();
1250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fadd(int i);
1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fsub(int i);
1253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fmul(int i);
1254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fdiv(int i);
1255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fisub_s(const Operand& adr);
1257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void faddp(int i = 1);
1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fsubp(int i = 1);
1260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fsubrp(int i = 1);
1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fmulp(int i = 1);
1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fdivp(int i = 1);
1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fprem();
1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fprem1();
1265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fxch(int i = 1);
1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fincstp();
1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ffree(int i = 0);
1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ftst();
1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fucomp(int i);
1272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fucompp();
12733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void fucomi(int i);
12743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void fucomip();
12753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fcompp();
1277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fnstsw_ax();
1278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fwait();
1279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fnclex();
1280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fsin();
1282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void fcos();
1283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void fyl2x();
1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void frndint();
1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void sahf();
1288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // SSE2 instructions
12906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movd(XMMRegister dst, Register src);
12916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movd(Register dst, XMMRegister src);
12926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movq(XMMRegister dst, Register src);
12936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movq(Register dst, XMMRegister src);
12946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void extractps(Register dst, XMMRegister src, byte imm8);
12956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
12968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  void movsd(const Operand& dst, XMMRegister src);
1297053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  void movsd(XMMRegister dst, XMMRegister src);
12986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void movsd(XMMRegister dst, const Operand& src);
1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void movdqa(const Operand& dst, XMMRegister src);
13011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void movdqa(XMMRegister dst, const Operand& src);
13021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
13038defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void movss(XMMRegister dst, const Operand& src);
13048defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void movss(const Operand& dst, XMMRegister src);
13058defd9ff6930b4e24729971a61cf7469daf119beSteve Block
1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvttss2si(Register dst, const Operand& src);
13071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void cvttss2si(Register dst, XMMRegister src);
1308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvttsd2si(Register dst, const Operand& src);
13091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void cvttsd2si(Register dst, XMMRegister src);
131025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  void cvttsd2siq(Register dst, XMMRegister src);
1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvtlsi2sd(XMMRegister dst, const Operand& src);
1313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvtlsi2sd(XMMRegister dst, Register src);
1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvtqsi2sd(XMMRegister dst, const Operand& src);
1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void cvtqsi2sd(XMMRegister dst, Register src);
1316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13178defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void cvtlsi2ss(XMMRegister dst, Register src);
13188defd9ff6930b4e24729971a61cf7469daf119beSteve Block
13196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void cvtss2sd(XMMRegister dst, XMMRegister src);
13208defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void cvtss2sd(XMMRegister dst, const Operand& src);
13218defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void cvtsd2ss(XMMRegister dst, XMMRegister src);
13228defd9ff6930b4e24729971a61cf7469daf119beSteve Block
13238defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void cvtsd2si(Register dst, XMMRegister src);
13248defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void cvtsd2siq(Register dst, XMMRegister src);
13256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void addsd(XMMRegister dst, XMMRegister src);
1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void subsd(XMMRegister dst, XMMRegister src);
1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void mulsd(XMMRegister dst, XMMRegister src);
1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void divsd(XMMRegister dst, XMMRegister src);
1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1331e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void andpd(XMMRegister dst, XMMRegister src);
1332e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void orpd(XMMRegister dst, XMMRegister src);
1333402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void xorpd(XMMRegister dst, XMMRegister src);
13346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void sqrtsd(XMMRegister dst, XMMRegister src);
1335402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1336402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void ucomisd(XMMRegister dst, XMMRegister src);
13378defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void ucomisd(XMMRegister dst, const Operand& src);
1338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void movmskpd(Register dst, XMMRegister src);
13401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
13416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // The first argument is the reg field, the second argument is the r/m field.
1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_sse_operand(XMMRegister dst, XMMRegister src);
1343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_sse_operand(XMMRegister reg, const Operand& adr);
1344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_sse_operand(XMMRegister dst, Register src);
13456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void emit_sse_operand(Register dst, XMMRegister src);
1346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Debugging
1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Print();
1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check the code size generated from label to here.
1351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); }
1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Mark address of the ExitJSFrame code.
1354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void RecordJSReturn();
1355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Mark address of a debug break slot.
13577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void RecordDebugBreakSlot();
13587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Record a comment relocation entry that can be used by a disassembler.
1360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Use --code-comments to enable.
1361e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void RecordComment(const char* msg, bool force = false);
1362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Writes a single word of data in the code stream.
1364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Used for inline tables, e.g., jump-tables.
1365b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void db(uint8_t data);
1366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void dd(uint32_t data);
1367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
13680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int pc_offset() const { return static_cast<int>(pc_ - buffer_); }
13693e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
13703e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  PositionsRecorder* positions_recorder() { return &positions_recorder_; }
1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if there is less than kGap bytes available in the buffer.
1373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If this is the case, we need to grow the buffer before emitting
1374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // an instruction or relocation information.
1375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool buffer_overflow() const {
1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return pc_ >= reloc_info_writer.pos() - kGap;
1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the number of bytes available in the buffer.
1380d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  inline int available_space() const {
1381d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    return static_cast<int>(reloc_info_writer.pos() - pc_);
1382d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
1383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static bool IsNop(Address addr) { return *addr == 0x90; }
13857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Avoid overflows for displacements etc.
1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaximalBufferSize = 512*MB;
1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMinimalBufferSize = 4*KB;
1389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
139044f0eee88ff00398ff7f715fab053374d808c90dSteve Block protected:
139144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool emit_debug_code() const { return emit_debug_code_; }
139244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* addr_at(int pos)  { return buffer_ + pos; }
1395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte byte_at(int pos)  { return buffer_[pos]; }
13960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
1397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uint32_t long_at(int pos)  {
1398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return *reinterpret_cast<uint32_t*>(addr_at(pos));
1399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void long_at_put(int pos, uint32_t x)  {
1401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
1402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // code emission
1405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GrowBuffer();
1406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit(byte x) { *pc_++ = x; }
1408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emitl(uint32_t x);
1409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emitq(uint64_t x, RelocInfo::Mode rmode);
1410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emitw(uint16_t x);
14113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline void emit_code_target(Handle<Code> target, RelocInfo::Mode rmode);
1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit(Immediate x) { emitl(x.value_); }
1413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a REX prefix that encodes a 64-bit operand size and
1415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the top bit of both register codes.
1416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is set.
1418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(XMMRegister reg, Register rm_reg);
14196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void emit_rex_64(Register reg, XMMRegister rm_reg);
14206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void emit_rex_64(Register reg, Register rm_reg);
1421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a REX prefix that encodes a 64-bit operand size and
1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the top bit of the destination, index, and base register codes.
1424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of reg is used for REX.R, the high bit of op's base
1425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register is used for REX.B, and the high bit of op's index register
1426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is used for REX.X.  REX.W is set.
1427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(Register reg, const Operand& op);
1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(XMMRegister reg, const Operand& op);
1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a REX prefix that encodes a 64-bit operand size and
1431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the top bit of the register code.
1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of register is used for REX.B.
1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is set and REX.R and REX.X are clear.
1434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(Register rm_reg);
1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a REX prefix that encodes a 64-bit operand size and
1437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the top bit of the index and base register codes.
1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of op's base register is used for REX.B, and the high
1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // bit of op's index register is used for REX.X.
1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is set and REX.R clear.
1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_64(const Operand& op);
1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size.
1444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_rex_64() { emit(0x48); }
1445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is clear.
1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_32(Register reg, Register rm_reg);
1449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of reg is used for REX.R, the high bit of op's base
1451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register is used for REX.B, and the high bit of op's index register
1452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is used for REX.X.  REX.W is cleared.
1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_32(Register reg, const Operand& op);
1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of rm_reg goes to REX.B.
1456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W, REX.R and REX.X are clear.
1457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_32(Register rm_reg);
1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of base goes to REX.B and high bit of index to REX.X.
1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W and REX.R are clear.
1461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_rex_32(const Operand& op);
1462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.W is cleared.  If no REX bits are set, no byte is emitted.
1465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(Register reg, Register rm_reg);
1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The high bit of reg is used for REX.R, the high bit of op's base
1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register is used for REX.B, and the high bit of op's index register
1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is used for REX.X.  REX.W is cleared.  If no REX bits are set, nothing
1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is emitted.
1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(Register reg, const Operand& op);
1472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // As for emit_optional_rex_32(Register, Register), except that
1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the registers are XMM registers.
1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base);
1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // As for emit_optional_rex_32(Register, Register), except that
14786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // one of the registers is an XMM registers.
1479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(XMMRegister reg, Register base);
1480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // As for emit_optional_rex_32(Register, Register), except that
14826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // one of the registers is an XMM registers.
14836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void emit_optional_rex_32(Register reg, XMMRegister base);
14846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // As for emit_optional_rex_32(Register, const Operand&), except that
1486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the register is an XMM register.
1487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(XMMRegister reg, const Operand& op);
1488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Optionally do as emit_rex_32(Register) if the register number has
1490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the high bit set.
1491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(Register rm_reg);
1492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Optionally do as emit_rex_32(const Operand&) if the operand register
1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // numbers have a high bit set.
1495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_optional_rex_32(const Operand& op);
1496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit the ModR/M byte, and optionally the SIB byte and
1499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // 1- or 4-byte offset for a memory operand.  Also encodes
1500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the second operand of the operation, a register or operation
1501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // subcode, into the reg field of the ModR/M byte.
1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_operand(Register reg, const Operand& adr) {
1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit_operand(reg.low_bits(), adr);
1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit the ModR/M byte, and optionally the SIB byte and
1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // 1- or 4-byte offset for a memory operand.  Also used to encode
1508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a three-bit opcode extension into the ModR/M byte.
1509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_operand(int rm, const Operand& adr);
1510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
1512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_modrm(Register reg, Register rm_reg) {
1513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
1514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit a ModR/M byte with an operation subcode in the reg field and
1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a register in the rm_reg field.
1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_modrm(int code, Register rm_reg) {
1519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(is_uint3(code));
1520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit(0xC0 | code << 3 | rm_reg.low_bits());
1521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit the code-object-relative offset of the label's position
1524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void emit_code_relative_offset(Label* label);
1525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit machine code for one of the operations ADD, ADC, SUB, SBC,
1527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // AND, OR, XOR, or CMP.  The encodings of these operations are all
1528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // similar, differing just in the opcode or in the reg field of the
1529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ModR/M byte.
1530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
1531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
1532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void arithmetic_op_32(byte opcode, Register reg, Register rm_reg);
1533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void arithmetic_op_32(byte opcode, Register reg, const Operand& rm_reg);
1534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void arithmetic_op(byte opcode, Register reg, Register rm_reg);
1535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void arithmetic_op(byte opcode, Register reg, const Operand& rm_reg);
1536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op(byte subcode, Register dst, Immediate src);
1537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);
1538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Operate on a byte in memory or register.
1539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_8(byte subcode,
1540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Register dst,
1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Immediate src);
1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_8(byte subcode,
1543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 const Operand& dst,
1544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Immediate src);
1545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Operate on a word in memory or register.
1546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_16(byte subcode,
1547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Register dst,
1548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Immediate src);
1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_16(byte subcode,
1550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  const Operand& dst,
1551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Immediate src);
1552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Operate on a 32-bit word in memory or register.
1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_32(byte subcode,
1554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Register dst,
1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Immediate src);
1556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void immediate_arithmetic_op_32(byte subcode,
1557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  const Operand& dst,
1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Immediate src);
1559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit machine code for a shift operation.
1561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shift(Register dst, Immediate shift_amount, int subcode);
1562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shift_32(Register dst, Immediate shift_amount, int subcode);
1563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shift dst by cl % 64 bits.
1564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shift(Register dst, int subcode);
1565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void shift_32(Register dst, int subcode);
1566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void emit_farith(int b1, int b2, int i);
1568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // labels
1570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // void print(Label* L);
1571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void bind_to(Label* L, int pos);
1572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // record reloc info for current pc_
1574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class CodePatcher;
1577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class EnsureSpace;
1578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class RegExpMacroAssemblerX64;
1579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Code buffer:
1581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The buffer into which code and relocation info are generated.
1582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* buffer_;
1583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int buffer_size_;
1584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // True if the assembler owns the buffer, false if buffer is external.
1585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool own_buffer_;
1586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // code generation
1588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* pc_;  // the program counter; moves forward
1589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RelocInfoWriter reloc_info_writer;
1590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
15913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  List< Handle<Code> > code_targets_;
1592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
15933e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  PositionsRecorder positions_recorder_;
159444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
159544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool emit_debug_code_;
159644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
15973e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  friend class PositionsRecorder;
1598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper class that ensures that there is enough space for generating
1602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instructions and relocation information.  The constructor makes
1603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// sure that there is enough space and (in debug mode) the destructor
1604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// checks that we did not generate too much.
1605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EnsureSpace BASE_EMBEDDED {
1606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
1608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
1609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
1610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    space_before_ = assembler_->available_space();
1611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
1615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ~EnsureSpace() {
1616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int bytes_generated = space_before_ - assembler_->available_space();
1617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(bytes_generated < assembler_->kGap);
1618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Assembler* assembler_;
1623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
1624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int space_before_;
1625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
1629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_X64_ASSEMBLER_X64_H_
1631