1864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright (c) 1994-2006 Sun Microsystems Inc. 2864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// All Rights Reserved. 3864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 4864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Redistribution and use in source and binary forms, with or without 5864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// modification, are permitted provided that the following conditions are 6864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// met: 7864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 8864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// - Redistributions of source code must retain the above copyright notice, 9864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// this list of conditions and the following disclaimer. 10864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 11864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// - Redistribution in binary form must reproduce the above copyright 12864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// notice, this list of conditions and the following disclaimer in the 13864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// documentation and/or other materials provided with the distribution. 14864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 15864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// - Neither the name of Sun Microsystems or the names of contributors may 16864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// be used to endorse or promote products derived from this software without 17864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// specific prior written permission. 18864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 19864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// The original source code covered by the above license above has been 32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// modified significantly by Google Inc. 33864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 34864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 35864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// A light-weight IA32 Assembler. 36864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 37864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifndef V8_X87_ASSEMBLER_X87_H_ 38864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define V8_X87_ASSEMBLER_X87_H_ 39864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 40196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate.h" 41196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/serialize.h" 42864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 43864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace v8 { 44864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace internal { 45864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 46864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// CPU Registers. 47864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 1) We would prefer to use an enum, but enum values are assignment- 49864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// compatible with int, which has caused code-generation bugs. 50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 51864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 2) We would prefer to use a class instead of a struct but we don't like 52864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// the register initialization to depend on the particular initialization 53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// order (which appears to be different on OS X, Linux, and Windows for the 54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// installed versions of C++ we tried). Using a struct permits C-style 55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// "initialization". Also, the Register objects cannot be const as this 56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// forces initialization stubs in MSVC, making us dependent on initialization 57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// order. 58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 3) By not using an enum, we are possibly preventing the compiler from 60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// doing certain constant folds, which may significantly reduce the 61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// code generated for some assembly instructions (because they boil down 62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// to a few constants). If this is a problem, we could change the code 63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// such that we use an enum in optimized mode, and the struct in debug 64864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// mode. This way we get the compile-time error checking in debug mode 65864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// and best performance in optimized code. 66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstruct Register { 68864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kMaxNumAllocatableRegisters = 6; 69864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static int NumAllocatableRegisters() { 70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return kMaxNumAllocatableRegisters; 71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kNumRegisters = 8; 73864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 74864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static inline const char* AllocationIndexToString(int index); 75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 76864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static inline int ToAllocationIndex(Register reg); 77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 78864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static inline Register FromAllocationIndex(int index); 79864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static Register from_code(int code) { 81e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(code >= 0); 82e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(code < kNumRegisters); 83864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register r = { code }; 84864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return r; 85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } 87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is(Register reg) const { return code_ == reg.code_; } 88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // eax, ebx, ecx and edx are byte registers, the rest are not. 89864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_byte_register() const { return code_ <= 3; } 90864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int code() const { 91e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_valid()); 92864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return code_; 93864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 94864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int bit() const { 95e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_valid()); 96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 1 << code_; 97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Unfortunately we can't make this private in a struct. 100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int code_; 101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst int kRegister_eax_Code = 0; 104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst int kRegister_ecx_Code = 1; 105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst int kRegister_edx_Code = 2; 106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst int kRegister_ebx_Code = 3; 107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst int kRegister_esp_Code = 4; 108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst int kRegister_ebp_Code = 5; 109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst int kRegister_esi_Code = 6; 110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst int kRegister_edi_Code = 7; 111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst int kRegister_no_reg_Code = -1; 112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst Register eax = { kRegister_eax_Code }; 114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst Register ecx = { kRegister_ecx_Code }; 115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst Register edx = { kRegister_edx_Code }; 116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst Register ebx = { kRegister_ebx_Code }; 117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst Register esp = { kRegister_esp_Code }; 118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst Register ebp = { kRegister_ebp_Code }; 119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst Register esi = { kRegister_esi_Code }; 120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst Register edi = { kRegister_edi_Code }; 121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst Register no_reg = { kRegister_no_reg_Code }; 122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline const char* Register::AllocationIndexToString(int index) { 125e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); 126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This is the mapping of allocation indices to registers. 127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* const kNames[] = { "eax", "ecx", "edx", "ebx", "esi", "edi" }; 128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return kNames[index]; 129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline int Register::ToAllocationIndex(Register reg) { 133e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(reg.is_valid() && !reg.is(esp) && !reg.is(ebp)); 134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return (reg.code() >= 6) ? reg.code() - 2 : reg.code(); 135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline Register Register::FromAllocationIndex(int index) { 139e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); 140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return (index >= 4) ? from_code(index + 2) : from_code(index); 141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstruct X87Register { 14506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org static const int kMaxNumAllocatableRegisters = 6; 146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kMaxNumRegisters = 8; 147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static int NumAllocatableRegisters() { 148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return kMaxNumAllocatableRegisters; 149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static int ToAllocationIndex(X87Register reg) { 152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return reg.code_; 153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const char* AllocationIndexToString(int index) { 156e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); 157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* const names[] = { 158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "stX_0", "stX_1", "stX_2", "stX_3", "stX_4", 159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "stX_5", "stX_6", "stX_7" 160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return names[index]; 162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static X87Register FromAllocationIndex(int index) { 165e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); 166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register result; 167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org result.code_ = index; 168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return result; 169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_valid() const { 172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 0 <= code_ && code_ < kMaxNumRegisters; 173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int code() const { 176e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_valid()); 177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return code_; 178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is(X87Register reg) const { 181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return code_ == reg.code_; 182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int code_; 185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgtypedef X87Register DoubleRegister; 189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst X87Register stX_0 = { 0 }; 192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst X87Register stX_1 = { 1 }; 193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst X87Register stX_2 = { 2 }; 194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst X87Register stX_3 = { 3 }; 195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst X87Register stX_4 = { 4 }; 196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst X87Register stX_5 = { 5 }; 197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst X87Register stX_6 = { 6 }; 198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst X87Register stX_7 = { 7 }; 199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgenum Condition { 202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // any value < 0 is considered no_condition 203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org no_condition = -1, 204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org overflow = 0, 206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org no_overflow = 1, 207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org below = 2, 208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org above_equal = 3, 209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org equal = 4, 210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org not_equal = 5, 211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org below_equal = 6, 212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org above = 7, 213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org negative = 8, 214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org positive = 9, 215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org parity_even = 10, 216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org parity_odd = 11, 217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org less = 12, 218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org greater_equal = 13, 219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org less_equal = 14, 220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org greater = 15, 221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // aliases 223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org carry = below, 224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org not_carry = above_equal, 225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org zero = equal, 226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org not_zero = not_equal, 227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org sign = negative, 228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org not_sign = positive 229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns the equivalent of !cc. 233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Negation of the default no_condition (-1) results in a non-default 234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// no_condition value (-2). As long as tests for no_condition check 235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// for condition < 0, this will work as expected. 236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline Condition NegateCondition(Condition cc) { 237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return static_cast<Condition>(cc ^ 1); 238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2411e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org// Commute a condition such that {a cond b == b cond' a}. 24238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orginline Condition CommuteCondition(Condition cc) { 243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (cc) { 244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case below: 245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return above; 246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case above: 247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return below; 248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case above_equal: 249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return below_equal; 250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case below_equal: 251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return above_equal; 252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case less: 253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return greater; 254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case greater: 255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return less; 256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case greater_equal: 257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return less_equal; 258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case less_equal: 259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return greater_equal; 260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return cc; 262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// ----------------------------------------------------------------------------- 267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Machine instruction Immediates 268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass Immediate BASE_EMBEDDED { 270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline explicit Immediate(int x); 272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline explicit Immediate(const ExternalReference& ext); 273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline explicit Immediate(Handle<Object> handle); 274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline explicit Immediate(Smi* value); 275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline explicit Immediate(Address addr); 276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static Immediate CodeRelativeOffset(Label* label) { 278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Immediate(label); 279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_zero() const { return x_ == 0 && RelocInfo::IsNone(rmode_); } 282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_int8() const { 283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return -128 <= x_ && x_ < 128 && RelocInfo::IsNone(rmode_); 284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_int16() const { 286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return -32768 <= x_ && x_ < 32768 && RelocInfo::IsNone(rmode_); 287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline explicit Immediate(Label* value); 291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int x_; 293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::Mode rmode_; 294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2955c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org friend class Operand; 296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org friend class Assembler; 297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org friend class MacroAssembler; 298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// ----------------------------------------------------------------------------- 302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Machine instruction Operands 303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgenum ScaleFactor { 305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_1 = 0, 306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_2 = 1, 307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_4 = 2, 308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_8 = 3, 309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_int_size = times_4, 310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_half_pointer_size = times_2, 311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_pointer_size = times_4, 312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_twice_pointer_size = times_8 313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass Operand BASE_EMBEDDED { 317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 3185c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org // reg 3195c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org INLINE(explicit Operand(Register reg)); 3205c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org 321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // [disp/r] 322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org INLINE(explicit Operand(int32_t disp, RelocInfo::Mode rmode)); 3235c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org 3245c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org // [disp/r] 3255c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org INLINE(explicit Operand(Immediate imm)); 326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // [base + disp/r] 328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org explicit Operand(Register base, int32_t disp, 329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::Mode rmode = RelocInfo::NONE32); 330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // [base + index*scale + disp/r] 332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org explicit Operand(Register base, 333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index, 334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ScaleFactor scale, 335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t disp, 336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::Mode rmode = RelocInfo::NONE32); 337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // [index*scale + disp/r] 339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org explicit Operand(Register index, 340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ScaleFactor scale, 341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t disp, 342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::Mode rmode = RelocInfo::NONE32); 343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static Operand StaticVariable(const ExternalReference& ext) { 345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Operand(reinterpret_cast<int32_t>(ext.address()), 346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::EXTERNAL_REFERENCE); 347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static Operand StaticArray(Register index, 350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ScaleFactor scale, 351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ExternalReference& arr) { 352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()), 353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::EXTERNAL_REFERENCE); 354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static Operand ForCell(Handle<Cell> cell) { 357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllowDeferredHandleDereference embedding_raw_address; 358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Operand(reinterpret_cast<int32_t>(cell.location()), 359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::CELL); 360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3625c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org static Operand ForRegisterPlusImmediate(Register base, Immediate imm) { 3635c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org return Operand(base, imm.x_, imm.rmode_); 3645c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org } 3655c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org 366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Returns true if this Operand is a wrapper for the specified register. 367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_reg(Register reg) const; 368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Returns true if this Operand is a wrapper for one register. 370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_reg_only() const; 371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Asserts that this Operand is a wrapper for one register and returns the 373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // register. 374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg() const; 375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Set the ModRM byte without an encoded 'reg' register. The 378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // register is encoded later as part of the emit_operand operation. 379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void set_modrm(int mod, Register rm); 380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void set_sib(ScaleFactor scale, Register index, Register base); 382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void set_disp8(int8_t disp); 383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void set_dispr(int32_t disp, RelocInfo::Mode rmode); 384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte buf_[6]; 386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The number of bytes in buf_. 387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org unsigned int len_; 388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Only valid if len_ > 4. 389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::Mode rmode_; 390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org friend class Assembler; 392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org friend class MacroAssembler; 393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// ----------------------------------------------------------------------------- 397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// A Displacement describes the 32bit immediate field of an instruction which 398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// may be used together with a Label in order to refer to a yet unknown code 399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// position. Displacements stored in the instruction stream are used to describe 400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// the instruction and to chain a list of instructions using the same Label. 401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// A Displacement contains 2 different fields: 402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// next field: position of next displacement in the chain (0 = end of list) 404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// type field: instruction type 405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// A next value of null (0) indicates the end of a chain (note that there can 407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// be no displacement at position zero, because there is always at least one 408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// instruction byte before the displacement). 409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Displacement _data field layout 411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// |31.....2|1......0| 413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// [ next | type | 414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass Displacement BASE_EMBEDDED { 416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org enum Type { 418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNCONDITIONAL_JUMP, 419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CODE_RELATIVE, 420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org OTHER 421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int data() const { return data_; } 424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Type type() const { return TypeField::decode(data_); } 425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void next(Label* L) const { 426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int n = NextField::decode(data_); 427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org n > 0 ? L->link_to(n) : L->Unuse(); 428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void link_to(Label* L) { init(L, type()); } 430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org explicit Displacement(int data) { data_ = data; } 432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Displacement(Label* L, Type type) { init(L, type); } 434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void print() { 436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"), 437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NextField::decode(data_)); 438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int data_; 442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org class TypeField: public BitField<Type, 0, 2> {}; 444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org class NextField: public BitField<int, 2, 32-2> {}; 445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void init(Label* L, Type type); 447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass Assembler : public AssemblerBase { 451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We check before assembling an instruction that there is sufficient 453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // space to write an instruction and its relocation information. 454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The relocation writer's position must be kGap bytes above the end of 455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the generated instructions. This leaves enough space for the 456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // longest possible ia32 instruction, 15 bytes, and the longest possible 457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // relocation information encoding, RelocInfoWriter::kMaxLength == 16. 458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // (There is a 15 byte limit on ia32 instruction length that rules out some 459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // otherwise valid instructions.) 460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This allows for a single, fast space check per instruction. 461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kGap = 32; 462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Create an assembler. Instructions and relocation information are emitted 465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // into a buffer, with the instructions starting from the beginning and the 466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // relocation information starting from the end of the buffer. See CodeDesc 467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // for a detailed comment on the layout (globals.h). 468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the provided buffer is NULL, the assembler allocates and grows its own 470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // buffer, and buffer_size determines the initial buffer size. The buffer is 471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // owned by the assembler and deallocated upon destruction of the assembler. 472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the provided buffer is not NULL, the assembler uses the provided buffer 474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // for code generation and assumes its size to be buffer_size. If the buffer 475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // is too small, a fatal error occurs. No deallocation of the buffer is done 476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // upon destruction of the assembler. 477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(vitalyr): the assembler does not need an isolate. 478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Assembler(Isolate* isolate, void* buffer, int buffer_size); 479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org virtual ~Assembler() { } 480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // GetCode emits any pending (non-emitted) code and fills the descriptor 482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // desc. GetCode() is idempotent; it returns the same result if no other 483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Assembler functions are invoked in between GetCode() calls. 484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void GetCode(CodeDesc* desc); 485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Read/Modify the code target in the branch/call instruction at pc. 487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline static Address target_address_at(Address pc, 488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ConstantPoolArray* constant_pool); 489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline static void set_target_address_at(Address pc, 490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ConstantPoolArray* constant_pool, 491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address target, 492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ICacheFlushMode icache_flush_mode = 493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FLUSH_ICACHE_IF_NEEDED); 494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static inline Address target_address_at(Address pc, Code* code) { 495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; 496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return target_address_at(pc, constant_pool); 497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static inline void set_target_address_at(Address pc, 499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Code* code, 500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address target, 501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ICacheFlushMode icache_flush_mode = 502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FLUSH_ICACHE_IF_NEEDED) { 503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; 504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org set_target_address_at(pc, constant_pool, target); 505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return the code target address at a call site from the return address 508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // of that call in the instruction stream. 509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline static Address target_address_from_return_address(Address pc); 510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5119d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Return the code target address of the patch debug break slot 5129d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org inline static Address break_address_from_return_address(Address pc); 5139d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This sets the branch destination (which is in the instruction on x86). 515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This is for calls and branches within generated code. 516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline static void deserialization_set_special_target_at( 517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address instruction_payload, Code* code, Address target) { 518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org set_target_address_at(instruction_payload, code, target); 519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kSpecialTargetSize = kPointerSize; 522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Distance between the address of the code target in the call instruction 524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // and the return address 525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kCallTargetAddressOffset = kPointerSize; 526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Distance between start of patched return sequence and the emitted address 527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // to jump to. 528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kPatchReturnSequenceAddressOffset = 1; // JMP imm32. 529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Distance between start of patched debug break slot and the emitted address 531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // to jump to. 532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kPatchDebugBreakSlotAddressOffset = 1; // JMP imm32. 533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kCallInstructionLength = 5; 535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kPatchDebugBreakSlotReturnOffset = kPointerSize; 536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kJSReturnSequenceLength = 6; 537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The debug break slot must be able to contain a call instruction. 539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kDebugBreakSlotLength = kCallInstructionLength; 540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // One byte opcode for test al, 0xXX. 542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const byte kTestAlByte = 0xA8; 543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // One byte opcode for nop. 544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const byte kNopByte = 0x90; 545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // One byte opcode for a short unconditional jump. 547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const byte kJmpShortOpcode = 0xEB; 548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // One byte prefix for a short conditional jump. 549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const byte kJccShortPrefix = 0x70; 550864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const byte kJncShortOpcode = kJccShortPrefix | not_carry; 551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const byte kJcShortOpcode = kJccShortPrefix | carry; 552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const byte kJnzShortOpcode = kJccShortPrefix | not_zero; 553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const byte kJzShortOpcode = kJccShortPrefix | zero; 554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // --------------------------------------------------------------------------- 557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Code generation 558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // - function names correspond one-to-one to ia32 instruction mnemonics 560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // - unless specified otherwise, instructions operate on 32bit operands 561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // - instructions on 8bit (byte) operands/registers have a trailing '_b' 562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // - instructions on 16bit (word) operands/registers have a trailing '_w' 563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // - naming conflicts with C++ keywords are resolved via a trailing '_' 564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // NOTE ON INTERFACE: Currently, the interface is not very consistent 566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // in the sense that some operations (e.g. mov()) can be called in more 567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the one way to generate the same instruction: The Register argument 568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // can in some cases be replaced with an Operand(Register) argument. 569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This should be cleaned up and made more orthogonal. The questions 570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // is: should we always use Operands instead of Registers where an 571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Operand is possible, or should we have a Register (overloaded) form 572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // instead? We must be careful to make sure that the selected instruction 573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // is obvious from the parameters to avoid hard-to-find code generation 574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // bugs. 575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Insert the smallest number of nop instructions 577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // possible to align the pc offset to a multiple 578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // of m. m must be a power of 2. 579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Align(int m); 580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Nop(int bytes = 1); 581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Aligns code to something that's optimal for a jump target for the platform. 582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CodeTargetAlign(); 583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Stack 585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void pushad(); 586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void popad(); 587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void pushfd(); 589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void popfd(); 590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void push(const Immediate& x); 592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void push_imm32(int32_t imm32); 593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void push(Register src); 594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void push(const Operand& src); 595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void pop(Register dst); 597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void pop(const Operand& dst); 598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void enter(const Immediate& size); 600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void leave(); 601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Moves 603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov_b(Register dst, Register src) { mov_b(dst, Operand(src)); } 604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov_b(Register dst, const Operand& src); 605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov_b(Register dst, int8_t imm8) { mov_b(Operand(dst), imm8); } 606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov_b(const Operand& dst, int8_t imm8); 607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov_b(const Operand& dst, Register src); 608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov_w(Register dst, const Operand& src); 610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov_w(const Operand& dst, Register src); 611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov_w(const Operand& dst, int16_t imm16); 612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov(Register dst, int32_t imm32); 614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov(Register dst, const Immediate& x); 615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov(Register dst, Handle<Object> handle); 616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov(Register dst, const Operand& src); 617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov(Register dst, Register src); 618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov(const Operand& dst, const Immediate& x); 619864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov(const Operand& dst, Handle<Object> handle); 620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mov(const Operand& dst, Register src); 621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void movsx_b(Register dst, Register src) { movsx_b(dst, Operand(src)); } 623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void movsx_b(Register dst, const Operand& src); 624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void movsx_w(Register dst, Register src) { movsx_w(dst, Operand(src)); } 626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void movsx_w(Register dst, const Operand& src); 627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void movzx_b(Register dst, Register src) { movzx_b(dst, Operand(src)); } 629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void movzx_b(Register dst, const Operand& src); 630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void movzx_w(Register dst, Register src) { movzx_w(dst, Operand(src)); } 632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void movzx_w(Register dst, const Operand& src); 633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Flag management. 635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cld(); 636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Repetitive string instructions. 638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void rep_movs(); 639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void rep_stos(); 640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void stos(); 641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6425c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org // Exchange 643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void xchg(Register dst, Register src); 6445c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void xchg(Register dst, const Operand& src); 645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Arithmetics 647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void adc(Register dst, int32_t imm32); 648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void adc(Register dst, const Operand& src); 649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void add(Register dst, Register src) { add(dst, Operand(src)); } 651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void add(Register dst, const Operand& src); 652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void add(const Operand& dst, Register src); 653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void add(Register dst, const Immediate& imm) { add(Operand(dst), imm); } 654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void add(const Operand& dst, const Immediate& x); 655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void and_(Register dst, int32_t imm32); 657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void and_(Register dst, const Immediate& x); 658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void and_(Register dst, Register src) { and_(dst, Operand(src)); } 659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void and_(Register dst, const Operand& src); 660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void and_(const Operand& dst, Register src); 661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void and_(const Operand& dst, const Immediate& x); 662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmpb(Register reg, int8_t imm8) { cmpb(Operand(reg), imm8); } 664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmpb(const Operand& op, int8_t imm8); 665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmpb(Register reg, const Operand& op); 666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmpb(const Operand& op, Register reg); 667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmpb_al(const Operand& op); 668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmpw_ax(const Operand& op); 669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmpw(const Operand& op, Immediate imm16); 670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmp(Register reg, int32_t imm32); 671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmp(Register reg, Handle<Object> handle); 672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmp(Register reg0, Register reg1) { cmp(reg0, Operand(reg1)); } 673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmp(Register reg, const Operand& op); 674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmp(Register reg, const Immediate& imm) { cmp(Operand(reg), imm); } 675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmp(const Operand& op, const Immediate& imm); 676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cmp(const Operand& op, Handle<Object> handle); 677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void dec_b(Register dst); 679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void dec_b(const Operand& dst); 680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void dec(Register dst); 682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void dec(const Operand& dst); 683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cdq(); 685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6865c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void idiv(Register src) { idiv(Operand(src)); } 6875c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void idiv(const Operand& src); 6885c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void div(Register src) { div(Operand(src)); } 6895c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void div(const Operand& src); 690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Signed multiply instructions. 692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void imul(Register src); // edx:eax = eax * src. 693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void imul(Register dst, Register src) { imul(dst, Operand(src)); } 694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void imul(Register dst, const Operand& src); // dst = dst * src. 695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void imul(Register dst, Register src, int32_t imm32); // dst = src * imm32. 6965c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void imul(Register dst, const Operand& src, int32_t imm32); 697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void inc(Register dst); 699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void inc(const Operand& dst); 700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void lea(Register dst, const Operand& src); 702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Unsigned multiply instruction. 704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void mul(Register src); // edx:eax = eax * reg. 705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void neg(Register dst); 7075c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void neg(const Operand& dst); 708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void not_(Register dst); 7105c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void not_(const Operand& dst); 711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void or_(Register dst, int32_t imm32); 713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void or_(Register dst, Register src) { or_(dst, Operand(src)); } 714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void or_(Register dst, const Operand& src); 715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void or_(const Operand& dst, Register src); 716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void or_(Register dst, const Immediate& imm) { or_(Operand(dst), imm); } 717864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void or_(const Operand& dst, const Immediate& x); 718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void rcl(Register dst, uint8_t imm8); 720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void rcr(Register dst, uint8_t imm8); 721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void ror(Register dst, uint8_t imm8); 722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void ror_cl(Register dst); 723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7245c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void sar(Register dst, uint8_t imm8) { sar(Operand(dst), imm8); } 7255c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void sar(const Operand& dst, uint8_t imm8); 7265c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void sar_cl(Register dst) { sar_cl(Operand(dst)); } 7275c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void sar_cl(const Operand& dst); 728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void sbb(Register dst, const Operand& src); 730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void shld(Register dst, Register src) { shld(dst, Operand(src)); } 732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void shld(Register dst, const Operand& src); 733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7345c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void shl(Register dst, uint8_t imm8) { shl(Operand(dst), imm8); } 7355c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void shl(const Operand& dst, uint8_t imm8); 7365c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void shl_cl(Register dst) { shl_cl(Operand(dst)); } 7375c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void shl_cl(const Operand& dst); 738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void shrd(Register dst, Register src) { shrd(dst, Operand(src)); } 740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void shrd(Register dst, const Operand& src); 741864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7425c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void shr(Register dst, uint8_t imm8) { shr(Operand(dst), imm8); } 7435c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void shr(const Operand& dst, uint8_t imm8); 7445c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void shr_cl(Register dst) { shr_cl(Operand(dst)); } 7455c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org void shr_cl(const Operand& dst); 746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void sub(Register dst, const Immediate& imm) { sub(Operand(dst), imm); } 748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void sub(const Operand& dst, const Immediate& x); 749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void sub(Register dst, Register src) { sub(dst, Operand(src)); } 750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void sub(Register dst, const Operand& src); 751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void sub(const Operand& dst, Register src); 752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void test(Register reg, const Immediate& imm); 754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void test(Register reg0, Register reg1) { test(reg0, Operand(reg1)); } 755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void test(Register reg, const Operand& op); 756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void test_b(Register reg, const Operand& op); 757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void test(const Operand& op, const Immediate& imm); 758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void test_b(Register reg, uint8_t imm8); 759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void test_b(const Operand& op, uint8_t imm8); 760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void xor_(Register dst, int32_t imm32); 762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void xor_(Register dst, Register src) { xor_(dst, Operand(src)); } 763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void xor_(Register dst, const Operand& src); 764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void xor_(const Operand& dst, Register src); 765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void xor_(Register dst, const Immediate& imm) { xor_(Operand(dst), imm); } 766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void xor_(const Operand& dst, const Immediate& x); 767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Bit operations. 769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void bt(const Operand& dst, Register src); 770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void bts(Register dst, Register src) { bts(Operand(dst), src); } 771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void bts(const Operand& dst, Register src); 772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void bsr(Register dst, Register src) { bsr(dst, Operand(src)); } 773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void bsr(Register dst, const Operand& src); 774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Miscellaneous 776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void hlt(); 777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void int3(); 778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void nop(); 779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void ret(int imm16); 780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Label operations & relative jumps (PPUM Appendix D) 782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Takes a branch opcode (cc) and a label (L) and generates 784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // either a backward branch or a forward branch and links it 785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // to the label fixup chain. Usage: 786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Label L; // unbound label 788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // j(cc, &L); // forward branch to unbound label 789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // bind(&L); // bind label to the current pc 790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // j(cc, &L); // backward branch to bound label 791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // bind(&L); // illegal: a label may be bound only once 792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Note: The same Label can be used for forward and backward branches 794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // but it may be bound only once. 795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void bind(Label* L); // binds an unbound label L to the current code position 797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Calls 799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void call(Label* L); 800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void call(byte* entry, RelocInfo::Mode rmode); 801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int CallSize(const Operand& adr); 802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void call(Register reg) { call(Operand(reg)); } 803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void call(const Operand& adr); 804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int CallSize(Handle<Code> code, RelocInfo::Mode mode); 805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void call(Handle<Code> code, 806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::Mode rmode, 807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TypeFeedbackId id = TypeFeedbackId::None()); 808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Jumps 810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // unconditional jump to L 811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void jmp(Label* L, Label::Distance distance = Label::kFar); 812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void jmp(byte* entry, RelocInfo::Mode rmode); 813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void jmp(Register reg) { jmp(Operand(reg)); } 814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void jmp(const Operand& adr); 815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void jmp(Handle<Code> code, RelocInfo::Mode rmode); 816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Conditional jumps 818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void j(Condition cc, 819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* L, 820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance distance = Label::kFar); 821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void j(Condition cc, byte* entry, RelocInfo::Mode rmode); 822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void j(Condition cc, Handle<Code> code); 823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Floating-point operations 825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fld(int i); 826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fstp(int i); 827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fld1(); 829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fldz(); 830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fldpi(); 831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fldln2(); 832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fld_s(const Operand& adr); 834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fld_d(const Operand& adr); 835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fstp_s(const Operand& adr); 837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fst_s(const Operand& adr); 838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fstp_d(const Operand& adr); 839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fst_d(const Operand& adr); 840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fild_s(const Operand& adr); 842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fild_d(const Operand& adr); 843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fist_s(const Operand& adr); 845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fistp_s(const Operand& adr); 847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fistp_d(const Operand& adr); 848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The fisttp instructions require SSE3. 850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fisttp_s(const Operand& adr); 851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fisttp_d(const Operand& adr); 852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fabs(); 854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fchs(); 85506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void fsqrt(); 856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fcos(); 857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fsin(); 858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fptan(); 859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fyl2x(); 860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void f2xm1(); 861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fscale(); 862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fninit(); 863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fadd(int i); 865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fadd_i(int i); 86606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void fadd_d(const Operand& adr); 867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fsub(int i); 868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fsub_i(int i); 869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fmul(int i); 870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fmul_i(int i); 871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fdiv(int i); 872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fdiv_i(int i); 873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fisub_s(const Operand& adr); 875864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 876864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void faddp(int i = 1); 877864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fsubp(int i = 1); 878864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fsubrp(int i = 1); 879864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fmulp(int i = 1); 880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fdivp(int i = 1); 881864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fprem(); 882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fprem1(); 883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 884864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fxch(int i = 1); 885864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fincstp(); 886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void ffree(int i = 0); 887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 888864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void ftst(); 88906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void fxam(); 890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fucomp(int i); 891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fucompp(); 892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fucomi(int i); 893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fucomip(); 894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fcompp(); 895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fnstsw_ax(); 89606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void fldcw(const Operand& adr); 89706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void fnstcw(const Operand& adr); 898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fwait(); 899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void fnclex(); 90006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void fnsave(const Operand& adr); 90106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void frstor(const Operand& adr); 902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void frndint(); 904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void sahf(); 906864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void setcc(Condition cc, Register reg); 907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void cpuid(); 909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(lrn): Need SFENCE for movnt? 911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Debugging 913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Print(); 914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check the code size generated from label to here. 916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int SizeOfCodeGeneratedSince(Label* label) { 917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return pc_offset() - label->pos(); 918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Mark address of the ExitJSFrame code. 921864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RecordJSReturn(); 922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Mark address of a debug break slot. 924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RecordDebugBreakSlot(); 925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record a comment relocation entry that can be used by a disassembler. 927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Use --code-comments to enable, or provide "force = true" flag to always 928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // write a comment. 929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RecordComment(const char* msg, bool force = false); 930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 931864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Writes a single byte or word of data in the code stream. Used for 932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // inline tables, e.g., jump-tables. 933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void db(uint8_t data); 934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void dd(uint32_t data); 935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 936864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if there is less than kGap bytes available in the buffer. 937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If this is the case, we need to grow the buffer before emitting 938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // an instruction or relocation information. 939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline bool buffer_overflow() const { 940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return pc_ >= reloc_info_writer.pos() - kGap; 941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the number of bytes available in the buffer. 944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline int available_space() const { return reloc_info_writer.pos() - pc_; } 945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static bool IsNop(Address addr); 947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PositionsRecorder* positions_recorder() { return &positions_recorder_; } 949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int relocation_writer_size() { 951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return (buffer_ + buffer_size_) - reloc_info_writer.pos(); 952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Avoid overflows for displacements etc. 955864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kMaximalBufferSize = 512*MB; 956864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte byte_at(int pos) { return buffer_[pos]; } 958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void set_byte_at(int pos, byte value) { buffer_[pos] = value; } 959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Allocate a constant pool of the correct size for the generated code. 961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); 962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate the constant pool for the generated code. 964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void PopulateConstantPool(ConstantPoolArray* constant_pool); 965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 966864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org protected: 967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* addr_at(int pos) { return buffer_ + pos; } 968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org uint32_t long_at(int pos) { 972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return *reinterpret_cast<uint32_t*>(addr_at(pos)); 973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void long_at_put(int pos, uint32_t x) { 975864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; 976864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 977864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // code emission 979864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void GrowBuffer(); 980864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void emit(uint32_t x); 981864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void emit(Handle<Object> handle); 982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void emit(uint32_t x, 983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::Mode rmode, 984864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TypeFeedbackId id = TypeFeedbackId::None()); 985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void emit(Handle<Code> code, 986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::Mode rmode, 987864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TypeFeedbackId id = TypeFeedbackId::None()); 988864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void emit(const Immediate& x); 989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void emit_w(const Immediate& x); 990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emit the code-object-relative offset of the label's position 992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void emit_code_relative_offset(Label* label); 993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // instruction generation 995864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void emit_arith_b(int op1, int op2, Register dst, int imm8); 996864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 997864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81) 998864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // with a given destination expression and an immediate operand. It attempts 999864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // to use the shortest encoding possible. 1000864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // sel specifies the /n in the modrm byte (see the Intel PRM). 1001864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void emit_arith(int sel, Operand dst, const Immediate& x); 1002864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1003864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void emit_operand(Register reg, const Operand& adr); 1004864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1005864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void emit_farith(int b1, int b2, int i); 1006864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1007864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // labels 1008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void print(Label* L); 1009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void bind_to(Label* L, int pos); 1010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1011864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // displacements 1012864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline Displacement disp_at(Label* L); 1013864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void disp_at_put(Label* L, Displacement disp); 1014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void emit_disp(Label* L, Displacement::Type type); 1015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inline void emit_near_disp(Label* L); 1016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // record reloc info for current pc_ 1018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org friend class CodePatcher; 1021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org friend class EnsureSpace; 1022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1023864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // code generation 1024864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfoWriter reloc_info_writer; 1025864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1026864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PositionsRecorder positions_recorder_; 1027864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org friend class PositionsRecorder; 1028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 1029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1031864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Helper class that ensures that there is enough space for generating 1032864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// instructions and relocation information. The constructor makes 1033864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// sure that there is enough space and (in debug mode) the destructor 1034864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// checks that we did not generate too much. 1035864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass EnsureSpace BASE_EMBEDDED { 1036864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 1037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { 1038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (assembler_->buffer_overflow()) assembler_->GrowBuffer(); 1039864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG 1040864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org space_before_ = assembler_->available_space(); 1041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 1042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1043864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1044864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG 1045864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ~EnsureSpace() { 1046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int bytes_generated = space_before_ - assembler_->available_space(); 1047e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(bytes_generated < assembler_->kGap); 1048864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1049864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 1050864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1051864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 1052864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Assembler* assembler_; 1053864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG 1054864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int space_before_; 1055864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 1056864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 1057864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1058864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} } // namespace v8::internal 1059864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif // V8_X87_ASSEMBLER_X87_H_ 1061