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
40ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#include "isolate.h"
41c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org#include "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) {
81c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(code >= 0);
82c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(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 {
9143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(is_valid());
9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return code_;
9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
944a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int bit() const {
9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(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) {
125a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(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) {
133496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(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)  {
139a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(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
144a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstruct IntelDoubleRegister {
14594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  static const int kMaxNumRegisters = 8;
146a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static const int kMaxNumAllocatableRegisters = 7;
147a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static int NumAllocatableRegisters();
148a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static int NumRegisters();
149a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static const char* AllocationIndexToString(int index);
15032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
151a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static int ToAllocationIndex(IntelDoubleRegister reg) {
1525323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    ASSERT(reg.code() != 0);
1535323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    return reg.code() - 1;
15432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  }
15532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
156a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static IntelDoubleRegister FromAllocationIndex(int index) {
157a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ASSERT(index >= 0 && index < NumAllocatableRegisters());
158a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return from_code(index + 1);
159a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
160a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
161a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static IntelDoubleRegister from_code(int code) {
162a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    IntelDoubleRegister result = { code };
163a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return result;
164a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
165a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
166a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool is_valid() const {
167a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return 0 <= code_ && code_ < NumRegisters();
168a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
169a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int code() const {
170a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ASSERT(is_valid());
171a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return code_;
172a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
173a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
174a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int code_;
175a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org};
176a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
177a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
178a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst IntelDoubleRegister double_register_0 = { 0 };
179a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst IntelDoubleRegister double_register_1 = { 1 };
180a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst IntelDoubleRegister double_register_2 = { 2 };
181a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst IntelDoubleRegister double_register_3 = { 3 };
182a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst IntelDoubleRegister double_register_4 = { 4 };
183a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst IntelDoubleRegister double_register_5 = { 5 };
184a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst IntelDoubleRegister double_register_6 = { 6 };
185a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst IntelDoubleRegister double_register_7 = { 7 };
186a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
187a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
188a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstruct XMMRegister : IntelDoubleRegister {
189a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static const int kNumAllocatableRegisters = 7;
190a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static const int kNumRegisters = 8;
191a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
192a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static XMMRegister from_code(int code) {
193a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    STATIC_ASSERT(sizeof(XMMRegister) == sizeof(IntelDoubleRegister));
194a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    XMMRegister result;
195a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    result.code_ = code;
196a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return result;
197a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
198a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
199a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool is(XMMRegister reg) const { return code_ == reg.code_; }
200a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
201a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static XMMRegister FromAllocationIndex(int index) {
202a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ASSERT(index >= 0 && index < NumAllocatableRegisters());
203a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return from_code(index + 1);
204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const char* AllocationIndexToString(int index) {
207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(index >= 0 && index < kNumAllocatableRegisters);
208a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    const char* const names[] = {
209a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm1",
210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm2",
211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm3",
212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm4",
213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm5",
214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm6",
215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      "xmm7"
216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    };
217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return names[index];
218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
219a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org};
22032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
221a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
222a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#define xmm0 (static_cast<const XMMRegister&>(double_register_0))
223a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#define xmm1 (static_cast<const XMMRegister&>(double_register_1))
224a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#define xmm2 (static_cast<const XMMRegister&>(double_register_2))
225a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#define xmm3 (static_cast<const XMMRegister&>(double_register_3))
226a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#define xmm4 (static_cast<const XMMRegister&>(double_register_4))
227a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#define xmm5 (static_cast<const XMMRegister&>(double_register_5))
228a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#define xmm6 (static_cast<const XMMRegister&>(double_register_6))
229a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#define xmm7 (static_cast<const XMMRegister&>(double_register_7))
230a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
231a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
232169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgstruct X87Register : IntelDoubleRegister {
233169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  static const int kNumAllocatableRegisters = 5;
234169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  static const int kNumRegisters = 5;
235a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
236169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  bool is(X87Register reg) const {
237a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return code_ == reg.code_;
238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
240a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static const char* AllocationIndexToString(int index) {
241a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ASSERT(index >= 0 && index < kNumAllocatableRegisters);
242a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    const char* const names[] = {
243169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      "stX_0", "stX_1", "stX_2", "stX_3", "stX_4"
244a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    };
245a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return names[index];
24643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
24743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
248169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  static X87Register FromAllocationIndex(int index) {
249169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    STATIC_ASSERT(sizeof(X87Register) == sizeof(IntelDoubleRegister));
250169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    ASSERT(index >= 0 && index < NumAllocatableRegisters());
251169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    X87Register result;
252169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    result.code_ = index;
253169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    return result;
254169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
255169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
256169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  static int ToAllocationIndex(X87Register reg) {
257169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    return reg.code_;
258a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
25943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
26043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
261169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org#define stX_0 static_cast<const X87Register&>(double_register_0)
262169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org#define stX_1 static_cast<const X87Register&>(double_register_1)
263169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org#define stX_2 static_cast<const X87Register&>(double_register_2)
264169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org#define stX_3 static_cast<const X87Register&>(double_register_3)
265169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org#define stX_4 static_cast<const X87Register&>(double_register_4)
26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
268a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgtypedef IntelDoubleRegister DoubleRegister;
269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
27143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum Condition {
27243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // any value < 0 is considered no_condition
27343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  no_condition  = -1,
27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  overflow      =  0,
27643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  no_overflow   =  1,
27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  below         =  2,
27843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  above_equal   =  3,
27943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  equal         =  4,
28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  not_equal     =  5,
28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  below_equal   =  6,
28243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  above         =  7,
283a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  negative      =  8,
284a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  positive      =  9,
28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  parity_even   = 10,
28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  parity_odd    = 11,
28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  less          = 12,
28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  greater_equal = 13,
28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  less_equal    = 14,
29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  greater       = 15,
29143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // aliases
293a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  carry         = below,
294a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  not_carry     = above_equal,
29543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  zero          = equal,
29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  not_zero      = not_equal,
297a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  sign          = negative,
298a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  not_sign      = positive
29943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
30043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns the equivalent of !cc.
30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Negation of the default no_condition (-1) results in a non-default
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// no_condition value (-2). As long as tests for no_condition check
30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// for condition < 0, this will work as expected.
3065ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orginline Condition NegateCondition(Condition cc) {
3075ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  return static_cast<Condition>(cc ^ 1);
3085ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org}
3095ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Corresponds to transposing the operands of a comparison.
31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hanseninline Condition ReverseCondition(Condition cc) {
31343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (cc) {
31443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case below:
31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return above;
31643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case above:
31743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return below;
31843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case above_equal:
31943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return below_equal;
32043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case below_equal:
32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return above_equal;
32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case less:
32343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return greater;
32443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case greater:
32543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return less;
32643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case greater_equal:
32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return less_equal;
32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case less_equal:
32943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return greater_equal;
33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    default:
33143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return cc;
33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  };
33343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
33443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3355ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
33643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
33743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Machine instruction Immediates
33843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
33943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Immediate BASE_EMBEDDED {
34043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
34143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline explicit Immediate(int x);
34243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline explicit Immediate(const ExternalReference& ext);
34343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline explicit Immediate(Handle<Object> handle);
34443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline explicit Immediate(Smi* value);
345a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  inline explicit Immediate(Address addr);
34643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  static Immediate CodeRelativeOffset(Label* label) {
34837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    return Immediate(label);
34937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  }
35037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
35159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  bool is_zero() const { return x_ == 0 && RelocInfo::IsNone(rmode_); }
352236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  bool is_int8() const {
35359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return -128 <= x_ && x_ < 128 && RelocInfo::IsNone(rmode_);
354236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
355a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  bool is_int16() const {
35659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return -32768 <= x_ && x_ < 32768 && RelocInfo::IsNone(rmode_);
357a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
35843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
35943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
36037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  inline explicit Immediate(Label* value);
36137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
36243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int x_;
363236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  RelocInfo::Mode rmode_;
36443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
36543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class Assembler;
3667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  friend class MacroAssembler;
36743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
36843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
36943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
37043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
37143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Machine instruction Operands
37243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
37343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum ScaleFactor {
37443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  times_1 = 0,
37543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  times_2 = 1,
37643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  times_4 = 2,
377b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org  times_8 = 3,
378b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  times_int_size = times_4,
379b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  times_half_pointer_size = times_2,
3805c838251403b0be9a882540f1922577abba4c872ager@chromium.org  times_pointer_size = times_4,
3815c838251403b0be9a882540f1922577abba4c872ager@chromium.org  times_twice_pointer_size = times_8
38243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
38343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Operand BASE_EMBEDDED {
38643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
387086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // XMM reg
388086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  INLINE(explicit Operand(XMMRegister xmm_reg));
389086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
39043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [disp/r]
391236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  INLINE(explicit Operand(int32_t disp, RelocInfo::Mode rmode));
39243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // disp only must always be relocated
39343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
39443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [base + disp/r]
395236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  explicit Operand(Register base, int32_t disp,
39659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                   RelocInfo::Mode rmode = RelocInfo::NONE32);
39743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
39843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [base + index*scale + disp/r]
39943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit Operand(Register base,
40043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                   Register index,
40143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                   ScaleFactor scale,
40243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                   int32_t disp,
40359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                   RelocInfo::Mode rmode = RelocInfo::NONE32);
40443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
40543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // [index*scale + disp/r]
40643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit Operand(Register index,
40743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                   ScaleFactor scale,
40843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                   int32_t disp,
40959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                   RelocInfo::Mode rmode = RelocInfo::NONE32);
41043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static Operand StaticVariable(const ExternalReference& ext) {
41243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return Operand(reinterpret_cast<int32_t>(ext.address()),
413236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org                   RelocInfo::EXTERNAL_REFERENCE);
41443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
41543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static Operand StaticArray(Register index,
41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                             ScaleFactor scale,
41843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                             const ExternalReference& arr) {
41943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()),
420236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org                   RelocInfo::EXTERNAL_REFERENCE);
42143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
42243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
42341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  static Operand ForCell(Handle<Cell> cell) {
42479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    AllowDeferredHandleDereference embedding_raw_address;
425a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return Operand(reinterpret_cast<int32_t>(cell.location()),
42641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                   RelocInfo::CELL);
427a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
428a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
42943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Returns true if this Operand is a wrapper for the specified register.
43043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool is_reg(Register reg) const;
43143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Returns true if this Operand is a wrapper for one register.
433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool is_reg_only() const;
434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
435c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Asserts that this Operand is a wrapper for one register and returns the
436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // register.
437c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Register reg() const;
438c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
43943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // reg
441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  INLINE(explicit Operand(Register reg));
44243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
443ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // Set the ModRM byte without an encoded 'reg' register. The
444ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // register is encoded later as part of the emit_operand operation.
445ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  inline void set_modrm(int mod, Register rm);
446ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
44743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void set_sib(ScaleFactor scale, Register index, Register base);
44843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void set_disp8(int8_t disp);
449236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  inline void set_dispr(int32_t disp, RelocInfo::Mode rmode);
45043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  byte buf_[6];
452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The number of bytes in buf_.
453c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  unsigned int len_;
454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Only valid if len_ > 4.
455c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  RelocInfo::Mode rmode_;
456c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
45743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class Assembler;
458c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  friend class MacroAssembler;
459c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  friend class LCodeGen;
46043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
46143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4637276f14ca716596e0a0d17539516370c1f453847kasper.lund// -----------------------------------------------------------------------------
4647276f14ca716596e0a0d17539516370c1f453847kasper.lund// A Displacement describes the 32bit immediate field of an instruction which
4657276f14ca716596e0a0d17539516370c1f453847kasper.lund// may be used together with a Label in order to refer to a yet unknown code
4667276f14ca716596e0a0d17539516370c1f453847kasper.lund// position. Displacements stored in the instruction stream are used to describe
4677276f14ca716596e0a0d17539516370c1f453847kasper.lund// the instruction and to chain a list of instructions using the same Label.
4687276f14ca716596e0a0d17539516370c1f453847kasper.lund// A Displacement contains 2 different fields:
4697276f14ca716596e0a0d17539516370c1f453847kasper.lund//
4707276f14ca716596e0a0d17539516370c1f453847kasper.lund// next field: position of next displacement in the chain (0 = end of list)
4717276f14ca716596e0a0d17539516370c1f453847kasper.lund// type field: instruction type
4727276f14ca716596e0a0d17539516370c1f453847kasper.lund//
4737276f14ca716596e0a0d17539516370c1f453847kasper.lund// A next value of null (0) indicates the end of a chain (note that there can
4747276f14ca716596e0a0d17539516370c1f453847kasper.lund// be no displacement at position zero, because there is always at least one
4757276f14ca716596e0a0d17539516370c1f453847kasper.lund// instruction byte before the displacement).
4767276f14ca716596e0a0d17539516370c1f453847kasper.lund//
4777276f14ca716596e0a0d17539516370c1f453847kasper.lund// Displacement _data field layout
4787276f14ca716596e0a0d17539516370c1f453847kasper.lund//
479a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// |31.....2|1......0|
4807276f14ca716596e0a0d17539516370c1f453847kasper.lund// [  next  |  type  |
4817276f14ca716596e0a0d17539516370c1f453847kasper.lund
4827276f14ca716596e0a0d17539516370c1f453847kasper.lundclass Displacement BASE_EMBEDDED {
4837276f14ca716596e0a0d17539516370c1f453847kasper.lund public:
4847276f14ca716596e0a0d17539516370c1f453847kasper.lund  enum Type {
4857276f14ca716596e0a0d17539516370c1f453847kasper.lund    UNCONDITIONAL_JUMP,
486a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    CODE_RELATIVE,
4877276f14ca716596e0a0d17539516370c1f453847kasper.lund    OTHER
4887276f14ca716596e0a0d17539516370c1f453847kasper.lund  };
4897276f14ca716596e0a0d17539516370c1f453847kasper.lund
4907276f14ca716596e0a0d17539516370c1f453847kasper.lund  int data() const { return data_; }
4917276f14ca716596e0a0d17539516370c1f453847kasper.lund  Type type() const { return TypeField::decode(data_); }
4927276f14ca716596e0a0d17539516370c1f453847kasper.lund  void next(Label* L) const {
4937276f14ca716596e0a0d17539516370c1f453847kasper.lund    int n = NextField::decode(data_);
4947276f14ca716596e0a0d17539516370c1f453847kasper.lund    n > 0 ? L->link_to(n) : L->Unuse();
4957276f14ca716596e0a0d17539516370c1f453847kasper.lund  }
4967276f14ca716596e0a0d17539516370c1f453847kasper.lund  void link_to(Label* L) { init(L, type()); }
4977276f14ca716596e0a0d17539516370c1f453847kasper.lund
4987276f14ca716596e0a0d17539516370c1f453847kasper.lund  explicit Displacement(int data) { data_ = data; }
4997276f14ca716596e0a0d17539516370c1f453847kasper.lund
5007276f14ca716596e0a0d17539516370c1f453847kasper.lund  Displacement(Label* L, Type type) { init(L, type); }
5017276f14ca716596e0a0d17539516370c1f453847kasper.lund
5027276f14ca716596e0a0d17539516370c1f453847kasper.lund  void print() {
5037276f14ca716596e0a0d17539516370c1f453847kasper.lund    PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"),
5047276f14ca716596e0a0d17539516370c1f453847kasper.lund                       NextField::decode(data_));
5057276f14ca716596e0a0d17539516370c1f453847kasper.lund  }
5067276f14ca716596e0a0d17539516370c1f453847kasper.lund
5077276f14ca716596e0a0d17539516370c1f453847kasper.lund private:
5087276f14ca716596e0a0d17539516370c1f453847kasper.lund  int data_;
5097276f14ca716596e0a0d17539516370c1f453847kasper.lund
510a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  class TypeField: public BitField<Type, 0, 2> {};
511a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  class NextField: public BitField<int,  2, 32-2> {};
5127276f14ca716596e0a0d17539516370c1f453847kasper.lund
5137276f14ca716596e0a0d17539516370c1f453847kasper.lund  void init(Label* L, Type type);
5147276f14ca716596e0a0d17539516370c1f453847kasper.lund};
5157276f14ca716596e0a0d17539516370c1f453847kasper.lund
5167276f14ca716596e0a0d17539516370c1f453847kasper.lund
517236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
51843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// CpuFeatures keeps track of which features are supported by the target CPU.
519750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// Supported features must be enabled by a CpuFeatureScope before use.
52043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Example:
521750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org//   if (assembler->IsSupported(SSE2)) {
522750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org//     CpuFeatureScope fscope(assembler, SSE2);
52343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     // Generate SSE2 floating point code.
52443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//   } else {
52543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     // Generate standard x87 floating point code.
52643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//   }
527c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgclass CpuFeatures : public AllStatic {
52843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
529c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // Detect features of the target CPU. Set safe defaults if the serializer
530c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // is enabled (snapshots must be portable).
531c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  static void Probe();
532a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
53343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check whether a feature is supported by the target CPU.
534c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  static bool IsSupported(CpuFeature f) {
535c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    ASSERT(initialized_);
5369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    if (f == SSE2 && !FLAG_enable_sse2) return false;
5379d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    if (f == SSE3 && !FLAG_enable_sse3) return false;
538f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org    if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
5399d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    if (f == CMOV && !FLAG_enable_cmov) return false;
5409d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    if (f == RDTSC && !FLAG_enable_rdtsc) return false;
541061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org    return (supported_ & (static_cast<uint64_t>(1) << f)) != 0;
542061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  }
543c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
544750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
545c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    ASSERT(initialized_);
546750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    return (found_by_runtime_probing_only_ &
547750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org            (static_cast<uint64_t>(1) << f)) != 0;
548061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  }
549c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
550750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  static bool IsSafeForSnapshot(CpuFeature f) {
551750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    return (IsSupported(f) &&
552750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org            (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
553750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
554c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
555c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org private:
556c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org#ifdef DEBUG
557c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  static bool initialized_;
558c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org#endif
559c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  static uint64_t supported_;
560750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  static uint64_t found_by_runtime_probing_only_;
561ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
562003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  friend class ExternalReference;
563ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
56443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
56543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
56643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
567ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass Assembler : public AssemblerBase {
56843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
5693e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // We check before assembling an instruction that there is sufficient
5703e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // space to write an instruction and its relocation information.
5713e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // The relocation writer's position must be kGap bytes above the end of
57243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the generated instructions. This leaves enough space for the
5733e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // longest possible ia32 instruction, 15 bytes, and the longest possible
5743e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
5753e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // (There is a 15 byte limit on ia32 instruction length that rules out some
5763e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // otherwise valid instructions.)
5773e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // This allows for a single, fast space check per instruction.
57843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static const int kGap = 32;
57943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
58143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create an assembler. Instructions and relocation information are emitted
58243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // into a buffer, with the instructions starting from the beginning and the
58343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // relocation information starting from the end of the buffer. See CodeDesc
58443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for a detailed comment on the layout (globals.h).
58543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
58643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the provided buffer is NULL, the assembler allocates and grows its own
58743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // buffer, and buffer_size determines the initial buffer size. The buffer is
58843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // owned by the assembler and deallocated upon destruction of the assembler.
58943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
59043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the provided buffer is not NULL, the assembler uses the provided buffer
59143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for code generation and assumes its size to be buffer_size. If the buffer
59243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is too small, a fatal error occurs. No deallocation of the buffer is done
59343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // upon destruction of the assembler.
594c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // TODO(vitalyr): the assembler does not need an isolate.
595c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Assembler(Isolate* isolate, void* buffer, int buffer_size);
5968e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  virtual ~Assembler() { }
59743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
59843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // GetCode emits any pending (non-emitted) code and fills the descriptor
59943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // desc. GetCode() is idempotent; it returns the same result if no other
6003291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // Assembler functions are invoked in between GetCode() calls.
60143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void GetCode(CodeDesc* desc);
60243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
60343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Read/Modify the code target in the branch/call instruction at pc.
60443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline static Address target_address_at(Address pc);
60543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline static void set_target_address_at(Address pc, Address target);
60643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
60789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // Return the code target address at a call site from the return address
60889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // of that call in the instruction stream.
60989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  inline static Address target_address_from_return_address(Address pc);
61089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
6113811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // This sets the branch destination (which is in the instruction on x86).
612c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // This is for calls and branches within generated code.
61388aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  inline static void deserialization_set_special_target_at(
61488aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org      Address instruction_payload, Address target) {
6153811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    set_target_address_at(instruction_payload, target);
6163811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
6173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
618c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // This sets the branch destination (which is in the instruction on x86).
619c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // This is for calls and branches to runtime code.
620c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  inline static void set_external_target_at(Address instruction_payload,
621c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                                            Address target) {
622c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    set_target_address_at(instruction_payload, target);
623c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  }
624c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
62588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  static const int kSpecialTargetSize = kPointerSize;
6263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
62743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Distance between the address of the code target in the call instruction
62843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // and the return address
6294af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  static const int kCallTargetAddressOffset = kPointerSize;
630911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  // Distance between start of patched return sequence and the emitted address
631911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  // to jump to.
632911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  static const int kPatchReturnSequenceAddressOffset = 1;  // JMP imm32.
63343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6342356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Distance between start of patched debug break slot and the emitted address
6352356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // to jump to.
6362356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  static const int kPatchDebugBreakSlotAddressOffset = 1;  // JMP imm32.
6372356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
638ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  static const int kCallInstructionLength = 5;
63989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  static const int kPatchDebugBreakSlotReturnOffset = kPointerSize;
640ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  static const int kJSReturnSequenceLength = 6;
64143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6422356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // The debug break slot must be able to contain a call instruction.
6432356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  static const int kDebugBreakSlotLength = kCallInstructionLength;
6442356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
645a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // One byte opcode for test al, 0xXX.
646a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const byte kTestAlByte = 0xA8;
6475f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // One byte opcode for nop.
6485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static const byte kNopByte = 0x90;
6495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
6505f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // One byte opcode for a short unconditional jump.
6515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static const byte kJmpShortOpcode = 0xEB;
6525f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // One byte prefix for a short conditional jump.
6535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static const byte kJccShortPrefix = 0x70;
6545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
6555f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static const byte kJcShortOpcode = kJccShortPrefix | carry;
656212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
657212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  static const byte kJzShortOpcode = kJccShortPrefix | zero;
658212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
659a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
66043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
66143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Code generation
66243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
66343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // - function names correspond one-to-one to ia32 instruction mnemonics
66443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // - unless specified otherwise, instructions operate on 32bit operands
66543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // - instructions on 8bit (byte) operands/registers have a trailing '_b'
66643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // - instructions on 16bit (word) operands/registers have a trailing '_w'
66743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // - naming conflicts with C++ keywords are resolved via a trailing '_'
66843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
66943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // NOTE ON INTERFACE: Currently, the interface is not very consistent
67043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // in the sense that some operations (e.g. mov()) can be called in more
67143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the one way to generate the same instruction: The Register argument
67243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // can in some cases be replaced with an Operand(Register) argument.
6733291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // This should be cleaned up and made more orthogonal. The questions
67443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is: should we always use Operands instead of Registers where an
67543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Operand is possible, or should we have a Register (overloaded) form
6763291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // instead? We must be careful to make sure that the selected instruction
67743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is obvious from the parameters to avoid hard-to-find code generation
67843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // bugs.
67943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
68043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Insert the smallest number of nop instructions
68143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // possible to align the pc offset to a multiple
68243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // of m. m must be a power of 2.
68343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void Align(int m);
68464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void Nop(int bytes = 1);
6855ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Aligns code to something that's optimal for a jump target for the platform.
6865ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  void CodeTargetAlign();
68743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
68843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Stack
68943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void pushad();
69043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void popad();
69143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void pushfd();
69343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void popfd();
69443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void push(const Immediate& x);
696a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void push_imm32(int32_t imm32);
69743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void push(Register src);
69843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void push(const Operand& src);
69943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
70043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void pop(Register dst);
70143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void pop(const Operand& dst);
70243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
703a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void enter(const Immediate& size);
704a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void leave();
705a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
70643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Moves
707c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void mov_b(Register dst, Register src) { mov_b(dst, Operand(src)); }
70843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov_b(Register dst, const Operand& src);
709c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void mov_b(Register dst, int8_t imm8) { mov_b(Operand(dst), imm8); }
71043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov_b(const Operand& dst, int8_t imm8);
71143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov_b(const Operand& dst, Register src);
71243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
71343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov_w(Register dst, const Operand& src);
71443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov_w(const Operand& dst, Register src);
71543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
71643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(Register dst, int32_t imm32);
7173bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org  void mov(Register dst, const Immediate& x);
71843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(Register dst, Handle<Object> handle);
71943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(Register dst, const Operand& src);
7203bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org  void mov(Register dst, Register src);
72143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(const Operand& dst, const Immediate& x);
72243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(const Operand& dst, Handle<Object> handle);
72343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mov(const Operand& dst, Register src);
72443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
725c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movsx_b(Register dst, Register src) { movsx_b(dst, Operand(src)); }
72643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void movsx_b(Register dst, const Operand& src);
72743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
728c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movsx_w(Register dst, Register src) { movsx_w(dst, Operand(src)); }
72943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void movsx_w(Register dst, const Operand& src);
73043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
731c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movzx_b(Register dst, Register src) { movzx_b(dst, Operand(src)); }
73243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void movzx_b(Register dst, const Operand& src);
73343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
734c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movzx_w(Register dst, Register src) { movzx_w(dst, Operand(src)); }
73543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void movzx_w(Register dst, const Operand& src);
73643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Conditional moves
738c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cmov(Condition cc, Register dst, Register src) {
739c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    cmov(cc, dst, Operand(src));
740c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
74143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmov(Condition cc, Register dst, const Operand& src);
74243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
743ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Flag management.
744ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void cld();
745ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7460c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // Repetitive string instructions.
7470c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void rep_movs();
748ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void rep_stos();
7499dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  void stos();
7500c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
7517be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  // Exchange two registers
7527be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  void xchg(Register dst, Register src);
7537be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
75443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Arithmetics
75543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void adc(Register dst, int32_t imm32);
75643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void adc(Register dst, const Operand& src);
75743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
758c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void add(Register dst, Register src) { add(dst, Operand(src)); }
75943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void add(Register dst, const Operand& src);
760c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void add(const Operand& dst, Register src);
761c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void add(Register dst, const Immediate& imm) { add(Operand(dst), imm); }
76243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void add(const Operand& dst, const Immediate& x);
76343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
76443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void and_(Register dst, int32_t imm32);
7652ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org  void and_(Register dst, const Immediate& x);
766c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void and_(Register dst, Register src) { and_(dst, Operand(src)); }
76743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void and_(Register dst, const Operand& src);
768c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void and_(const Operand& dst, Register src);
76943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void and_(const Operand& dst, const Immediate& x);
77043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
771c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cmpb(Register reg, int8_t imm8) { cmpb(Operand(reg), imm8); }
772a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void cmpb(const Operand& op, int8_t imm8);
773c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cmpb(Register reg, const Operand& op);
774c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cmpb(const Operand& op, Register reg);
77537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  void cmpb_al(const Operand& op);
77637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  void cmpw_ax(const Operand& op);
777a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void cmpw(const Operand& op, Immediate imm16);
77843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmp(Register reg, int32_t imm32);
77943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmp(Register reg, Handle<Object> handle);
780c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cmp(Register reg0, Register reg1) { cmp(reg0, Operand(reg1)); }
78143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmp(Register reg, const Operand& op);
782c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cmp(Register reg, const Immediate& imm) { cmp(Operand(reg), imm); }
78343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cmp(const Operand& op, const Immediate& imm);
7844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void cmp(const Operand& op, Handle<Object> handle);
78543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void dec_b(Register dst);
7874a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  void dec_b(const Operand& dst);
78843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void dec(Register dst);
79043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void dec(const Operand& dst);
79143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cdq();
79343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void idiv(Register src);
79543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7962abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // Signed multiply instructions.
7972abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  void imul(Register src);                               // edx:eax = eax * src.
798c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void imul(Register dst, Register src) { imul(dst, Operand(src)); }
7992abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  void imul(Register dst, const Operand& src);           // dst = dst * src.
8002abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  void imul(Register dst, Register src, int32_t imm32);  // dst = src * imm32.
80143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
80243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void inc(Register dst);
80343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void inc(const Operand& dst);
80443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
80543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void lea(Register dst, const Operand& src);
80643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8072abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // Unsigned multiply instruction.
8082abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  void mul(Register src);                                // edx:eax = eax * reg.
80943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
81043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void neg(Register dst);
81143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
81243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void not_(Register dst);
81343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
81443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void or_(Register dst, int32_t imm32);
815c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void or_(Register dst, Register src) { or_(dst, Operand(src)); }
81643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void or_(Register dst, const Operand& src);
81743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void or_(const Operand& dst, Register src);
818c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void or_(Register dst, const Immediate& imm) { or_(Operand(dst), imm); }
81943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void or_(const Operand& dst, const Immediate& x);
82043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
82143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void rcl(Register dst, uint8_t imm8);
82226c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org  void rcr(Register dst, uint8_t imm8);
823e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void ror(Register dst, uint8_t imm8);
824e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void ror_cl(Register dst);
82543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
82643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sar(Register dst, uint8_t imm8);
827c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  void sar_cl(Register dst);
82843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
82943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sbb(Register dst, const Operand& src);
83043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
831c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void shld(Register dst, Register src) { shld(dst, Operand(src)); }
83243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void shld(Register dst, const Operand& src);
83343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
83443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void shl(Register dst, uint8_t imm8);
835c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  void shl_cl(Register dst);
83643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
837c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void shrd(Register dst, Register src) { shrd(dst, Operand(src)); }
83843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void shrd(Register dst, const Operand& src);
83943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
84043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void shr(Register dst, uint8_t imm8);
841a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void shr_cl(Register dst);
84243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
843c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void sub(Register dst, const Immediate& imm) { sub(Operand(dst), imm); }
84443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sub(const Operand& dst, const Immediate& x);
845c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void sub(Register dst, Register src) { sub(dst, Operand(src)); }
84643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sub(Register dst, const Operand& src);
84743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sub(const Operand& dst, Register src);
84843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
84943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void test(Register reg, const Immediate& imm);
850c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void test(Register reg0, Register reg1) { test(reg0, Operand(reg1)); }
85143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void test(Register reg, const Operand& op);
852b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void test_b(Register reg, const Operand& op);
85343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void test(const Operand& op, const Immediate& imm);
854c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void test_b(Register reg, uint8_t imm8) { test_b(Operand(reg), imm8); }
8551af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  void test_b(const Operand& op, uint8_t imm8);
85643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void xor_(Register dst, int32_t imm32);
858c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void xor_(Register dst, Register src) { xor_(dst, Operand(src)); }
85943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void xor_(Register dst, const Operand& src);
860c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void xor_(const Operand& dst, Register src);
861c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void xor_(Register dst, const Immediate& imm) { xor_(Operand(dst), imm); }
86243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void xor_(const Operand& dst, const Immediate& x);
86343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Bit operations.
865a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void bt(const Operand& dst, Register src);
866c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void bts(Register dst, Register src) { bts(Operand(dst), src); }
86743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bts(const Operand& dst, Register src);
86843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Miscellaneous
87043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void hlt();
87143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void int3();
87243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void nop();
87343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void rdtsc();
87443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ret(int imm16);
87543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
87643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Label operations & relative jumps (PPUM Appendix D)
87743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
87843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Takes a branch opcode (cc) and a label (L) and generates
87943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // either a backward branch or a forward branch and links it
88043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to the label fixup chain. Usage:
88143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
88243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Label L;    // unbound label
88343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // j(cc, &L);  // forward branch to unbound label
88443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // bind(&L);   // bind label to the current pc
88543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // j(cc, &L);  // backward branch to bound label
88643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // bind(&L);   // illegal: a label may be bound only once
88743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
88843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note: The same Label can be used for forward and backward branches
88943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // but it may be bound only once.
89043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bind(Label* L);  // binds an unbound label L to the current code position
89243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Calls
89443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void call(Label* L);
895236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  void call(byte* entry, RelocInfo::Mode rmode);
896fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  int CallSize(const Operand& adr);
897c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void call(Register reg) { call(Operand(reg)); }
89843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void call(const Operand& adr);
899fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  int CallSize(Handle<Code> code, RelocInfo::Mode mode);
9008e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void call(Handle<Code> code,
901471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            RelocInfo::Mode rmode,
902471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            TypeFeedbackId id = TypeFeedbackId::None());
90343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
90443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Jumps
90583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // unconditional jump to L
90683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void jmp(Label* L, Label::Distance distance = Label::kFar);
907236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  void jmp(byte* entry, RelocInfo::Mode rmode);
908c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void jmp(Register reg) { jmp(Operand(reg)); }
90943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void jmp(const Operand& adr);
910236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  void jmp(Handle<Code> code, RelocInfo::Mode rmode);
91143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
91243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Conditional jumps
91383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void j(Condition cc,
91483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org         Label* L,
91583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org         Label::Distance distance = Label::kFar);
9167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  void j(Condition cc, byte* entry, RelocInfo::Mode rmode);
9177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  void j(Condition cc, Handle<Code> code);
91843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
91943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Floating-point operations
92043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fld(int i);
921ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void fstp(int i);
92243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
92343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fld1();
92443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fldz();
925ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void fldpi();
926a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void fldln2();
92743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
92843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fld_s(const Operand& adr);
92943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fld_d(const Operand& adr);
93043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
93143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fstp_s(const Operand& adr);
93243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fstp_d(const Operand& adr);
933ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void fst_d(const Operand& adr);
93443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
93543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fild_s(const Operand& adr);
93643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fild_d(const Operand& adr);
93743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
93843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fist_s(const Operand& adr);
93943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fistp_s(const Operand& adr);
94143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fistp_d(const Operand& adr);
94243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
943086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // The fisttp instructions require SSE3.
944061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  void fisttp_s(const Operand& adr);
9450c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void fisttp_d(const Operand& adr);
946061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
94743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fabs();
94843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fchs();
949eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void fcos();
950eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void fsin();
9511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  void fptan();
952a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void fyl2x();
95364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void f2xm1();
95464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void fscale();
95564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void fninit();
95643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
95743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fadd(int i);
95843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fsub(int i);
95943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fmul(int i);
960169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  void fmul_i(int i);
96143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fdiv(int i);
96243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
96343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fisub_s(const Operand& adr);
96443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
96543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void faddp(int i = 1);
96643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fsubp(int i = 1);
96743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fsubrp(int i = 1);
96843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fmulp(int i = 1);
96943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fdivp(int i = 1);
97043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fprem();
97143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fprem1();
97243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
97343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fxch(int i = 1);
97443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fincstp();
97543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ffree(int i = 0);
97643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
97743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ftst();
97843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fucomp(int i);
97943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fucompp();
9803811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  void fucomi(int i);
9813811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  void fucomip();
98243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fcompp();
98343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fnstsw_ax();
98443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void fwait();
985061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  void fnclex();
98643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
98743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void frndint();
98843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
98943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void sahf();
9907be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  void setcc(Condition cc, Register reg);
99143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
99243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cpuid();
99343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
99443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // SSE2 instructions
99543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cvttss2si(Register dst, const Operand& src);
99643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cvttsd2si(Register dst, const Operand& src);
99746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  void cvtsd2si(Register dst, XMMRegister src);
99843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
999c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void cvtsi2sd(XMMRegister dst, Register src) { cvtsi2sd(dst, Operand(src)); }
100043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void cvtsi2sd(XMMRegister dst, const Operand& src);
1001ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void cvtss2sd(XMMRegister dst, XMMRegister src);
10027979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  void cvtsd2ss(XMMRegister dst, XMMRegister src);
100343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
100443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void addsd(XMMRegister dst, XMMRegister src);
10051f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  void addsd(XMMRegister dst, const Operand& src);
100643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void subsd(XMMRegister dst, XMMRegister src);
100743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void mulsd(XMMRegister dst, XMMRegister src);
10081f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  void mulsd(XMMRegister dst, const Operand& src);
100943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void divsd(XMMRegister dst, XMMRegister src);
1010846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org  void xorpd(XMMRegister dst, XMMRegister src);
1011fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  void xorps(XMMRegister dst, XMMRegister src);
1012ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void sqrtsd(XMMRegister dst, XMMRegister src);
101343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1014c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  void andpd(XMMRegister dst, XMMRegister src);
1015471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  void orpd(XMMRegister dst, XMMRegister src);
1016c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
1017ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void ucomisd(XMMRegister dst, XMMRegister src);
101864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void ucomisd(XMMRegister dst, const Operand& src);
10194acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
10204acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  enum RoundingMode {
10214acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    kRoundToNearest = 0x0,
10224acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    kRoundDown      = 0x1,
10234acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    kRoundUp        = 0x2,
10244acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    kRoundToZero    = 0x3
10254acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  };
10264acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
10274acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode);
10284acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
1029f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  void movmskpd(Register dst, XMMRegister src);
10304121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org  void movmskps(Register dst, XMMRegister src);
10314af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
1032c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  void cmpltsd(XMMRegister dst, XMMRegister src);
103333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  void pcmpeqd(XMMRegister dst, XMMRegister src);
1034c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
1035c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  void movaps(XMMRegister dst, XMMRegister src);
1036c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
10370c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void movdqa(XMMRegister dst, const Operand& src);
10380c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void movdqa(const Operand& dst, XMMRegister src);
10390c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void movdqu(XMMRegister dst, const Operand& src);
10400c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void movdqu(const Operand& dst, XMMRegister src);
1041e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  void movdq(bool aligned, XMMRegister dst, const Operand& src) {
1042e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (aligned) {
1043e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      movdqa(dst, src);
1044e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    } else {
1045e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      movdqu(dst, src);
1046e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
1047e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
10480c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
104943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Use either movsd or movlpd.
105043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void movdbl(XMMRegister dst, const Operand& src);
105143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void movdbl(const Operand& dst, XMMRegister src);
105243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1053c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movd(XMMRegister dst, Register src) { movd(dst, Operand(src)); }
1054ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void movd(XMMRegister dst, const Operand& src);
1055c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movd(Register dst, XMMRegister src) { movd(Operand(dst), src); }
1056c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movd(const Operand& dst, XMMRegister src);
1057ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void movsd(XMMRegister dst, XMMRegister src);
1058ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
10597979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  void movss(XMMRegister dst, const Operand& src);
1060c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movss(const Operand& dst, XMMRegister src);
10617979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  void movss(XMMRegister dst, XMMRegister src);
106264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void extractps(Register dst, XMMRegister src, byte imm8);
10637979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
1064a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void pand(XMMRegister dst, XMMRegister src);
1065ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void pxor(XMMRegister dst, XMMRegister src);
1066c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void por(XMMRegister dst, XMMRegister src);
1067ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void ptest(XMMRegister dst, XMMRegister src);
1068ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
10695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  void psllq(XMMRegister reg, int8_t shift);
1070c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void psllq(XMMRegister dst, XMMRegister src);
1071c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void psrlq(XMMRegister reg, int8_t shift);
1072c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void psrlq(XMMRegister dst, XMMRegister src);
10731f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  void pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle);
1074c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void pextrd(Register dst, XMMRegister src, int8_t offset) {
1075c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    pextrd(Operand(dst), src, offset);
1076c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
10775f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  void pextrd(const Operand& dst, XMMRegister src, int8_t offset);
1078c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void pinsrd(XMMRegister dst, Register src, int8_t offset) {
1079c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    pinsrd(dst, Operand(src), offset);
1080c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1081d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  void pinsrd(XMMRegister dst, const Operand& src, int8_t offset);
1082c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
10831af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Parallel XMM operations.
1084c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void movntdqa(XMMRegister dst, const Operand& src);
10851af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  void movntdq(const Operand& dst, XMMRegister src);
10861af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Prefetch src position into cache level.
10871af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Level 1, 2 or 3 specifies CPU cache level. Level 0 specifies a
10881af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // non-temporal
10891af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  void prefetch(const Operand& src, int level);
10901af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // TODO(lrn): Need SFENCE for movnt?
10911af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
109243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Debugging
109343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void Print();
109443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
109543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check the code size generated from label to here.
10964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  int SizeOfCodeGeneratedSince(Label* label) {
10974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return pc_offset() - label->pos();
10984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
109943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
110043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Mark address of the ExitJSFrame code.
110143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void RecordJSReturn();
110243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11032356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Mark address of a debug break slot.
11042356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  void RecordDebugBreakSlot();
11052356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
110643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Record a comment relocation entry that can be used by a disassembler.
110749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // Use --code-comments to enable, or provide "force = true" flag to always
110849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // write a comment.
110949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  void RecordComment(const char* msg, bool force = false);
111043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Writes a single byte or word of data in the code stream.  Used for
1112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // inline tables, e.g., jump-tables.
1113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void db(uint8_t data);
1114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void dd(uint32_t data);
1115236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
111643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if there is less than kGap bytes available in the buffer.
111743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If this is the case, we need to grow the buffer before emitting
111843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // an instruction or relocation information.
111943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline bool overflow() const { return pc_ >= reloc_info_writer.pos() - kGap; }
112043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
112143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the number of bytes available in the buffer.
112243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline int available_space() const { return reloc_info_writer.pos() - pc_; }
112343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
112464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  static bool IsNop(Address addr);
11252356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
1126f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  PositionsRecorder* positions_recorder() { return &positions_recorder_; }
1127f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
11283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  int relocation_writer_size() {
11293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    return (buffer_ + buffer_size_) - reloc_info_writer.pos();
11303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
11313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
113243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Avoid overflows for displacements etc.
113343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static const int kMaximalBufferSize = 512*MB;
113443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  byte byte_at(int pos)  { return buffer_[pos]; }
1136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
1137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
113843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen protected:
113943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void movsd(XMMRegister dst, const Operand& src);
114043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void movsd(const Operand& dst, XMMRegister src);
114143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
114243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void emit_sse_operand(XMMRegister reg, const Operand& adr);
114343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void emit_sse_operand(XMMRegister dst, XMMRegister src);
1144f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  void emit_sse_operand(Register dst, XMMRegister src);
114543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1146ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  byte* addr_at(int pos) { return buffer_ + pos; }
1147ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1149a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
115043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t long_at(int pos)  {
115143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return *reinterpret_cast<uint32_t*>(addr_at(pos));
115243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
115343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void long_at_put(int pos, uint32_t x)  {
115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
115543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
115643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
115743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // code emission
115843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void GrowBuffer();
115943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void emit(uint32_t x);
116043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void emit(Handle<Object> handle);
11618e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  inline void emit(uint32_t x,
11628e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                   RelocInfo::Mode rmode,
1163471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                   TypeFeedbackId id = TypeFeedbackId::None());
116432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  inline void emit(Handle<Code> code,
116532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                   RelocInfo::Mode rmode,
116632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                   TypeFeedbackId id = TypeFeedbackId::None());
116743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void emit(const Immediate& x);
1168a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  inline void emit_w(const Immediate& x);
116943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  // Emit the code-object-relative offset of the label's position
117137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  inline void emit_code_relative_offset(Label* label);
117237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
117343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // instruction generation
117443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void emit_arith_b(int op1, int op2, Register dst, int imm8);
117543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81)
117743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // with a given destination expression and an immediate operand.  It attempts
117843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to use the shortest encoding possible.
117943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // sel specifies the /n in the modrm byte (see the Intel PRM).
118043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void emit_arith(int sel, Operand dst, const Immediate& x);
118143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
118243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void emit_operand(Register reg, const Operand& adr);
118343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
118443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void emit_farith(int b1, int b2, int i);
118543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
118643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // labels
118743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void print(Label* L);
118843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bind_to(Label* L, int pos);
118943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11907276f14ca716596e0a0d17539516370c1f453847kasper.lund  // displacements
11917276f14ca716596e0a0d17539516370c1f453847kasper.lund  inline Displacement disp_at(Label* L);
11927276f14ca716596e0a0d17539516370c1f453847kasper.lund  inline void disp_at_put(Label* L, Displacement disp);
11937276f14ca716596e0a0d17539516370c1f453847kasper.lund  inline void emit_disp(Label* L, Displacement::Type type);
119483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  inline void emit_near_disp(Label* L);
11957276f14ca716596e0a0d17539516370c1f453847kasper.lund
119643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // record reloc info for current pc_
1197236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
119843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
119943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class CodePatcher;
120043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class EnsureSpace;
120137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
120237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  // code generation
120337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  RelocInfoWriter reloc_info_writer;
120437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
1205f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  PositionsRecorder positions_recorder_;
1206f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  friend class PositionsRecorder;
120743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
120843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
120943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
121043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Helper class that ensures that there is enough space for generating
121143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// instructions and relocation information.  The constructor makes
121243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// sure that there is enough space and (in debug mode) the destructor
121343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// checks that we did not generate too much.
121443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass EnsureSpace BASE_EMBEDDED {
121543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
121643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
121743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (assembler_->overflow()) assembler_->GrowBuffer();
121843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
121943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    space_before_ = assembler_->available_space();
122043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
122143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
122243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
122343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
122443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ~EnsureSpace() {
122543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int bytes_generated = space_before_ - assembler_->available_space();
122643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(bytes_generated < assembler_->kGap);
122743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
122843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
122943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
123043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
123143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Assembler* assembler_;
123243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
123343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int space_before_;
123443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
123543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
123643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
123743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
123843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12395ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#endif  // V8_IA32_ASSEMBLER_IA32_H_
1240