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