assembler-x64.h revision e0cee9b3ed82e2391fd85d118aeaa4ea361c687d
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright (c) 1994-2006 Sun Microsystems Inc. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All Rights Reserved. 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistributions of source code must retain the above copyright notice, 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this list of conditions and the following disclaimer. 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistribution in binary form must reproduce the above copyright 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer in the 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// documentation and/or other materials provided with the distribution. 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Neither the name of Sun Microsystems or the names of contributors may 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be used to endorse or promote products derived from this software without 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// specific prior written permission. 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The original source code covered by the above license above has been 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modified significantly by Google Inc. 33e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A lightweight X64 Assembler. 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_X64_ASSEMBLER_X64_H_ 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_X64_ASSEMBLER_X64_H_ 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "serialize.h" 41d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utility functions 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test whether a 64-bit value is in a specific range. 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uint32(int64_t x) { 498defd9ff6930b4e24729971a61cf7469daf119beSteve Block static const uint64_t kMaxUInt32 = V8_UINT64_C(0xffffffff); 508defd9ff6930b4e24729971a61cf7469daf119beSteve Block return static_cast<uint64_t>(x) <= kMaxUInt32; 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_int32(int64_t x) { 548defd9ff6930b4e24729971a61cf7469daf119beSteve Block static const int64_t kMinInt32 = -V8_INT64_C(0x80000000); 558defd9ff6930b4e24729971a61cf7469daf119beSteve Block return is_uint32(x - kMinInt32); 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool uint_is_int32(uint64_t x) { 598defd9ff6930b4e24729971a61cf7469daf119beSteve Block static const uint64_t kMaxInt32 = V8_UINT64_C(0x7fffffff); 608defd9ff6930b4e24729971a61cf7469daf119beSteve Block return x <= kMaxInt32; 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool is_uint32(uint64_t x) { 648defd9ff6930b4e24729971a61cf7469daf119beSteve Block static const uint64_t kMaxUInt32 = V8_UINT64_C(0xffffffff); 658defd9ff6930b4e24729971a61cf7469daf119beSteve Block return x <= kMaxUInt32; 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CPU Registers. 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 1) We would prefer to use an enum, but enum values are assignment- 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// compatible with int, which has caused code-generation bugs. 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 2) We would prefer to use a class instead of a struct but we don't like 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the register initialization to depend on the particular initialization 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order (which appears to be different on OS X, Linux, and Windows for the 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// installed versions of C++ we tried). Using a struct permits C-style 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "initialization". Also, the Register objects cannot be const as this 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// forces initialization stubs in MSVC, making us dependent on initialization 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// order. 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 3) By not using an enum, we are possibly preventing the compiler from 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// doing certain constant folds, which may significantly reduce the 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// code generated for some assembly instructions (because they boil down 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to a few constants). If this is a problem, we could change the code 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// such that we use an enum in optimized mode, and the struct in debug 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// mode. This way we get the compile-time error checking in debug mode 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and best performance in optimized code. 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct Register { 91b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The non-allocatable registers are: 92b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // rsp - stack pointer 93b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // rbp - frame pointer 94b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // rsi - context register 95b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // r10 - fixed scratch register 96b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // r13 - root register 97b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // r15 - smi constant register 98b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const int kNumRegisters = 16; 99b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const int kNumAllocatableRegisters = 10; 100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 101b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch static int ToAllocationIndex(Register reg) { 102e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return kAllocationIndexByRegisterCode[reg.code()]; 103b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 104b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 105b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch static Register FromAllocationIndex(int index) { 106b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ASSERT(index >= 0 && index < kNumAllocatableRegisters); 107e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Register result = { kRegisterCodeByAllocationIndex[index] }; 108b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return result; 109b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 110b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const char* AllocationIndexToString(int index) { 112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(index >= 0 && index < kNumAllocatableRegisters); 113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* const names[] = { 114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "rax", 115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "rbx", 116b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch "rdx", 117b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch "rcx", 118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "rdi", 119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "r8", 120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "r9", 121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "r11", 122b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch "r14", 123b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch "r12" 124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return names[index]; 126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Register toRegister(int code) { 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register r = { code }; 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return r; 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } 1330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool is(Register reg) const { return code_ == reg.code_; } 1340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int code() const { 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_valid()); 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code_; 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int bit() const { 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 1 << code_; 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the high bit of the register code as a 0 or 1. Used often 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // when constructing the REX prefix byte. 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int high_bit() const { 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code_ >> 3; 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the 3 low bits of the register code. Used when encoding registers 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in modR/M, SIB, and opcode bytes. 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int low_bits() const { 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code_ & 0x7; 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Unfortunately we can't make this private in a struct when initializing 1543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // by assignment. 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int code_; 1561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 157b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 158e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static const int kRegisterCodeByAllocationIndex[kNumAllocatableRegisters]; 159e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static const int kAllocationIndexByRegisterCode[kNumRegisters]; 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 162402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rax = { 0 }; 163402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rcx = { 1 }; 164402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rdx = { 2 }; 165402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rbx = { 3 }; 166402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rsp = { 4 }; 167402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rbp = { 5 }; 168402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rsi = { 6 }; 169402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register rdi = { 7 }; 170402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r8 = { 8 }; 171402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r9 = { 9 }; 172402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r10 = { 10 }; 173402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r11 = { 11 }; 174402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r12 = { 12 }; 175402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r13 = { 13 }; 176402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r14 = { 14 }; 177402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register r15 = { 15 }; 178402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst Register no_reg = { -1 }; 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct XMMRegister { 182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const int kNumRegisters = 16; 183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const int kNumAllocatableRegisters = 15; 184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int ToAllocationIndex(XMMRegister reg) { 186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(reg.code() != 0); 187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return reg.code() - 1; 188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 190b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch static XMMRegister FromAllocationIndex(int index) { 191b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ASSERT(0 <= index && index < kNumAllocatableRegisters); 192b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch XMMRegister result = { index + 1 }; 193b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return result; 194b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 195b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const char* AllocationIndexToString(int index) { 197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(index >= 0 && index < kNumAllocatableRegisters); 198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* const names[] = { 199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm1", 200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm2", 201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm3", 202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm4", 203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm5", 204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm6", 205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm7", 206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm8", 207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm9", 208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm10", 209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm11", 210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm12", 211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm13", 212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm14", 213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "xmm15" 214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return names[index]; 216b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } 219b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool is(XMMRegister reg) const { return code_ == reg.code_; } 2200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int code() const { 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_valid()); 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code_; 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the high bit of the register code as a 0 or 1. Used often 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // when constructing the REX prefix byte. 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int high_bit() const { 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code_ >> 3; 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the 3 low bits of the register code. Used when encoding registers 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in modR/M, SIB, and opcode bytes. 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int low_bits() const { 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code_ & 0x7; 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int code_; 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 239402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm0 = { 0 }; 240402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm1 = { 1 }; 241402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm2 = { 2 }; 242402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm3 = { 3 }; 243402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm4 = { 4 }; 244402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm5 = { 5 }; 245402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm6 = { 6 }; 246402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm7 = { 7 }; 247402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm8 = { 8 }; 248402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm9 = { 9 }; 249402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm10 = { 10 }; 250402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm11 = { 11 }; 251402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm12 = { 12 }; 252402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm13 = { 13 }; 253402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm14 = { 14 }; 254402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst XMMRegister xmm15 = { 15 }; 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochtypedef XMMRegister DoubleRegister; 258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum Condition { 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // any value < 0 is considered no_condition 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block no_condition = -1, 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block overflow = 0, 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block no_overflow = 1, 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block below = 2, 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block above_equal = 3, 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block equal = 4, 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_equal = 5, 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block below_equal = 6, 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block above = 7, 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block negative = 8, 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block positive = 9, 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parity_even = 10, 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parity_odd = 11, 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block less = 12, 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block greater_equal = 13, 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block less_equal = 14, 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block greater = 15, 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Fake conditions that are handled by the 2823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // opcodes using them. 2833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block always = 16, 2843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block never = 17, 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // aliases 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block carry = below, 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_carry = above_equal, 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block zero = equal, 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_zero = not_equal, 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sign = negative, 2913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block not_sign = positive, 2923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block last_condition = greater 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns the equivalent of !cc. 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Negation of the default no_condition (-1) results in a non-default 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// no_condition value (-2). As long as tests for no_condition check 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for condition < 0, this will work as expected. 3009dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monseninline Condition NegateCondition(Condition cc) { 3019dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return static_cast<Condition>(cc ^ 1); 3029dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 3039dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Corresponds to transposing the operands of a comparison. 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockinline Condition ReverseCondition(Condition cc) { 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (cc) { 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case below: 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return above; 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case above: 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return below; 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case above_equal: 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return below_equal; 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case below_equal: 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return above_equal; 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case less: 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return greater; 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case greater: 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return less; 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case greater_equal: 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return less_equal; 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case less_equal: 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return greater_equal; 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return cc; 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3299dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum Hint { 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block no_hint = 0, 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block not_taken = 0x2e, 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block taken = 0x3e 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The result of negating a hint is as if the corresponding condition 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// were negated by NegateCondition. That is, no_hint is mapped to 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// itself and not_taken and taken are mapped to each other. 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockinline Hint NegateHint(Hint hint) { 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (hint == no_hint) 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ? no_hint 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : ((hint == not_taken) ? taken : not_taken); 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Machine instruction Immediates 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Immediate BASE_EMBEDDED { 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit Immediate(int32_t value) : value_(value) {} 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t value_; 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class Assembler; 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Machine instruction Operands 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum ScaleFactor { 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_1 = 0, 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_2 = 1, 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_4 = 2, 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_8 = 3, 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_int_size = times_4, 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block times_pointer_size = times_8 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Operand BASE_EMBEDDED { 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + disp/r] 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Operand(Register base, int32_t disp); 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [base + index*scale + disp/r] 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Operand(Register base, 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register index, 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t disp); 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [index*scale + disp/r] 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Operand(Register index, 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScaleFactor scale, 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t disp); 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 389f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Offset from existing memory operand. 390f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Offset is added to existing displacement as 32-bit signed values and 391f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // this must not overflow. 392f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand(const Operand& base, int32_t offset); 393f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 3941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Checks whether either base or index register is the given register. 3951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Does not check the "reg" part of the Operand. 3961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool AddressUsesRegister(Register reg) const; 3971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte rex_; 4007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch byte buf_[6]; 4011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The number of bytes of buf_ in use. 4021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block byte len_; 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the ModR/M byte without an encoded 'reg' register. The 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register is encoded later as part of the emit_operand operation. 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // set_modrm can be called before or after set_sib and set_disp*. 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_modrm(int mod, Register rm); 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the SIB byte if one is needed. Sets the length to 2 rather than 1. 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_sib(ScaleFactor scale, Register index, Register base); 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Adds operand displacement fields (offsets added to the memory address). 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Needs to be called after set_sib, not before it. 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_disp8(int disp); 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_disp32(int disp); 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class Assembler; 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CpuFeatures keeps track of which features are supported by the target CPU. 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Supported features must be enabled by a Scope before use. 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Example: 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// if (CpuFeatures::IsSupported(SSE3)) { 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CpuFeatures::Scope fscope(SSE3); 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// // Generate SSE3 floating point code. 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// } else { 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// // Generate standard x87 or SSE2 floating point code. 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// } 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CpuFeatures : public AllStatic { 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Detect features of the target CPU. Set safe defaults if the serializer 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is enabled (snapshots must be portable). 434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void Probe(bool portable); 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check whether a feature is supported by the target CPU. 436d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static bool IsSupported(CpuFeature f) { 4373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (f == SSE2 && !FLAG_enable_sse2) return false; 4383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (f == SSE3 && !FLAG_enable_sse3) return false; 4393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (f == CMOV && !FLAG_enable_cmov) return false; 4403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (f == RDTSC && !FLAG_enable_rdtsc) return false; 4413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (f == SAHF && !FLAG_enable_sahf) return false; 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (supported_ & (V8_UINT64_C(1) << f)) != 0; 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check whether a feature is currently enabled. 445d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static bool IsEnabled(CpuFeature f) { 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (enabled_ & (V8_UINT64_C(1) << f)) != 0; 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enable a specified feature within a scope. 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class Scope BASE_EMBEDDED { 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 452d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block explicit Scope(CpuFeature f) { 453d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block uint64_t mask = (V8_UINT64_C(1) << f); 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(CpuFeatures::IsSupported(f)); 455d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(!Serializer::enabled() || (found_by_runtime_probing_ & mask) == 0); 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block old_enabled_ = CpuFeatures::enabled_; 457d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CpuFeatures::enabled_ |= mask; 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~Scope() { CpuFeatures::enabled_ = old_enabled_; } 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint64_t old_enabled_; 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 464d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block explicit Scope(CpuFeature f) {} 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Safe defaults include SSE2 and CMOV for X64. It is always available, if 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // anyone checks, but they shouldn't need to check. 470d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static const uint64_t kDefaultCpuFeatures = (1 << SSE2 | 1 << CMOV); 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static uint64_t supported_; 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static uint64_t enabled_; 473d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static uint64_t found_by_runtime_probing_; 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Assembler : public Malloced { 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We check before assembling an instruction that there is sufficient 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // space to write an instruction and its relocation information. 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The relocation writer's position must be kGap bytes above the end of 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the generated instructions. This leaves enough space for the 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // longest possible x64 instruction, 15 bytes, and the longest possible 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // relocation information encoding, RelocInfoWriter::kMaxLength == 16. 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // (There is a 15 byte limit on x64 instruction length that rules out some 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // otherwise valid instructions.) 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This allows for a single, fast space check per instruction. 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kGap = 32; 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create an assembler. Instructions and relocation information are emitted 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // into a buffer, with the instructions starting from the beginning and the 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // relocation information starting from the end of the buffer. See CodeDesc 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // for a detailed comment on the layout (globals.h). 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the provided buffer is NULL, the assembler allocates and grows its own 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // buffer, and buffer_size determines the initial buffer size. The buffer is 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // owned by the assembler and deallocated upon destruction of the assembler. 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the provided buffer is not NULL, the assembler uses the provided buffer 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // for code generation and assumes its size to be buffer_size. If the buffer 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is too small, a fatal error occurs. No deallocation of the buffer is done 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // upon destruction of the assembler. 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler(void* buffer, int buffer_size); 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~Assembler(); 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // GetCode emits any pending (non-emitted) code and fills the descriptor 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // desc. GetCode() is idempotent; it returns the same result if no other 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Assembler functions are invoked in between GetCode() calls. 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void GetCode(CodeDesc* desc); 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Read/Modify the code target in the relative branch/call instruction at pc. 5133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // On the x64 architecture, we use relative jumps with a 32-bit displacement 5143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // to jump to other Code objects in the Code space in the heap. 5153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Jumps to C functions are done indirectly through a 64-bit register holding 5163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // the absolute address of the target. 5173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // These functions convert between absolute Addresses of Code objects and 5183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // the relative displacements stored in the code. 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Address target_address_at(Address pc); 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline void set_target_address_at(Address pc, Address target); 521d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 522d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This sets the branch destination (which is in the instruction on x64). 523d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This is for calls and branches within generated code. 524d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block inline static void set_target_at(Address instruction_payload, 525d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address target) { 526d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block set_target_address_at(instruction_payload, target); 527d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 528d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 529d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This sets the branch destination (which is a load instruction on x64). 530d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This is for calls and branches to runtime code. 531d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block inline static void set_external_target_at(Address instruction_payload, 532d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address target) { 533d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block *reinterpret_cast<Address*>(instruction_payload) = target; 534d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 535d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block inline Handle<Object> code_target_object_handle_at(Address pc); 537d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Number of bytes taken up by the branch target in the code. 538d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static const int kCallTargetSize = 4; // Use 32-bit displacement. 539d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static const int kExternalTargetSize = 8; // Use 64-bit absolute. 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Distance between the address of the code target in the call instruction 5413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // and the return address pushed on the stack. 5423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement. 5433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Distance between the start of the JS return sequence and where the 5443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // 32-bit displacement of a near call would be, relative to the pushed 5453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // return address. TODO: Use return sequence length instead. 5463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset; 5473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static const int kPatchReturnSequenceAddressOffset = 13 - 4; 5487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Distance between start of patched debug break slot and where the 5497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // 32-bit displacement of a near call would be, relative to the pushed 5507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // return address. TODO: Use return sequence length instead. 5517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset; 5527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static const int kPatchDebugBreakSlotAddressOffset = 13 - 4; 5533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // TODO(X64): Rename this, removing the "Real", after changing the above. 5543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static const int kRealPatchReturnSequenceAddressOffset = 2; 555d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Some x64 JS code is padded with int3 to make it large 5571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // enough to hold an instruction when the debugger patches it. 5581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const int kJumpInstructionLength = 13; 559d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static const int kCallInstructionLength = 13; 560d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static const int kJSReturnSequenceLength = 13; 5611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const int kShortCallInstructionLength = 5; 562d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // The debug break slot must be able to contain a call instruction. 5647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static const int kDebugBreakSlotLength = kCallInstructionLength; 5657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5669fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block // One byte opcode for test eax,0xXXXXXXXX. 5679fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block static const byte kTestEaxByte = 0xA9; 5681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // One byte opcode for test al, 0xXX. 5691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kTestAlByte = 0xA8; 5701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // One byte opcode for nop. 5711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kNopByte = 0x90; 5721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // One byte prefix for a short conditional jump. 5741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kJccShortPrefix = 0x70; 5751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kJncShortOpcode = kJccShortPrefix | not_carry; 5761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const byte kJcShortOpcode = kJccShortPrefix | carry; 5771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --------------------------------------------------------------------------- 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Code generation 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Function names correspond one-to-one to x64 instruction mnemonics. 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Unless specified otherwise, instructions operate on 64-bit operands. 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we need versions of an assembly instruction that operate on different 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // width arguments, we add a single-letter suffix specifying the width. 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This is done for the following instructions: mov, cmp, inc, dec, 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // add, sub, and test. 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // There are no versions of these instructions without the suffix. 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - Instructions on 32-bit (doubleword) operands/registers use 'l'. 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - Instructions on 64-bit (quadword) operands/registers use 'q'. 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Some mnemonics, such as "and", are the same as C++ keywords. 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Naming conflicts with C++ keywords are resolved by adding a trailing '_'. 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Insert the smallest number of nop instructions 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // possible to align the pc offset to a multiple 6011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // of m, where m must be a power of 2. 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Align(int m); 6039dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Aligns code to something that's optimal for a jump target for the platform. 6049dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen void CodeTargetAlign(); 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stack 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void pushfq(); 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void popfq(); 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void push(Immediate value); 6111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Push a 32 bit integer, and guarantee that it is actually pushed as a 6121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // 32 bit value, the normal push will optimize the 8 bit case. 6131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void push_imm32(int32_t imm32); 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void push(Register src); 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void push(const Operand& src); 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void pop(Register dst); 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void pop(const Operand& dst); 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void enter(Immediate size); 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void leave(); 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Moves 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movb(Register dst, const Operand& src); 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movb(Register dst, Immediate imm); 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movb(const Operand& dst, Register src); 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Move the low 16 bits of a 64-bit register value to a 16-bit 6293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // memory location. 6303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void movw(const Operand& dst, Register src); 6313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movl(Register dst, Register src); 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movl(Register dst, const Operand& src); 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movl(const Operand& dst, Register src); 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movl(const Operand& dst, Immediate imm); 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Load a 32-bit immediate value, zero-extended to 64 bits. 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movl(Register dst, Immediate imm32); 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move 64 bit register value to 64-bit memory location. 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movq(const Operand& dst, Register src); 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move 64 bit memory location to 64-bit register value. 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movq(Register dst, const Operand& src); 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movq(Register dst, Register src); 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Sign extends immediate 32-bit value to 64 bits. 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movq(Register dst, Immediate x); 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move the offset of the label location relative to the current 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // position (after the move) to the destination. 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movl(const Operand& dst, Label* src); 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move sign extended immediate to memory location. 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movq(const Operand& dst, Immediate value); 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // New x64 instructions to load a 64-bit immediate into a register. 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All 64-bit immediates must have a relocation mode. 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movq(Register dst, void* ptr, RelocInfo::Mode rmode); 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movq(Register dst, int64_t value, RelocInfo::Mode rmode); 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movq(Register dst, const char* s, RelocInfo::Mode rmode); 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Moves the address of the external reference into the register. 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movq(Register dst, ExternalReference ext); 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode); 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void movsxbq(Register dst, const Operand& src); 6623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void movsxwq(Register dst, const Operand& src); 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movsxlq(Register dst, Register src); 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movsxlq(Register dst, const Operand& src); 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movzxbq(Register dst, const Operand& src); 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movzxbl(Register dst, const Operand& src); 6673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void movzxwq(Register dst, const Operand& src); 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movzxwl(Register dst, const Operand& src); 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 670d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Repeated moves. 671d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 672d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void repmovsb(); 673d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void repmovsw(); 674d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void repmovsl(); 675d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void repmovsq(); 676d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // New x64 instruction to load from an immediate 64-bit pointer into RAX. 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void load_rax(void* ptr, RelocInfo::Mode rmode); 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void load_rax(ExternalReference ext); 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Conditional moves. 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmovq(Condition cc, Register dst, Register src); 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmovq(Condition cc, Register dst, const Operand& src); 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmovl(Condition cc, Register dst, Register src); 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmovl(Condition cc, Register dst, const Operand& src); 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Exchange two registers 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void xchg(Register dst, Register src); 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Arithmetics 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void addl(Register dst, Register src) { 692f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke arithmetic_op_32(0x03, dst, src); 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void addl(Register dst, Immediate src) { 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_32(0x0, dst, src); 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void addl(Register dst, const Operand& src) { 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_32(0x03, dst, src); 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void addl(const Operand& dst, Immediate src) { 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_32(0x0, dst, src); 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void addq(Register dst, Register src) { 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x03, dst, src); 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void addq(Register dst, const Operand& src) { 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x03, dst, src); 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void addq(const Operand& dst, Register src) { 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x01, src, dst); 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void addq(Register dst, Immediate src) { 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op(0x0, dst, src); 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void addq(const Operand& dst, Immediate src) { 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op(0x0, dst, src); 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 72725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen void sbbl(Register dst, Register src) { 728f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke arithmetic_op_32(0x1b, dst, src); 72925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen } 73025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 7311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void sbbq(Register dst, Register src) { 7321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block arithmetic_op(0x1b, dst, src); 7331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 7341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(Register dst, Immediate src) { 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_8(0x7, dst, src); 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb_al(Immediate src); 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(Register dst, Register src) { 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x3A, dst, src); 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(Register dst, const Operand& src) { 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x3A, dst, src); 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(const Operand& dst, Register src) { 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x38, src, dst); 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpb(const Operand& dst, Immediate src) { 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_8(0x7, dst, src); 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(const Operand& dst, Immediate src) { 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_16(0x7, dst, src); 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(Register dst, Immediate src) { 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_16(0x7, dst, src); 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(Register dst, const Operand& src) { 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_16(0x3B, dst, src); 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(Register dst, Register src) { 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_16(0x3B, dst, src); 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpw(const Operand& dst, Register src) { 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_16(0x39, src, dst); 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpl(Register dst, Register src) { 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_32(0x3B, dst, src); 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpl(Register dst, const Operand& src) { 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_32(0x3B, dst, src); 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpl(const Operand& dst, Register src) { 786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_32(0x39, src, dst); 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpl(Register dst, Immediate src) { 790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_32(0x7, dst, src); 791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpl(const Operand& dst, Immediate src) { 794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_32(0x7, dst, src); 795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpq(Register dst, Register src) { 798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x3B, dst, src); 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpq(Register dst, const Operand& src) { 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x3B, dst, src); 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpq(const Operand& dst, Register src) { 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x39, src, dst); 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpq(Register dst, Immediate src) { 810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op(0x7, dst, src); 811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cmpq(const Operand& dst, Immediate src) { 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op(0x7, dst, src); 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void and_(Register dst, Register src) { 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x23, dst, src); 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void and_(Register dst, const Operand& src) { 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x23, dst, src); 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void and_(const Operand& dst, Register src) { 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x21, src, dst); 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void and_(Register dst, Immediate src) { 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op(0x4, dst, src); 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void and_(const Operand& dst, Immediate src) { 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op(0x4, dst, src); 835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void andl(Register dst, Immediate src) { 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_32(0x4, dst, src); 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void andl(Register dst, Register src) { 8423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block arithmetic_op_32(0x23, dst, src); 8433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 8443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void andl(Register dst, const Operand& src) { 8461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block arithmetic_op_32(0x23, dst, src); 8471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 8481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 8494515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke void andb(Register dst, Immediate src) { 8504515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke immediate_arithmetic_op_8(0x4, dst, src); 8514515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 8523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void decq(Register dst); 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void decq(const Operand& dst); 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void decl(Register dst); 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void decl(const Operand& dst); 8573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void decb(Register dst); 8583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void decb(const Operand& dst); 859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Sign-extends rax into rdx:rax. 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cqo(); 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Sign-extends eax into edx:eax. 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cdq(); 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Divide rdx:rax by src. Quotient in rax, remainder in rdx. 866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void idivq(Register src); 867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Divide edx:eax by lower 32 bits of src. Quotient in eax, rem. in edx. 868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void idivl(Register src); 869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Signed multiply instructions. 871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void imul(Register src); // rdx:rax = rax * src. 872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void imul(Register dst, Register src); // dst = dst * src. 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void imul(Register dst, const Operand& src); // dst = dst * src. 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void imul(Register dst, Register src, Immediate imm); // dst = src * imm. 8756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Signed 32-bit multiply instructions. 8766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void imull(Register dst, Register src); // dst = dst * src. 8771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void imull(Register dst, const Operand& src); // dst = dst * src. 8786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void imull(Register dst, Register src, Immediate imm); // dst = src * imm. 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void incq(Register dst); 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void incq(const Operand& dst); 8829dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen void incl(Register dst); 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void incl(const Operand& dst); 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void lea(Register dst, const Operand& src); 8866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void leal(Register dst, const Operand& src); 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Multiply rax by src, put the result in rdx:rax. 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mul(Register src); 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void neg(Register dst); 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void neg(const Operand& dst); 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void negl(Register dst); 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void not_(Register dst); 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void not_(const Operand& dst); 8976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void notl(Register dst); 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void or_(Register dst, Register src) { 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x0B, dst, src); 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void orl(Register dst, Register src) { 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_32(0x0B, dst, src); 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void or_(Register dst, const Operand& src) { 908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x0B, dst, src); 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void orl(Register dst, const Operand& src) { 9121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block arithmetic_op_32(0x0B, dst, src); 9131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 9141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void or_(const Operand& dst, Register src) { 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x09, src, dst); 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void or_(Register dst, Immediate src) { 920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op(0x1, dst, src); 921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void orl(Register dst, Immediate src) { 9243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block immediate_arithmetic_op_32(0x1, dst, src); 9253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 9263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void or_(const Operand& dst, Immediate src) { 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op(0x1, dst, src); 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void orl(const Operand& dst, Immediate src) { 9323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block immediate_arithmetic_op_32(0x1, dst, src); 9333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 9343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void rcl(Register dst, Immediate imm8) { 9373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block shift(dst, imm8, 0x2); 9383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 9393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 9403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void rol(Register dst, Immediate imm8) { 9413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block shift(dst, imm8, 0x0); 9423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 9433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 9443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void rcr(Register dst, Immediate imm8) { 9453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block shift(dst, imm8, 0x3); 9463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 9473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 9483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void ror(Register dst, Immediate imm8) { 9493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block shift(dst, imm8, 0x1); 9503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shifts dst:src left by cl bits, affecting only dst. 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shld(Register dst, Register src); 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shifts src:dst right by cl bits, affecting only dst. 956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shrd(Register dst, Register src); 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shifts dst right, duplicating sign bit, by shift_amount bits. 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shifting by 1 is handled efficiently. 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void sar(Register dst, Immediate shift_amount) { 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift(dst, shift_amount, 0x7); 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shifts dst right, duplicating sign bit, by shift_amount bits. 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shifting by 1 is handled efficiently. 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void sarl(Register dst, Immediate shift_amount) { 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_32(dst, shift_amount, 0x7); 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shifts dst right, duplicating sign bit, by cl % 64 bits. 971d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void sar_cl(Register dst) { 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift(dst, 0x7); 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shifts dst right, duplicating sign bit, by cl % 64 bits. 976d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void sarl_cl(Register dst) { 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_32(dst, 0x7); 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shl(Register dst, Immediate shift_amount) { 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift(dst, shift_amount, 0x4); 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 984d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void shl_cl(Register dst) { 985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift(dst, 0x4); 986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 988d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void shll_cl(Register dst) { 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_32(dst, 0x4); 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shll(Register dst, Immediate shift_amount) { 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_32(dst, shift_amount, 0x4); 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shr(Register dst, Immediate shift_amount) { 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift(dst, shift_amount, 0x5); 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1000d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void shr_cl(Register dst) { 1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift(dst, 0x5); 1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1004d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void shrl_cl(Register dst) { 1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_32(dst, 0x5); 1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shrl(Register dst, Immediate shift_amount) { 1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_32(dst, shift_amount, 0x5); 1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void store_rax(void* dst, RelocInfo::Mode mode); 1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void store_rax(ExternalReference ref); 1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subq(Register dst, Register src) { 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x2B, dst, src); 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subq(Register dst, const Operand& src) { 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x2B, dst, src); 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subq(const Operand& dst, Register src) { 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x29, src, dst); 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subq(Register dst, Immediate src) { 1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op(0x5, dst, src); 1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subq(const Operand& dst, Immediate src) { 1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op(0x5, dst, src); 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subl(Register dst, Register src) { 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_32(0x2B, dst, src); 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1039e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void subl(Register dst, const Operand& src) { 1040e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke arithmetic_op_32(0x2B, dst, src); 1041e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 1042e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subl(const Operand& dst, Immediate src) { 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_32(0x5, dst, src); 1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subl(Register dst, Immediate src) { 1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_32(0x5, dst, src); 1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subb(Register dst, Immediate src) { 1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op_8(0x5, dst, src); 1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void testb(Register dst, Register src); 1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void testb(Register reg, Immediate mask); 1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void testb(const Operand& op, Immediate mask); 1058e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void testb(const Operand& op, Register reg); 1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void testl(Register dst, Register src); 1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void testl(Register reg, Immediate mask); 1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void testl(const Operand& op, Immediate mask); 1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void testq(const Operand& op, Register reg); 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void testq(Register dst, Register src); 1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void testq(Register dst, Immediate mask); 1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void xor_(Register dst, Register src) { 1067d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (dst.code() == src.code()) { 1068d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block arithmetic_op_32(0x33, dst, src); 1069d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } else { 1070d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block arithmetic_op(0x33, dst, src); 1071d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void xorl(Register dst, Register src) { 1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op_32(0x33, dst, src); 1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void xorl(Register dst, const Operand& src) { 10791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block arithmetic_op_32(0x33, dst, src); 10801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 10811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 10821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void xorl(Register dst, Immediate src) { 10831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block immediate_arithmetic_op_32(0x6, dst, src); 10841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 10851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 10861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void xorl(const Operand& dst, Immediate src) { 10871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block immediate_arithmetic_op_32(0x6, dst, src); 10881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 10891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void xor_(Register dst, const Operand& src) { 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x33, dst, src); 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void xor_(const Operand& dst, Register src) { 1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arithmetic_op(0x31, src, dst); 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void xor_(Register dst, Immediate src) { 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op(0x6, dst, src); 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void xor_(const Operand& dst, Immediate src) { 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block immediate_arithmetic_op(0x6, dst, src); 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bit operations. 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bt(const Operand& dst, Register src); 1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bts(const Operand& dst, Register src); 1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Miscellaneous 11113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void clc(); 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cpuid(); 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void hlt(); 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void int3(); 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void nop(); 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void nop(int n); 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void rdtsc(); 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ret(int imm16); 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void setcc(Condition cc, Register reg); 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Label operations & relative jumps (PPUM Appendix D) 1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Takes a branch opcode (cc) and a label (L) and generates 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // either a backward branch or a forward branch and links it 1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to the label fixup chain. Usage: 1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Label L; // unbound label 1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // j(cc, &L); // forward branch to unbound label 1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bind(&L); // bind label to the current pc 1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // j(cc, &L); // backward branch to bound label 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bind(&L); // illegal: a label may be bound only once 1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note: The same Label can be used for forward and backward branches 1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // but it may be bound only once. 1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bind(Label* L); // binds an unbound label L to the current code position 11370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void bind(NearLabel* L); 1138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calls 1140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call near relative 32-bit displacement, relative to next instruction. 1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void call(Label* L); 11423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void call(Handle<Code> target, RelocInfo::Mode rmode); 1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Calls directly to the given address using a relative offset. 11451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Should only ever be used in Code objects for calls within the 11461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // same Code object. Should not be used when generating new code (use labels), 11471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // but only when patching existing code. 11481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void call(Address target); 11491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call near absolute indirect, address in register 1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void call(Register adr); 1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call near indirect 1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void call(const Operand& operand); 1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Jumps 1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Jump short or near relative. 11583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Use a 32-bit signed displacement. 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void jmp(Label* L); // unconditional jump to L 11603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void jmp(Handle<Code> target, RelocInfo::Mode rmode); 1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Jump near absolute indirect (r64) 1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void jmp(Register adr); 1164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Jump near absolute indirect (m64) 1166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void jmp(const Operand& src); 1167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Short jump 11690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void jmp(NearLabel* L); 11700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Conditional jumps 1172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void j(Condition cc, Label* L); 11733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode); 1174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Conditional short jump 11760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void j(Condition cc, NearLabel* L, Hint hint = no_hint); 11770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Floating-point operations 1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld(int i); 1180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld1(); 1182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fldz(); 11836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void fldpi(); 1184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void fldln2(); 1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld_s(const Operand& adr); 1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fld_d(const Operand& adr); 1188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fstp_s(const Operand& adr); 1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fstp_d(const Operand& adr); 11913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void fstp(int index); 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fild_s(const Operand& adr); 1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fild_d(const Operand& adr); 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fist_s(const Operand& adr); 1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fistp_s(const Operand& adr); 1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fistp_d(const Operand& adr); 1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fisttp_s(const Operand& adr); 1202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void fisttp_d(const Operand& adr); 1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fabs(); 1205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fchs(); 1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fadd(int i); 1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsub(int i); 1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fmul(int i); 1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fdiv(int i); 1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fisub_s(const Operand& adr); 1213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void faddp(int i = 1); 1215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsubp(int i = 1); 1216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsubrp(int i = 1); 1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fmulp(int i = 1); 1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fdivp(int i = 1); 1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fprem(); 1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fprem1(); 1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fxch(int i = 1); 1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fincstp(); 1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ffree(int i = 0); 1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ftst(); 1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fucomp(int i); 1228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fucompp(); 12293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void fucomi(int i); 12303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block void fucomip(); 12313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fcompp(); 1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fnstsw_ax(); 1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fwait(); 1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fnclex(); 1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fsin(); 1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void fcos(); 1239b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void fyl2x(); 1240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void frndint(); 1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void sahf(); 1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // SSE2 instructions 12466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movd(XMMRegister dst, Register src); 12476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movd(Register dst, XMMRegister src); 12486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movq(XMMRegister dst, Register src); 12496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movq(Register dst, XMMRegister src); 12506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void extractps(Register dst, XMMRegister src, byte imm8); 12516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void movsd(const Operand& dst, XMMRegister src); 12536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movsd(XMMRegister dst, XMMRegister src); 12546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void movsd(XMMRegister dst, const Operand& src); 1255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void movdqa(const Operand& dst, XMMRegister src); 12571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void movdqa(XMMRegister dst, const Operand& src); 12581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 12598defd9ff6930b4e24729971a61cf7469daf119beSteve Block void movss(XMMRegister dst, const Operand& src); 12608defd9ff6930b4e24729971a61cf7469daf119beSteve Block void movss(const Operand& dst, XMMRegister src); 12618defd9ff6930b4e24729971a61cf7469daf119beSteve Block 1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvttss2si(Register dst, const Operand& src); 12631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void cvttss2si(Register dst, XMMRegister src); 1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvttsd2si(Register dst, const Operand& src); 12651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void cvttsd2si(Register dst, XMMRegister src); 126625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen void cvttsd2siq(Register dst, XMMRegister src); 1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvtlsi2sd(XMMRegister dst, const Operand& src); 1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvtlsi2sd(XMMRegister dst, Register src); 1270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvtqsi2sd(XMMRegister dst, const Operand& src); 1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void cvtqsi2sd(XMMRegister dst, Register src); 1272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12738defd9ff6930b4e24729971a61cf7469daf119beSteve Block void cvtlsi2ss(XMMRegister dst, Register src); 12748defd9ff6930b4e24729971a61cf7469daf119beSteve Block 12756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void cvtss2sd(XMMRegister dst, XMMRegister src); 12768defd9ff6930b4e24729971a61cf7469daf119beSteve Block void cvtss2sd(XMMRegister dst, const Operand& src); 12778defd9ff6930b4e24729971a61cf7469daf119beSteve Block void cvtsd2ss(XMMRegister dst, XMMRegister src); 12788defd9ff6930b4e24729971a61cf7469daf119beSteve Block 12798defd9ff6930b4e24729971a61cf7469daf119beSteve Block void cvtsd2si(Register dst, XMMRegister src); 12808defd9ff6930b4e24729971a61cf7469daf119beSteve Block void cvtsd2siq(Register dst, XMMRegister src); 12816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void addsd(XMMRegister dst, XMMRegister src); 1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void subsd(XMMRegister dst, XMMRegister src); 1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void mulsd(XMMRegister dst, XMMRegister src); 1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void divsd(XMMRegister dst, XMMRegister src); 1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1287e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void andpd(XMMRegister dst, XMMRegister src); 1288e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void orpd(XMMRegister dst, XMMRegister src); 1289402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void xorpd(XMMRegister dst, XMMRegister src); 12906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void sqrtsd(XMMRegister dst, XMMRegister src); 1291402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1292402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu void ucomisd(XMMRegister dst, XMMRegister src); 12938defd9ff6930b4e24729971a61cf7469daf119beSteve Block void ucomisd(XMMRegister dst, const Operand& src); 1294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void movmskpd(Register dst, XMMRegister src); 12961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 12976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // The first argument is the reg field, the second argument is the r/m field. 1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_sse_operand(XMMRegister dst, XMMRegister src); 1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_sse_operand(XMMRegister reg, const Operand& adr); 1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_sse_operand(XMMRegister dst, Register src); 13016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void emit_sse_operand(Register dst, XMMRegister src); 1302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugging 1304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Print(); 1305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check the code size generated from label to here. 1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); } 1308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark address of the ExitJSFrame code. 1310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void RecordJSReturn(); 1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark address of a debug break slot. 13137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch void RecordDebugBreakSlot(); 13147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Record a comment relocation entry that can be used by a disassembler. 1316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Use --code-comments to enable. 1317e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void RecordComment(const char* msg, bool force = false); 1318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Writes a single word of data in the code stream. 1320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Used for inline tables, e.g., jump-tables. 1321b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void db(uint8_t data); 1322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void dd(uint32_t data); 1323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 13240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int pc_offset() const { return static_cast<int>(pc_ - buffer_); } 13253e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 13263e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu PositionsRecorder* positions_recorder() { return &positions_recorder_; } 1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if there is less than kGap bytes available in the buffer. 1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If this is the case, we need to grow the buffer before emitting 1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // an instruction or relocation information. 1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool buffer_overflow() const { 1332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return pc_ >= reloc_info_writer.pos() - kGap; 1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the number of bytes available in the buffer. 1336d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block inline int available_space() const { 1337d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return static_cast<int>(reloc_info_writer.pos() - pc_); 1338d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static bool IsNop(Address addr) { return *addr == 0x90; } 13417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Avoid overflows for displacements etc. 1343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kMaximalBufferSize = 512*MB; 1344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kMinimalBufferSize = 4*KB; 1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* addr_at(int pos) { return buffer_ + pos; } 1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte byte_at(int pos) { return buffer_[pos]; } 13490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void set_byte_at(int pos, byte value) { buffer_[pos] = value; } 1350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t long_at(int pos) { 1351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *reinterpret_cast<uint32_t*>(addr_at(pos)); 1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void long_at_put(int pos, uint32_t x) { 1354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; 1355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // code emission 1358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void GrowBuffer(); 1359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit(byte x) { *pc_++ = x; } 1361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emitl(uint32_t x); 1362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emitq(uint64_t x, RelocInfo::Mode rmode); 1363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emitw(uint16_t x); 13643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block inline void emit_code_target(Handle<Code> target, RelocInfo::Mode rmode); 1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit(Immediate x) { emitl(x.value_); } 1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emits a REX prefix that encodes a 64-bit operand size and 1368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top bit of both register codes. 1369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is set. 1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(XMMRegister reg, Register rm_reg); 13726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block inline void emit_rex_64(Register reg, XMMRegister rm_reg); 13736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block inline void emit_rex_64(Register reg, Register rm_reg); 1374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emits a REX prefix that encodes a 64-bit operand size and 1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top bit of the destination, index, and base register codes. 1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of reg is used for REX.R, the high bit of op's base 1378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register is used for REX.B, and the high bit of op's index register 1379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is used for REX.X. REX.W is set. 1380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(Register reg, const Operand& op); 1381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(XMMRegister reg, const Operand& op); 1382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emits a REX prefix that encodes a 64-bit operand size and 1384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top bit of the register code. 1385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of register is used for REX.B. 1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is set and REX.R and REX.X are clear. 1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(Register rm_reg); 1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emits a REX prefix that encodes a 64-bit operand size and 1390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top bit of the index and base register codes. 1391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of op's base register is used for REX.B, and the high 1392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bit of op's index register is used for REX.X. 1393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is set and REX.R clear. 1394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_64(const Operand& op); 1395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size. 1397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_rex_64() { emit(0x48); } 1398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is clear. 1401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_32(Register reg, Register rm_reg); 1402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of reg is used for REX.R, the high bit of op's base 1404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register is used for REX.B, and the high bit of op's index register 1405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is used for REX.X. REX.W is cleared. 1406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_32(Register reg, const Operand& op); 1407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of rm_reg goes to REX.B. 1409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W, REX.R and REX.X are clear. 1410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_32(Register rm_reg); 1411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of base goes to REX.B and high bit of index to REX.X. 1413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W and REX.R are clear. 1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_rex_32(const Operand& op); 1415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // REX.W is cleared. If no REX bits are set, no byte is emitted. 1418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(Register reg, Register rm_reg); 1419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The high bit of reg is used for REX.R, the high bit of op's base 1421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // register is used for REX.B, and the high bit of op's index register 1422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing 1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is emitted. 1424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(Register reg, const Operand& op); 1425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // As for emit_optional_rex_32(Register, Register), except that 1427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the registers are XMM registers. 1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base); 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // As for emit_optional_rex_32(Register, Register), except that 14316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // one of the registers is an XMM registers. 1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(XMMRegister reg, Register base); 1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // As for emit_optional_rex_32(Register, Register), except that 14356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // one of the registers is an XMM registers. 14366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block inline void emit_optional_rex_32(Register reg, XMMRegister base); 14376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // As for emit_optional_rex_32(Register, const Operand&), except that 1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the register is an XMM register. 1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(XMMRegister reg, const Operand& op); 1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Optionally do as emit_rex_32(Register) if the register number has 1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the high bit set. 1444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(Register rm_reg); 1445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Optionally do as emit_rex_32(const Operand&) if the operand register 1447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // numbers have a high bit set. 1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_optional_rex_32(const Operand& op); 1449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit the ModR/M byte, and optionally the SIB byte and 1452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1- or 4-byte offset for a memory operand. Also encodes 1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the second operand of the operation, a register or operation 1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // subcode, into the reg field of the ModR/M byte. 1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_operand(Register reg, const Operand& adr) { 1456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_operand(reg.low_bits(), adr); 1457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit the ModR/M byte, and optionally the SIB byte and 1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1- or 4-byte offset for a memory operand. Also used to encode 1461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a three-bit opcode extension into the ModR/M byte. 1462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_operand(int rm, const Operand& adr); 1463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit a ModR/M byte with registers coded in the reg and rm_reg fields. 1465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_modrm(Register reg, Register rm_reg) { 1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits()); 1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit a ModR/M byte with an operation subcode in the reg field and 1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a register in the rm_reg field. 1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_modrm(int code, Register rm_reg) { 1472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_uint3(code)); 1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0xC0 | code << 3 | rm_reg.low_bits()); 1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit the code-object-relative offset of the label's position 1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void emit_code_relative_offset(Label* label); 1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit machine code for one of the operations ADD, ADC, SUB, SBC, 1480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // AND, OR, XOR, or CMP. The encodings of these operations are all 1481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // similar, differing just in the opcode or in the reg field of the 1482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ModR/M byte. 1483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void arithmetic_op_16(byte opcode, Register reg, Register rm_reg); 1484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg); 1485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void arithmetic_op_32(byte opcode, Register reg, Register rm_reg); 1486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void arithmetic_op_32(byte opcode, Register reg, const Operand& rm_reg); 1487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void arithmetic_op(byte opcode, Register reg, Register rm_reg); 1488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void arithmetic_op(byte opcode, Register reg, const Operand& rm_reg); 1489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op(byte subcode, Register dst, Immediate src); 1490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src); 1491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Operate on a byte in memory or register. 1492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_8(byte subcode, 1493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register dst, 1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 1495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_8(byte subcode, 1496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Operand& dst, 1497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 1498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Operate on a word in memory or register. 1499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_16(byte subcode, 1500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register dst, 1501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_16(byte subcode, 1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Operand& dst, 1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Operate on a 32-bit word in memory or register. 1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_32(byte subcode, 1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register dst, 1508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 1509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void immediate_arithmetic_op_32(byte subcode, 1510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Operand& dst, 1511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate src); 1512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Emit machine code for a shift operation. 1514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shift(Register dst, Immediate shift_amount, int subcode); 1515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shift_32(Register dst, Immediate shift_amount, int subcode); 1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shift dst by cl % 64 bits. 1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shift(Register dst, int subcode); 1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void shift_32(Register dst, int subcode); 1519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void emit_farith(int b1, int b2, int i); 1521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // labels 1523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // void print(Label* L); 1524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void bind_to(Label* L, int pos); 1525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // record reloc info for current pc_ 1527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class CodePatcher; 1530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class EnsureSpace; 1531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class RegExpMacroAssemblerX64; 1532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Code buffer: 1534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The buffer into which code and relocation info are generated. 1535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* buffer_; 1536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int buffer_size_; 1537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // True if the assembler owns the buffer, false if buffer is external. 1538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool own_buffer_; 1539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // A previously allocated buffer of kMinimalBufferSize bytes, or NULL. 1540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static byte* spare_buffer_; 1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // code generation 1543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* pc_; // the program counter; moves forward 1544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfoWriter reloc_info_writer; 1545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block List< Handle<Code> > code_targets_; 1547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // push-pop elimination 1548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* last_pc_; 1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15503e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu PositionsRecorder positions_recorder_; 15513e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu friend class PositionsRecorder; 1552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper class that ensures that there is enough space for generating 1556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instructions and relocation information. The constructor makes 1557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// sure that there is enough space and (in debug mode) the destructor 1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// checks that we did not generate too much. 1559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EnsureSpace BASE_EMBEDDED { 1560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 1561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { 1562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (assembler_->buffer_overflow()) assembler_->GrowBuffer(); 1563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 1564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block space_before_ = assembler_->available_space(); 1565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 1569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~EnsureSpace() { 1570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bytes_generated = space_before_ - assembler_->available_space(); 1571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(bytes_generated < assembler_->kGap); 1572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 1576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler* assembler_; 1577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 1578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int space_before_; 1579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 1581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 1583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_X64_ASSEMBLER_X64_H_ 1585