143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Copyright (c) 1994-2006 Sun Microsystems Inc.
243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// All Rights Reserved.
343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met:
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// - Redistributions of source code must retain the above copyright notice,
943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// this list of conditions and the following disclaimer.
1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// - Redistribution in binary form must reproduce the above copyright
1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// notice, this list of conditions and the following disclaimer in the
1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// documentation and/or other materials provided with the distribution.
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// - Neither the name of Sun Microsystems or the names of contributors may
1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// be used to endorse or promote products derived from this software without
1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// specific prior written permission.
1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The original source code covered by the above license above has been
3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modified significantly by Google Inc.
33496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org// Copyright 2011 the V8 project authors. All rights reserved.
3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A light-weight IA32 Assembler.
3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
375ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#ifndef V8_IA32_ASSEMBLER_IA32_H_
385ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#define V8_IA32_ASSEMBLER_IA32_H_
3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
40196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate.h"
41196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/serialize.h"
42c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
4371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
4471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// CPU Registers.
4743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
4843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1) We would prefer to use an enum, but enum values are assignment-
4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// compatible with int, which has caused code-generation bugs.
5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
5143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 2) We would prefer to use a class instead of a struct but we don't like
5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the register initialization to depend on the particular initialization
5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// order (which appears to be different on OS X, Linux, and Windows for the
5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// installed versions of C++ we tried). Using a struct permits C-style
5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "initialization". Also, the Register objects cannot be const as this
5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// forces initialization stubs in MSVC, making us dependent on initialization
5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// order.
5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 3) By not using an enum, we are possibly preventing the compiler from
6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// doing certain constant folds, which may significantly reduce the
6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// code generated for some assembly instructions (because they boil down
6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// to a few constants). If this is a problem, we could change the code
6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// such that we use an enum in optimized mode, and the struct in debug
6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// mode. This way we get the compile-time error checking in debug mode
6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and best performance in optimized code.
6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstruct Register {
68a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static const int kMaxNumAllocatableRegisters = 6;
69a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static int NumAllocatableRegisters() {
70a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return kMaxNumAllocatableRegisters;
71a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
72a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const int kNumRegisters = 8;
73a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
74496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static inline const char* AllocationIndexToString(int index);
75a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
76496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static inline int ToAllocationIndex(Register reg);
77a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
78496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static inline Register FromAllocationIndex(int index);
79a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
80a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static Register from_code(int code) {
81e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(code >= 0);
82e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(code < kNumRegisters);
83a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Register r = { code };
84a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return r;
85a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
86a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
874a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is(Register reg) const { return code_ == reg.code_; }
887be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  // eax, ebx, ecx and edx are byte registers, the rest are not.
894a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool is_byte_register() const { return code_ <= 3; }
904a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int code() const {
91e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return code_;
9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
944a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int bit() const {
95e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
9643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return 1 << code_;
9743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
9843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
995c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Unfortunately we can't make this private in a struct.
10043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int code_;
10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
10243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1031456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_eax_Code = 0;
1041456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_ecx_Code = 1;
1051456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_edx_Code = 2;
1061456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_ebx_Code = 3;
1071456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_esp_Code = 4;
1081456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_ebp_Code = 5;
1091456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_esi_Code = 6;
1101456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_edi_Code = 7;
1111456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_no_reg_Code = -1;
1121456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
1131456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register eax = { kRegister_eax_Code };
1141456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register ecx = { kRegister_ecx_Code };
1151456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register edx = { kRegister_edx_Code };
1161456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register ebx = { kRegister_ebx_Code };
1171456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register esp = { kRegister_esp_Code };
1181456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register ebp = { kRegister_ebp_Code };
1191456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register esi = { kRegister_esi_Code };
1201456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register edi = { kRegister_edi_Code };
1211456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register no_reg = { kRegister_no_reg_Code };
12243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
124496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orginline const char* Register::AllocationIndexToString(int index) {
125e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
126496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  // This is the mapping of allocation indices to registers.
127496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  const char* const kNames[] = { "eax", "ecx", "edx", "ebx", "esi", "edi" };
128496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return kNames[index];
129496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
130496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
131496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
132496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orginline int Register::ToAllocationIndex(Register reg) {
133e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(reg.is_valid() && !reg.is(esp) && !reg.is(ebp));
134496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return (reg.code() >= 6) ? reg.code() - 2 : reg.code();
135496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
136496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
137496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
138496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orginline Register Register::FromAllocationIndex(int index)  {
139e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
140496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  return (index >= 4) ? from_code(index + 2) : from_code(index);
141496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
142496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
143496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
1441e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgstruct XMMRegister {
145a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static const int kMaxNumAllocatableRegisters = 7;
1461e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org  static const int kMaxNumRegisters = 8;
1471e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org  static int NumAllocatableRegisters() {
1481e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org    return kMaxNumAllocatableRegisters;
1491e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org  }
15032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
1511e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org  static int ToAllocationIndex(XMMRegister reg) {
152e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(reg.code() != 0);
1535323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    return reg.code() - 1;
15432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  }
15532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
1561e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org  static XMMRegister FromAllocationIndex(int index) {
157e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
158a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return from_code(index + 1);
159a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
160a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1611e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org  static XMMRegister from_code(int code) {
1621e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org    XMMRegister result = { code };
163a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return result;
164a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
165a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
166a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool is_valid() const {
1671e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org    return 0 <= code_ && code_ < kMaxNumRegisters;
168a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
1691e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org
170a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int code() const {
171e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_valid());
172a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return code_;
173a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
174a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
175a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool is(XMMRegister reg) const { return code_ == reg.code_; }
176a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
177a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const char* AllocationIndexToString(int index) {
178e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    const char* const names[] = {
180a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm1",
181a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm2",
182a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm3",
183a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm4",
184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm5",
185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm6",
186a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm7"
187a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    };
188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return names[index];
189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1901e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org
1911e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org  int code_;
192a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org};
19332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
194a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1951e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgtypedef XMMRegister DoubleRegister;
1961e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org
1971e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org
1981e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgconst XMMRegister xmm0 = { 0 };
1991e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgconst XMMRegister xmm1 = { 1 };
2001e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgconst XMMRegister xmm2 = { 2 };
2011e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgconst XMMRegister xmm3 = { 3 };
2021e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgconst XMMRegister xmm4 = { 4 };
2031e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgconst XMMRegister xmm5 = { 5 };
2041e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgconst XMMRegister xmm6 = { 6 };
2051e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgconst XMMRegister xmm7 = { 7 };
2061e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.orgconst XMMRegister no_xmm_reg = { -1 };
207a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
208a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
20943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum Condition {
21043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // any value < 0 is considered no_condition
21143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  no_condition  = -1,
21243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
21343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  overflow      =  0,
21443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  no_overflow   =  1,
21543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  below         =  2,
21643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  above_equal   =  3,
21743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  equal         =  4,
21843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  not_equal     =  5,
21943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  below_equal   =  6,
22043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  above         =  7,
221a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  negative      =  8,
222a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  positive      =  9,
22343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  parity_even   = 10,
22443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  parity_odd    = 11,
22543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  less          = 12,
22643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  greater_equal = 13,
22743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  less_equal    = 14,
22843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  greater       = 15,
22943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
23043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // aliases
231a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  carry         = below,
232a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  not_carry     = above_equal,
23343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  zero          = equal,
23443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  not_zero      = not_equal,
235a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  sign          = negative,
236a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  not_sign      = positive
23743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
23843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
23943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns the equivalent of !cc.
24143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Negation of the default no_condition (-1) results in a non-default
24243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// no_condition value (-2). As long as tests for no_condition check
24343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// for condition < 0, this will work as expected.
2445ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orginline Condition NegateCondition(Condition cc) {
2455ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  return static_cast<Condition>(cc ^ 1);
2465ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
2475ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
24843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2491e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org// Commute a condition such that {a cond b == b cond' a}.
25038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orginline Condition CommuteCondition(Condition cc) {
25143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (cc) {
25243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case below:
25343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return above;
25443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case above:
25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return below;
25643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case above_equal:
25743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return below_equal;
25843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case below_equal:
25943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return above_equal;
26043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case less:
26143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return greater;
26243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case greater:
26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return less;
26443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case greater_equal:
26543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return less_equal;
26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case less_equal:
26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return greater_equal;
26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    default:
26943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return cc;
2703c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  }
27143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
27243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2735ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Machine instruction Immediates
27643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Immediate BASE_EMBEDDED {
27843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
27943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline explicit Immediate(int x);
28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline explicit Immediate(const ExternalReference& ext);
28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline explicit Immediate(Handle<Object> handle);
28243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline explicit Immediate(Smi* value);
283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  inline explicit Immediate(Address addr);
28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  static Immediate CodeRelativeOffset(Label* label) {
28637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    return Immediate(label);
28737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  }
28837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
28959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  bool is_zero() const { return x_ == 0 && RelocInfo::IsNone(rmode_); }
290236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  bool is_int8() const {
29159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return -128 <= x_ && x_ < 128 && RelocInfo::IsNone(rmode_);
292236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
293a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  bool is_int16() const {
29459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return -32768 <= x_ && x_ < 32768 && RelocInfo::IsNone(rmode_);
295a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
29837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  inline explicit Immediate(Label* value);
29937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
30043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int x_;
301236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  RelocInfo::Mode rmode_;
30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  friend class Operand;
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class Assembler;
3057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  friend class MacroAssembler;
30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Machine instruction Operands
31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum ScaleFactor {
31343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  times_1 = 0,
31443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  times_2 = 1,
31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  times_4 = 2,
316b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org  times_8 = 3,
317b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  times_int_size = times_4,
318b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  times_half_pointer_size = times_2,
3195c838251403b0be9a882540f1922577abba4c872ager@chromium.org  times_pointer_size = times_4,
3205c838251403b0be9a882540f1922577abba4c872ager@chromium.org  times_twice_pointer_size = times_8
32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Operand BASE_EMBEDDED {
32543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
3267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // reg
3277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  INLINE(explicit Operand(Register reg));
3287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
329086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // XMM reg
330086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  INLINE(explicit Operand(XMMRegister xmm_reg));
331086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [disp/r]
333236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  INLINE(explicit Operand(int32_t disp, RelocInfo::Mode rmode));
3347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // [disp/r]
3367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  INLINE(explicit Operand(Immediate imm));
33743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
33843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [base + disp/r]
339236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  explicit Operand(Register base, int32_t disp,
34059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                   RelocInfo::Mode rmode = RelocInfo::NONE32);
34143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [base + index*scale + disp/r]
34343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit Operand(Register base,
34443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                   Register index,
34543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                   ScaleFactor scale,
34643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                   int32_t disp,
34759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                   RelocInfo::Mode rmode = RelocInfo::NONE32);
34843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [index*scale + disp/r]
35043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit Operand(Register index,
35143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                   ScaleFactor scale,
35243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                   int32_t disp,
35359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                   RelocInfo::Mode rmode = RelocInfo::NONE32);
35443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
35543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static Operand StaticVariable(const ExternalReference& ext) {
35643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return Operand(reinterpret_cast<int32_t>(ext.address()),
357236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org                   RelocInfo::EXTERNAL_REFERENCE);
35843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
35943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
36043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static Operand StaticArray(Register index,
36143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                             ScaleFactor scale,
36243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                             const ExternalReference& arr) {
36343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()),
364236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org                   RelocInfo::EXTERNAL_REFERENCE);
36543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
36643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
36741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static Operand ForCell(Handle<Cell> cell) {
36879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    AllowDeferredHandleDereference embedding_raw_address;
369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return Operand(reinterpret_cast<int32_t>(cell.location()),
37041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                   RelocInfo::CELL);
371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static Operand ForRegisterPlusImmediate(Register base, Immediate imm) {
3747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return Operand(base, imm.x_, imm.rmode_);
3757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
3767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
37743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Returns true if this Operand is a wrapper for the specified register.
37843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool is_reg(Register reg) const;
37943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Returns true if this Operand is a wrapper for one register.
381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool is_reg_only() const;
382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Asserts that this Operand is a wrapper for one register and returns the
384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // register.
385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Register reg() const;
386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
38743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
388ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // Set the ModRM byte without an encoded 'reg' register. The
389ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // register is encoded later as part of the emit_operand operation.
390ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  inline void set_modrm(int mod, Register rm);
391ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
39243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void set_sib(ScaleFactor scale, Register index, Register base);
39343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void set_disp8(int8_t disp);
394236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  inline void set_dispr(int32_t disp, RelocInfo::Mode rmode);
39543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  byte buf_[6];
397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The number of bytes in buf_.
398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  unsigned int len_;
399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Only valid if len_ > 4.
400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  RelocInfo::Mode rmode_;
401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
40243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class Assembler;
403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  friend class MacroAssembler;
40443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
40543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
40643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4077276f14ca716596e0a0d17539516370c1f453847kasper.lund// -----------------------------------------------------------------------------
4087276f14ca716596e0a0d17539516370c1f453847kasper.lund// A Displacement describes the 32bit immediate field of an instruction which
4097276f14ca716596e0a0d17539516370c1f453847kasper.lund// may be used together with a Label in order to refer to a yet unknown code
4107276f14ca716596e0a0d17539516370c1f453847kasper.lund// position. Displacements stored in the instruction stream are used to describe
4117276f14ca716596e0a0d17539516370c1f453847kasper.lund// the instruction and to chain a list of instructions using the same Label.
4127276f14ca716596e0a0d17539516370c1f453847kasper.lund// A Displacement contains 2 different fields:
4137276f14ca716596e0a0d17539516370c1f453847kasper.lund//
4147276f14ca716596e0a0d17539516370c1f453847kasper.lund// next field: position of next displacement in the chain (0 = end of list)
4157276f14ca716596e0a0d17539516370c1f453847kasper.lund// type field: instruction type
4167276f14ca716596e0a0d17539516370c1f453847kasper.lund//
4177276f14ca716596e0a0d17539516370c1f453847kasper.lund// A next value of null (0) indicates the end of a chain (note that there can
4187276f14ca716596e0a0d17539516370c1f453847kasper.lund// be no displacement at position zero, because there is always at least one
4197276f14ca716596e0a0d17539516370c1f453847kasper.lund// instruction byte before the displacement).
4207276f14ca716596e0a0d17539516370c1f453847kasper.lund//
4217276f14ca716596e0a0d17539516370c1f453847kasper.lund// Displacement _data field layout
4227276f14ca716596e0a0d17539516370c1f453847kasper.lund//
423a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// |31.....2|1......0|
4247276f14ca716596e0a0d17539516370c1f453847kasper.lund// [  next  |  type  |
4257276f14ca716596e0a0d17539516370c1f453847kasper.lund
4267276f14ca716596e0a0d17539516370c1f453847kasper.lundclass Displacement BASE_EMBEDDED {
4277276f14ca716596e0a0d17539516370c1f453847kasper.lund public:
4287276f14ca716596e0a0d17539516370c1f453847kasper.lund  enum Type {
4297276f14ca716596e0a0d17539516370c1f453847kasper.lund    UNCONDITIONAL_JUMP,
430a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    CODE_RELATIVE,
4317276f14ca716596e0a0d17539516370c1f453847kasper.lund    OTHER
4327276f14ca716596e0a0d17539516370c1f453847kasper.lund  };
4337276f14ca716596e0a0d17539516370c1f453847kasper.lund
4347276f14ca716596e0a0d17539516370c1f453847kasper.lund  int data() const { return data_; }
4357276f14ca716596e0a0d17539516370c1f453847kasper.lund  Type type() const { return TypeField::decode(data_); }
4367276f14ca716596e0a0d17539516370c1f453847kasper.lund  void next(Label* L) const {
4377276f14ca716596e0a0d17539516370c1f453847kasper.lund    int n = NextField::decode(data_);
4387276f14ca716596e0a0d17539516370c1f453847kasper.lund    n > 0 ? L->link_to(n) : L->Unuse();
4397276f14ca716596e0a0d17539516370c1f453847kasper.lund  }
4407276f14ca716596e0a0d17539516370c1f453847kasper.lund  void link_to(Label* L) { init(L, type()); }
4417276f14ca716596e0a0d17539516370c1f453847kasper.lund
4427276f14ca716596e0a0d17539516370c1f453847kasper.lund  explicit Displacement(int data) { data_ = data; }
4437276f14ca716596e0a0d17539516370c1f453847kasper.lund
4447276f14ca716596e0a0d17539516370c1f453847kasper.lund  Displacement(Label* L, Type type) { init(L, type); }
4457276f14ca716596e0a0d17539516370c1f453847kasper.lund
4467276f14ca716596e0a0d17539516370c1f453847kasper.lund  void print() {
4477276f14ca716596e0a0d17539516370c1f453847kasper.lund    PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"),
4487276f14ca716596e0a0d17539516370c1f453847kasper.lund                       NextField::decode(data_));
4497276f14ca716596e0a0d17539516370c1f453847kasper.lund  }
4507276f14ca716596e0a0d17539516370c1f453847kasper.lund
4517276f14ca716596e0a0d17539516370c1f453847kasper.lund private:
4527276f14ca716596e0a0d17539516370c1f453847kasper.lund  int data_;
4537276f14ca716596e0a0d17539516370c1f453847kasper.lund
454a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  class TypeField: public BitField<Type, 0, 2> {};
455a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  class NextField: public BitField<int,  2, 32-2> {};
4567276f14ca716596e0a0d17539516370c1f453847kasper.lund
4577276f14ca716596e0a0d17539516370c1f453847kasper.lund  void init(Label* L, Type type);
4587276f14ca716596e0a0d17539516370c1f453847kasper.lund};
4597276f14ca716596e0a0d17539516370c1f453847kasper.lund
4607276f14ca716596e0a0d17539516370c1f453847kasper.lund
461ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass Assembler : public AssemblerBase {
46243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
4633e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // We check before assembling an instruction that there is sufficient
4643e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // space to write an instruction and its relocation information.
4653e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // The relocation writer's position must be kGap bytes above the end of
46643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the generated instructions. This leaves enough space for the
4673e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // longest possible ia32 instruction, 15 bytes, and the longest possible
4683e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
4693e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // (There is a 15 byte limit on ia32 instruction length that rules out some
4703e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // otherwise valid instructions.)
4713e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // This allows for a single, fast space check per instruction.
47243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static const int kGap = 32;
47343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
47443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
47543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create an assembler. Instructions and relocation information are emitted
47643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // into a buffer, with the instructions starting from the beginning and the
47743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // relocation information starting from the end of the buffer. See CodeDesc
47843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for a detailed comment on the layout (globals.h).
47943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
48043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the provided buffer is NULL, the assembler allocates and grows its own
48143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // buffer, and buffer_size determines the initial buffer size. The buffer is
48243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // owned by the assembler and deallocated upon destruction of the assembler.
48343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
48443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the provided buffer is not NULL, the assembler uses the provided buffer
48543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for code generation and assumes its size to be buffer_size. If the buffer
48643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is too small, a fatal error occurs. No deallocation of the buffer is done
48743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // upon destruction of the assembler.
488c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // TODO(vitalyr): the assembler does not need an isolate.
489c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Assembler(Isolate* isolate, void* buffer, int buffer_size);
4908e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  virtual ~Assembler() { }
49143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // GetCode emits any pending (non-emitted) code and fills the descriptor
49343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // desc. GetCode() is idempotent; it returns the same result if no other
4943291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // Assembler functions are invoked in between GetCode() calls.
49543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void GetCode(CodeDesc* desc);
49643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Read/Modify the code target in the branch/call instruction at pc.
49897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  inline static Address target_address_at(Address pc,
49997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                          ConstantPoolArray* constant_pool);
50097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  inline static void set_target_address_at(Address pc,
50197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                           ConstantPoolArray* constant_pool,
5026a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                           Address target,
5036a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                           ICacheFlushMode icache_flush_mode =
5046a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                               FLUSH_ICACHE_IF_NEEDED);
50597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  static inline Address target_address_at(Address pc, Code* code) {
50697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
50797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    return target_address_at(pc, constant_pool);
50897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
50997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  static inline void set_target_address_at(Address pc,
51097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                           Code* code,
5116a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                           Address target,
5126a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                           ICacheFlushMode icache_flush_mode =
5136a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                               FLUSH_ICACHE_IF_NEEDED) {
51497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
51597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    set_target_address_at(pc, constant_pool, target);
51697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
51743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
51889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // Return the code target address at a call site from the return address
51989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // of that call in the instruction stream.
52089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  inline static Address target_address_from_return_address(Address pc);
52189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
5229d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  // Return the code target address of the patch debug break slot
5239d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  inline static Address break_address_from_return_address(Address pc);
5249d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
5253811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // This sets the branch destination (which is in the instruction on x86).
526c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // This is for calls and branches within generated code.
52788aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  inline static void deserialization_set_special_target_at(
52897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      Address instruction_payload, Code* code, Address target) {
52997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    set_target_address_at(instruction_payload, code, target);
5303811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
5313811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
53288aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  static const int kSpecialTargetSize = kPointerSize;
5333811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
53443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Distance between the address of the code target in the call instruction
53543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // and the return address
5364af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  static const int kCallTargetAddressOffset = kPointerSize;
537911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  // Distance between start of patched return sequence and the emitted address
538911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  // to jump to.
539911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  static const int kPatchReturnSequenceAddressOffset = 1;  // JMP imm32.
54043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5412356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Distance between start of patched debug break slot and the emitted address
5422356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // to jump to.
5432356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  static const int kPatchDebugBreakSlotAddressOffset = 1;  // JMP imm32.
5442356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
545ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  static const int kCallInstructionLength = 5;
54689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  static const int kPatchDebugBreakSlotReturnOffset = kPointerSize;
547ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  static const int kJSReturnSequenceLength = 6;
54843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5492356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // The debug break slot must be able to contain a call instruction.
5502356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  static const int kDebugBreakSlotLength = kCallInstructionLength;
5512356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
552a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // One byte opcode for test al, 0xXX.
553a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const byte kTestAlByte = 0xA8;
5545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // One byte opcode for nop.
5555f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static const byte kNopByte = 0x90;
5565f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
5575f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // One byte opcode for a short unconditional jump.
5585f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static const byte kJmpShortOpcode = 0xEB;
5595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // One byte prefix for a short conditional jump.
5605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static const byte kJccShortPrefix = 0x70;
5615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
5625f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static const byte kJcShortOpcode = kJccShortPrefix | carry;
563212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
564212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  static const byte kJzShortOpcode = kJccShortPrefix | zero;
565212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
56743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
56843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Code generation
56943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
57043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // - function names correspond one-to-one to ia32 instruction mnemonics
57143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // - unless specified otherwise, instructions operate on 32bit operands
57243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // - instructions on 8bit (byte) operands/registers have a trailing '_b'
57343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // - instructions on 16bit (word) operands/registers have a trailing '_w'
57443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // - naming conflicts with C++ keywords are resolved via a trailing '_'
57543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // NOTE ON INTERFACE: Currently, the interface is not very consistent
57743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // in the sense that some operations (e.g. mov()) can be called in more
57843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the one way to generate the same instruction: The Register argument
57943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // can in some cases be replaced with an Operand(Register) argument.
5803291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // This should be cleaned up and made more orthogonal. The questions
58143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is: should we always use Operands instead of Registers where an
58243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Operand is possible, or should we have a Register (overloaded) form
5833291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // instead? We must be careful to make sure that the selected instruction
58443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is obvious from the parameters to avoid hard-to-find code generation
58543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // bugs.
58643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Insert the smallest number of nop instructions
58843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // possible to align the pc offset to a multiple
58943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // of m. m must be a power of 2.
59043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void Align(int m);
59164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void Nop(int bytes = 1);
5925ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Aligns code to something that's optimal for a jump target for the platform.
5935ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  void CodeTargetAlign();
59443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
59543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Stack
59643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void pushad();
59743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void popad();
59843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
59943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void pushfd();
60043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void popfd();
60143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
60243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void push(const Immediate& x);
603a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void push_imm32(int32_t imm32);
60443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void push(Register src);
60543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void push(const Operand& src);
60643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
60743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void pop(Register dst);
60843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void pop(const Operand& dst);
60943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
610a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void enter(const Immediate& size);
611a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void leave();
612a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
61343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Moves
614c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void mov_b(Register dst, Register src) { mov_b(dst, Operand(src)); }
61543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov_b(Register dst, const Operand& src);
616c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void mov_b(Register dst, int8_t imm8) { mov_b(Operand(dst), imm8); }
61743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov_b(const Operand& dst, int8_t imm8);
61843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov_b(const Operand& dst, Register src);
61943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
62043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov_w(Register dst, const Operand& src);
62143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov_w(const Operand& dst, Register src);
622e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  void mov_w(const Operand& dst, int16_t imm16);
62343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
62443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(Register dst, int32_t imm32);
6253bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org  void mov(Register dst, const Immediate& x);
62643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(Register dst, Handle<Object> handle);
62743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(Register dst, const Operand& src);
6283bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org  void mov(Register dst, Register src);
62943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(const Operand& dst, const Immediate& x);
63043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(const Operand& dst, Handle<Object> handle);
63143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(const Operand& dst, Register src);
63243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
633c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movsx_b(Register dst, Register src) { movsx_b(dst, Operand(src)); }
63443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void movsx_b(Register dst, const Operand& src);
63543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
636c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movsx_w(Register dst, Register src) { movsx_w(dst, Operand(src)); }
63743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void movsx_w(Register dst, const Operand& src);
63843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
639c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movzx_b(Register dst, Register src) { movzx_b(dst, Operand(src)); }
64043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void movzx_b(Register dst, const Operand& src);
64143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
642c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movzx_w(Register dst, Register src) { movzx_w(dst, Operand(src)); }
64343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void movzx_w(Register dst, const Operand& src);
64443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
64543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Conditional moves
646c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cmov(Condition cc, Register dst, Register src) {
647c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    cmov(cc, dst, Operand(src));
648c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
64943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmov(Condition cc, Register dst, const Operand& src);
65043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
651ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Flag management.
652ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void cld();
653ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6540c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // Repetitive string instructions.
6550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void rep_movs();
656ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void rep_stos();
6579dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  void stos();
6580c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
6597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Exchange
6607be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  void xchg(Register dst, Register src);
6617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void xchg(Register dst, const Operand& src);
6627be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
66343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Arithmetics
66443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void adc(Register dst, int32_t imm32);
66543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void adc(Register dst, const Operand& src);
66643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
667c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void add(Register dst, Register src) { add(dst, Operand(src)); }
66843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void add(Register dst, const Operand& src);
669c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void add(const Operand& dst, Register src);
670c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void add(Register dst, const Immediate& imm) { add(Operand(dst), imm); }
67143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void add(const Operand& dst, const Immediate& x);
67243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
67343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void and_(Register dst, int32_t imm32);
6742ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org  void and_(Register dst, const Immediate& x);
675c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void and_(Register dst, Register src) { and_(dst, Operand(src)); }
67643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void and_(Register dst, const Operand& src);
677c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void and_(const Operand& dst, Register src);
67843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void and_(const Operand& dst, const Immediate& x);
67943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
680c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cmpb(Register reg, int8_t imm8) { cmpb(Operand(reg), imm8); }
681a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void cmpb(const Operand& op, int8_t imm8);
682c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cmpb(Register reg, const Operand& op);
683c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cmpb(const Operand& op, Register reg);
68437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  void cmpb_al(const Operand& op);
68537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  void cmpw_ax(const Operand& op);
686a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void cmpw(const Operand& op, Immediate imm16);
68743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmp(Register reg, int32_t imm32);
68843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmp(Register reg, Handle<Object> handle);
689c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cmp(Register reg0, Register reg1) { cmp(reg0, Operand(reg1)); }
69043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmp(Register reg, const Operand& op);
691c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cmp(Register reg, const Immediate& imm) { cmp(Operand(reg), imm); }
69243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmp(const Operand& op, const Immediate& imm);
6934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void cmp(const Operand& op, Handle<Object> handle);
69443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void dec_b(Register dst);
6964a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  void dec_b(const Operand& dst);
69743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void dec(Register dst);
69943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void dec(const Operand& dst);
70043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
70143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cdq();
70243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void idiv(Register src) { idiv(Operand(src)); }
7047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void idiv(const Operand& src);
7057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void div(Register src) { div(Operand(src)); }
7067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void div(const Operand& src);
70743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7082abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // Signed multiply instructions.
7092abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  void imul(Register src);                               // edx:eax = eax * src.
710c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void imul(Register dst, Register src) { imul(dst, Operand(src)); }
7112abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  void imul(Register dst, const Operand& src);           // dst = dst * src.
7122abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  void imul(Register dst, Register src, int32_t imm32);  // dst = src * imm32.
7137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void imul(Register dst, const Operand& src, int32_t imm32);
71443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
71543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void inc(Register dst);
71643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void inc(const Operand& dst);
71743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
71843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void lea(Register dst, const Operand& src);
71943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7202abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // Unsigned multiply instruction.
7212abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  void mul(Register src);                                // edx:eax = eax * reg.
72243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
72343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void neg(Register dst);
7247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void neg(const Operand& dst);
72543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
72643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void not_(Register dst);
7277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void not_(const Operand& dst);
72843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
72943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void or_(Register dst, int32_t imm32);
730c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void or_(Register dst, Register src) { or_(dst, Operand(src)); }
73143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void or_(Register dst, const Operand& src);
73243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void or_(const Operand& dst, Register src);
733c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void or_(Register dst, const Immediate& imm) { or_(Operand(dst), imm); }
73443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void or_(const Operand& dst, const Immediate& x);
73543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void rcl(Register dst, uint8_t imm8);
73726c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org  void rcr(Register dst, uint8_t imm8);
738e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void ror(Register dst, uint8_t imm8);
739e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void ror_cl(Register dst);
74043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void sar(Register dst, uint8_t imm8) { sar(Operand(dst), imm8); }
7427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void sar(const Operand& dst, uint8_t imm8);
7437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void sar_cl(Register dst) { sar_cl(Operand(dst)); }
7447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void sar_cl(const Operand& dst);
74543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
74643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sbb(Register dst, const Operand& src);
74743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
748c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void shld(Register dst, Register src) { shld(dst, Operand(src)); }
74943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void shld(Register dst, const Operand& src);
75043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void shl(Register dst, uint8_t imm8) { shl(Operand(dst), imm8); }
7527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void shl(const Operand& dst, uint8_t imm8);
7537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void shl_cl(Register dst) { shl_cl(Operand(dst)); }
7547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void shl_cl(const Operand& dst);
75543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
756c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void shrd(Register dst, Register src) { shrd(dst, Operand(src)); }
75743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void shrd(Register dst, const Operand& src);
75843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void shr(Register dst, uint8_t imm8) { shr(Operand(dst), imm8); }
7607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void shr(const Operand& dst, uint8_t imm8);
7617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void shr_cl(Register dst) { shr_cl(Operand(dst)); }
7627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void shr_cl(const Operand& dst);
76343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
764c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void sub(Register dst, const Immediate& imm) { sub(Operand(dst), imm); }
76543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sub(const Operand& dst, const Immediate& x);
766c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void sub(Register dst, Register src) { sub(dst, Operand(src)); }
76743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sub(Register dst, const Operand& src);
76843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sub(const Operand& dst, Register src);
76943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void test(Register reg, const Immediate& imm);
771c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void test(Register reg0, Register reg1) { test(reg0, Operand(reg1)); }
77243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void test(Register reg, const Operand& op);
773b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void test_b(Register reg, const Operand& op);
77443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void test(const Operand& op, const Immediate& imm);
7753d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  void test_b(Register reg, uint8_t imm8);
7761af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  void test_b(const Operand& op, uint8_t imm8);
77743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void xor_(Register dst, int32_t imm32);
779c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void xor_(Register dst, Register src) { xor_(dst, Operand(src)); }
78043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void xor_(Register dst, const Operand& src);
781c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void xor_(const Operand& dst, Register src);
782c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void xor_(Register dst, const Immediate& imm) { xor_(Operand(dst), imm); }
78343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void xor_(const Operand& dst, const Immediate& x);
78443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Bit operations.
786a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void bt(const Operand& dst, Register src);
787c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void bts(Register dst, Register src) { bts(Operand(dst), src); }
78843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bts(const Operand& dst, Register src);
789f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void bsr(Register dst, Register src) { bsr(dst, Operand(src)); }
790f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void bsr(Register dst, const Operand& src);
79143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Miscellaneous
79343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void hlt();
79443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void int3();
79543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void nop();
79643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ret(int imm16);
79743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Label operations & relative jumps (PPUM Appendix D)
79943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
80043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Takes a branch opcode (cc) and a label (L) and generates
80143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // either a backward branch or a forward branch and links it
80243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to the label fixup chain. Usage:
80343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
80443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Label L;    // unbound label
80543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // j(cc, &L);  // forward branch to unbound label
80643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // bind(&L);   // bind label to the current pc
80743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // j(cc, &L);  // backward branch to bound label
80843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // bind(&L);   // illegal: a label may be bound only once
80943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
81043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note: The same Label can be used for forward and backward branches
81143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // but it may be bound only once.
81243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
81343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bind(Label* L);  // binds an unbound label L to the current code position
81443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
81543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Calls
81643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void call(Label* L);
817236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  void call(byte* entry, RelocInfo::Mode rmode);
818fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  int CallSize(const Operand& adr);
819c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void call(Register reg) { call(Operand(reg)); }
82043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void call(const Operand& adr);
821fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  int CallSize(Handle<Code> code, RelocInfo::Mode mode);
8228e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void call(Handle<Code> code,
823471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            RelocInfo::Mode rmode,
824471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            TypeFeedbackId id = TypeFeedbackId::None());
82543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
82643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Jumps
82783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // unconditional jump to L
82883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void jmp(Label* L, Label::Distance distance = Label::kFar);
829236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  void jmp(byte* entry, RelocInfo::Mode rmode);
830c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void jmp(Register reg) { jmp(Operand(reg)); }
83143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void jmp(const Operand& adr);
832236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  void jmp(Handle<Code> code, RelocInfo::Mode rmode);
83343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
83443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Conditional jumps
83583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void j(Condition cc,
83683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org         Label* L,
83783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org         Label::Distance distance = Label::kFar);
8387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  void j(Condition cc, byte* entry, RelocInfo::Mode rmode);
8397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  void j(Condition cc, Handle<Code> code);
84043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
84143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Floating-point operations
84243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fld(int i);
843ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void fstp(int i);
84443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
84543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fld1();
84643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fldz();
847ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void fldpi();
848a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void fldln2();
84943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fld_s(const Operand& adr);
85143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fld_d(const Operand& adr);
85243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fstp_s(const Operand& adr);
85432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  void fst_s(const Operand& adr);
85543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fstp_d(const Operand& adr);
856ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void fst_d(const Operand& adr);
85743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fild_s(const Operand& adr);
85943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fild_d(const Operand& adr);
86043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fist_s(const Operand& adr);
86243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fistp_s(const Operand& adr);
86443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fistp_d(const Operand& adr);
86543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
866086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // The fisttp instructions require SSE3.
867061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  void fisttp_s(const Operand& adr);
8680c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void fisttp_d(const Operand& adr);
869061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
87043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fabs();
87143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fchs();
872eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void fcos();
873eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void fsin();
8741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  void fptan();
875a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void fyl2x();
87664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void f2xm1();
87764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void fscale();
87864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void fninit();
87943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fadd(int i);
881c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  void fadd_i(int i);
88243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fsub(int i);
883c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  void fsub_i(int i);
88443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fmul(int i);
885169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void fmul_i(int i);
88643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fdiv(int i);
887c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  void fdiv_i(int i);
88843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fisub_s(const Operand& adr);
89043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void faddp(int i = 1);
89243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fsubp(int i = 1);
89343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fsubrp(int i = 1);
89443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fmulp(int i = 1);
89543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fdivp(int i = 1);
89643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fprem();
89743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fprem1();
89843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fxch(int i = 1);
90043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fincstp();
90143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ffree(int i = 0);
90243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
90343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ftst();
90443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fucomp(int i);
90543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fucompp();
9063811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  void fucomi(int i);
9073811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  void fucomip();
90843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fcompp();
90943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fnstsw_ax();
91043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fwait();
911061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  void fnclex();
91243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
91343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void frndint();
91443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
91543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sahf();
9167be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  void setcc(Condition cc, Register reg);
91743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
91843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cpuid();
91943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
920ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  // SSE instructions
921af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void movaps(XMMRegister dst, XMMRegister src);
922af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void shufps(XMMRegister dst, XMMRegister src, byte imm8);
923af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
924af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void andps(XMMRegister dst, const Operand& src);
925af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void andps(XMMRegister dst, XMMRegister src) { andps(dst, Operand(src)); }
926af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void xorps(XMMRegister dst, const Operand& src);
927af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void xorps(XMMRegister dst, XMMRegister src) { xorps(dst, Operand(src)); }
928af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void orps(XMMRegister dst, const Operand& src);
929af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void orps(XMMRegister dst, XMMRegister src) { orps(dst, Operand(src)); }
930af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
931af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void addps(XMMRegister dst, const Operand& src);
932af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void addps(XMMRegister dst, XMMRegister src) { addps(dst, Operand(src)); }
933af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void subps(XMMRegister dst, const Operand& src);
934af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void subps(XMMRegister dst, XMMRegister src) { subps(dst, Operand(src)); }
935af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void mulps(XMMRegister dst, const Operand& src);
936af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void mulps(XMMRegister dst, XMMRegister src) { mulps(dst, Operand(src)); }
937af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void divps(XMMRegister dst, const Operand& src);
938af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void divps(XMMRegister dst, XMMRegister src) { divps(dst, Operand(src)); }
939ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org
94043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // SSE2 instructions
94143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cvttss2si(Register dst, const Operand& src);
942af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void cvttss2si(Register dst, XMMRegister src) {
943af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    cvttss2si(dst, Operand(src));
944af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
94543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cvttsd2si(Register dst, const Operand& src);
9467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void cvttsd2si(Register dst, XMMRegister src) {
9477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    cvttsd2si(dst, Operand(src));
9487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
94946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  void cvtsd2si(Register dst, XMMRegister src);
95043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
951c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cvtsi2sd(XMMRegister dst, Register src) { cvtsi2sd(dst, Operand(src)); }
95243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cvtsi2sd(XMMRegister dst, const Operand& src);
953ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void cvtss2sd(XMMRegister dst, XMMRegister src);
9547979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  void cvtsd2ss(XMMRegister dst, XMMRegister src);
95543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
95643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void addsd(XMMRegister dst, XMMRegister src);
9571f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  void addsd(XMMRegister dst, const Operand& src);
95843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void subsd(XMMRegister dst, XMMRegister src);
959a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  void subsd(XMMRegister dst, const Operand& src);
96043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mulsd(XMMRegister dst, XMMRegister src);
9611f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  void mulsd(XMMRegister dst, const Operand& src);
96243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void divsd(XMMRegister dst, XMMRegister src);
963846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org  void xorpd(XMMRegister dst, XMMRegister src);
964ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void sqrtsd(XMMRegister dst, XMMRegister src);
9657e6132b924829c353864933f29124419916db550machenbach@chromium.org  void sqrtsd(XMMRegister dst, const Operand& src);
96643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
967c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  void andpd(XMMRegister dst, XMMRegister src);
968471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  void orpd(XMMRegister dst, XMMRegister src);
969c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
970af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void ucomisd(XMMRegister dst, XMMRegister src) { ucomisd(dst, Operand(src)); }
97164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void ucomisd(XMMRegister dst, const Operand& src);
9724acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
9734acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  enum RoundingMode {
9744acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    kRoundToNearest = 0x0,
9754acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    kRoundDown      = 0x1,
9764acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    kRoundUp        = 0x2,
9774acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    kRoundToZero    = 0x3
9784acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  };
9794acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
9804acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode);
9814acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
982f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  void movmskpd(Register dst, XMMRegister src);
9834121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org  void movmskps(Register dst, XMMRegister src);
9844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
985c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  void cmpltsd(XMMRegister dst, XMMRegister src);
98633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  void pcmpeqd(XMMRegister dst, XMMRegister src);
987c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
9880c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void movdqa(XMMRegister dst, const Operand& src);
9890c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void movdqa(const Operand& dst, XMMRegister src);
9900c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void movdqu(XMMRegister dst, const Operand& src);
9910c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void movdqu(const Operand& dst, XMMRegister src);
992e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  void movdq(bool aligned, XMMRegister dst, const Operand& src) {
993e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (aligned) {
994e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      movdqa(dst, src);
995e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    } else {
996e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      movdqu(dst, src);
997e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
998e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
9990c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
1000c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movd(XMMRegister dst, Register src) { movd(dst, Operand(src)); }
1001ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void movd(XMMRegister dst, const Operand& src);
1002c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movd(Register dst, XMMRegister src) { movd(Operand(dst), src); }
1003c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movd(const Operand& dst, XMMRegister src);
1004af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void movsd(XMMRegister dst, XMMRegister src) { movsd(dst, Operand(src)); }
10050fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org  void movsd(XMMRegister dst, const Operand& src);
10060fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org  void movsd(const Operand& dst, XMMRegister src);
10070fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org
1008ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
10097979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  void movss(XMMRegister dst, const Operand& src);
1010c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movss(const Operand& dst, XMMRegister src);
1011af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void movss(XMMRegister dst, XMMRegister src) { movss(dst, Operand(src)); }
101264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void extractps(Register dst, XMMRegister src, byte imm8);
10137979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
1014a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void pand(XMMRegister dst, XMMRegister src);
1015ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void pxor(XMMRegister dst, XMMRegister src);
1016c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void por(XMMRegister dst, XMMRegister src);
1017ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void ptest(XMMRegister dst, XMMRegister src);
1018ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
10195f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  void psllq(XMMRegister reg, int8_t shift);
1020c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void psllq(XMMRegister dst, XMMRegister src);
1021c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void psrlq(XMMRegister reg, int8_t shift);
1022c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void psrlq(XMMRegister dst, XMMRegister src);
10231f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  void pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle);
1024c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void pextrd(Register dst, XMMRegister src, int8_t offset) {
1025c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    pextrd(Operand(dst), src, offset);
1026c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
10275f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  void pextrd(const Operand& dst, XMMRegister src, int8_t offset);
1028c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void pinsrd(XMMRegister dst, Register src, int8_t offset) {
1029c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    pinsrd(dst, Operand(src), offset);
1030c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1031d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  void pinsrd(XMMRegister dst, const Operand& src, int8_t offset);
1032c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
10331af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Parallel XMM operations.
1034c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movntdqa(XMMRegister dst, const Operand& src);
10351af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  void movntdq(const Operand& dst, XMMRegister src);
10361af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Prefetch src position into cache level.
10371af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Level 1, 2 or 3 specifies CPU cache level. Level 0 specifies a
10381af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // non-temporal
10391af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  void prefetch(const Operand& src, int level);
10401af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // TODO(lrn): Need SFENCE for movnt?
10411af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
104243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Debugging
104343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void Print();
104443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
104543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check the code size generated from label to here.
10464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  int SizeOfCodeGeneratedSince(Label* label) {
10474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return pc_offset() - label->pos();
10484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
104943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
105043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Mark address of the ExitJSFrame code.
105143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void RecordJSReturn();
105243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10532356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Mark address of a debug break slot.
10542356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  void RecordDebugBreakSlot();
10552356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Record a comment relocation entry that can be used by a disassembler.
105749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // Use --code-comments to enable, or provide "force = true" flag to always
105849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // write a comment.
105949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  void RecordComment(const char* msg, bool force = false);
106043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1061a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Writes a single byte or word of data in the code stream.  Used for
1062a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // inline tables, e.g., jump-tables.
1063a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void db(uint8_t data);
1064a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void dd(uint32_t data);
1065236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
106643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if there is less than kGap bytes available in the buffer.
106743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If this is the case, we need to grow the buffer before emitting
106843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // an instruction or relocation information.
1069a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  inline bool buffer_overflow() const {
1070a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    return pc_ >= reloc_info_writer.pos() - kGap;
1071a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  }
107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
107343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the number of bytes available in the buffer.
107443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline int available_space() const { return reloc_info_writer.pos() - pc_; }
107543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
107664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  static bool IsNop(Address addr);
10772356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
1078f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  PositionsRecorder* positions_recorder() { return &positions_recorder_; }
1079f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
10803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  int relocation_writer_size() {
10813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    return (buffer_ + buffer_size_) - reloc_info_writer.pos();
10823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
10833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
108443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Avoid overflows for displacements etc.
108543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static const int kMaximalBufferSize = 512*MB;
108643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1087ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  byte byte_at(int pos) { return buffer_[pos]; }
1088c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
1089c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1090763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Allocate a constant pool of the correct size for the generated code.
10919fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
1092763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
1093763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Generate the constant pool for the generated code.
1094763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  void PopulateConstantPool(ConstantPoolArray* constant_pool);
1095763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
109643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen protected:
109743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void emit_sse_operand(XMMRegister reg, const Operand& adr);
109843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void emit_sse_operand(XMMRegister dst, XMMRegister src);
1099f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  void emit_sse_operand(Register dst, XMMRegister src);
1100b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  void emit_sse_operand(XMMRegister dst, Register src);
110143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1102ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  byte* addr_at(int pos) { return buffer_ + pos; }
1103ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
110643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t long_at(int pos)  {
110743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return *reinterpret_cast<uint32_t*>(addr_at(pos));
110843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
110943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void long_at_put(int pos, uint32_t x)  {
111043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
111143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
111243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
111343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // code emission
111443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void GrowBuffer();
111543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void emit(uint32_t x);
111643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void emit(Handle<Object> handle);
11178e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  inline void emit(uint32_t x,
11188e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                   RelocInfo::Mode rmode,
1119471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                   TypeFeedbackId id = TypeFeedbackId::None());
112032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  inline void emit(Handle<Code> code,
112132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                   RelocInfo::Mode rmode,
112232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                   TypeFeedbackId id = TypeFeedbackId::None());
112343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void emit(const Immediate& x);
1124a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  inline void emit_w(const Immediate& x);
112543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
112637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  // Emit the code-object-relative offset of the label's position
112737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  inline void emit_code_relative_offset(Label* label);
112837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
112943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // instruction generation
113043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void emit_arith_b(int op1, int op2, Register dst, int imm8);
113143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
113243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81)
113343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // with a given destination expression and an immediate operand.  It attempts
113443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to use the shortest encoding possible.
113543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // sel specifies the /n in the modrm byte (see the Intel PRM).
113643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void emit_arith(int sel, Operand dst, const Immediate& x);
113743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
113843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void emit_operand(Register reg, const Operand& adr);
113943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
114043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void emit_farith(int b1, int b2, int i);
114143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
114243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // labels
114343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void print(Label* L);
114443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bind_to(Label* L, int pos);
114543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11467276f14ca716596e0a0d17539516370c1f453847kasper.lund  // displacements
11477276f14ca716596e0a0d17539516370c1f453847kasper.lund  inline Displacement disp_at(Label* L);
11487276f14ca716596e0a0d17539516370c1f453847kasper.lund  inline void disp_at_put(Label* L, Displacement disp);
11497276f14ca716596e0a0d17539516370c1f453847kasper.lund  inline void emit_disp(Label* L, Displacement::Type type);
115083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  inline void emit_near_disp(Label* L);
11517276f14ca716596e0a0d17539516370c1f453847kasper.lund
115243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // record reloc info for current pc_
1153236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
115543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class CodePatcher;
115643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class EnsureSpace;
115737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
115837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  // code generation
115937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  RelocInfoWriter reloc_info_writer;
116037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
1161f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  PositionsRecorder positions_recorder_;
1162f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  friend class PositionsRecorder;
116343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
116443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
116543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
116643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Helper class that ensures that there is enough space for generating
116743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// instructions and relocation information.  The constructor makes
116843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// sure that there is enough space and (in debug mode) the destructor
116943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// checks that we did not generate too much.
117043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass EnsureSpace BASE_EMBEDDED {
117143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
117243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
1173a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
117443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
117543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    space_before_ = assembler_->available_space();
117643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
117743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
117843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
118043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ~EnsureSpace() {
118143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int bytes_generated = space_before_ - assembler_->available_space();
1182e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(bytes_generated < assembler_->kGap);
118343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
118443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
118543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
118643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
118743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Assembler* assembler_;
118843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
118943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int space_before_;
119043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
119143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
119243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
119343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
119443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11955ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#endif  // V8_IA32_ASSEMBLER_IA32_H_
1196