1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright (c) 1994-2006 Sun Microsystems Inc. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// All Rights Reserved. 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Redistribution and use in source and binary forms, with or without 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modification, are permitted provided that the following conditions are 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// met: 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Redistributions of source code must retain the above copyright notice, 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// this list of conditions and the following disclaimer. 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Redistribution in binary form must reproduce the above copyright 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// notice, this list of conditions and the following disclaimer in the 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// documentation and/or other materials provided with the distribution. 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Neither the name of Sun Microsystems or the names of contributors may 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// be used to endorse or promote products derived from this software without 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// specific prior written permission. 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The original source code covered by the above license above has been 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modified significantly by Google Inc. 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A light-weight IA32 Assembler. 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_X87_ASSEMBLER_X87_H_ 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_X87_ASSEMBLER_X87_H_ 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <deque> 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/assembler.h" 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/isolate.h" 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/utils.h" 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define GENERAL_REGISTERS(V) \ 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(eax) \ 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(ecx) \ 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(edx) \ 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(ebx) \ 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(esp) \ 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(ebp) \ 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(esi) \ 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(edi) 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_GENERAL_REGISTERS(V) \ 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(eax) \ 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(ecx) \ 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(edx) \ 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(ebx) \ 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(esi) \ 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(edi) 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DOUBLE_REGISTERS(V) \ 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_0) \ 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_1) \ 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_2) \ 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_3) \ 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_4) \ 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_5) \ 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_6) \ 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_7) 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 77537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#define FLOAT_REGISTERS DOUBLE_REGISTERS 78537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_0) \ 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_1) \ 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_2) \ 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_3) \ 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_4) \ 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(stX_5) 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CPU Registers. 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 1) We would prefer to use an enum, but enum values are assignment- 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// compatible with int, which has caused code-generation bugs. 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 2) We would prefer to use a class instead of a struct but we don't like 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the register initialization to depend on the particular initialization 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// order (which appears to be different on OS X, Linux, and Windows for the 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// installed versions of C++ we tried). Using a struct permits C-style 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// "initialization". Also, the Register objects cannot be const as this 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// forces initialization stubs in MSVC, making us dependent on initialization 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// order. 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3) By not using an enum, we are possibly preventing the compiler from 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// doing certain constant folds, which may significantly reduce the 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// code generated for some assembly instructions (because they boil down 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// to a few constants). If this is a problem, we could change the code 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// such that we use an enum in optimized mode, and the struct in debug 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// mode. This way we get the compile-time error checking in debug mode 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and best performance in optimized code. 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct Register { 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Code { 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R, 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GENERAL_REGISTERS(REGISTER_CODE) 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kAfterLast, 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCode_no_reg = -1 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kNumRegisters = Code::kAfterLast; 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Register from_code(int code) { 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(code >= 0); 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(code < kNumRegisters); 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register r = {code}; 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return r; 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is(Register reg) const { return reg_code == reg.reg_code; } 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int code() const { 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bit() const { 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 1 << reg_code; 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_byte_register() const { return reg_code <= 3; } 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unfortunately we can't make this private in a struct. 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochGENERAL_REGISTERS(DECLARE_REGISTER) 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register no_reg = {Register::kCode_no_reg}; 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 14821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochstatic const bool kSimpleFPAliasing = true; 14921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 150537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochstruct X87Register { 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Code { 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REGISTER_CODE(R) kCode_##R, 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DOUBLE_REGISTERS(REGISTER_CODE) 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef REGISTER_CODE 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kAfterLast, 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCode_no_reg = -1 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMaxNumRegisters = Code::kAfterLast; 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kMaxNumAllocatableRegisters = 6; 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 162537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch static X87Register from_code(int code) { 163537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch X87Register result = {code}; 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; } 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int code() const { 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_valid()); 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reg_code; 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 174537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch bool is(X87Register reg) const { return reg_code == reg.reg_code; } 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_code; 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 179537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochtypedef X87Register FloatRegister; 180537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 181537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochtypedef X87Register DoubleRegister; 182537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 183537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch// TODO(x87) Define SIMD registers. 184537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochtypedef X87Register Simd128Register; 185537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_REGISTER(R) \ 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const DoubleRegister R = {DoubleRegister::kCode_##R}; 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDOUBLE_REGISTERS(DECLARE_REGISTER) 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_REGISTER 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg}; 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum Condition { 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // any value < 0 is considered no_condition 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch no_condition = -1, 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch overflow = 0, 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch no_overflow = 1, 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch below = 2, 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch above_equal = 3, 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch equal = 4, 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_equal = 5, 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch below_equal = 6, 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch above = 7, 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negative = 8, 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch positive = 9, 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch parity_even = 10, 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch parity_odd = 11, 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch less = 12, 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch greater_equal = 13, 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch less_equal = 14, 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch greater = 15, 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // aliases 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch carry = below, 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_carry = above_equal, 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zero = equal, 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_zero = not_equal, 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sign = negative, 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_sign = positive 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Returns the equivalent of !cc. 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Negation of the default no_condition (-1) results in a non-default 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// no_condition value (-2). As long as tests for no_condition check 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// for condition < 0, this will work as expected. 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline Condition NegateCondition(Condition cc) { 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<Condition>(cc ^ 1); 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Commute a condition such that {a cond b == b cond' a}. 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline Condition CommuteCondition(Condition cc) { 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (cc) { 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case below: 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return above; 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case above: 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return below; 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case above_equal: 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return below_equal; 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case below_equal: 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return above_equal; 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case less: 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return greater; 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case greater: 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return less; 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case greater_equal: 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return less_equal; 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case less_equal: 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return greater_equal; 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return cc; 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum RoundingMode { 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundToNearest = 0x0, 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundDown = 0x1, 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundUp = 0x2, 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kRoundToZero = 0x3 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ----------------------------------------------------------------------------- 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Machine instruction Immediates 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Immediate BASE_EMBEDDED { 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline explicit Immediate(int x); 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline explicit Immediate(const ExternalReference& ext); 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline explicit Immediate(Handle<Object> handle); 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline explicit Immediate(Smi* value); 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline explicit Immediate(Address addr); 2751b268ca467c924004286c97bac133db489cf43d0Ben Murdoch inline explicit Immediate(Address x, RelocInfo::Mode rmode); 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Immediate CodeRelativeOffset(Label* label) { 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Immediate(label); 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_zero() const { return x_ == 0 && RelocInfo::IsNone(rmode_); } 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_int8() const { 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return -128 <= x_ && x_ < 128 && RelocInfo::IsNone(rmode_); 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2851b268ca467c924004286c97bac133db489cf43d0Ben Murdoch bool is_uint8() const { 2861b268ca467c924004286c97bac133db489cf43d0Ben Murdoch return v8::internal::is_uint8(x_) && RelocInfo::IsNone(rmode_); 2871b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_int16() const { 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return -32768 <= x_ && x_ < 32768 && RelocInfo::IsNone(rmode_); 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2911b268ca467c924004286c97bac133db489cf43d0Ben Murdoch bool is_uint16() const { 2921b268ca467c924004286c97bac133db489cf43d0Ben Murdoch return v8::internal::is_uint16(x_) && RelocInfo::IsNone(rmode_); 2931b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline explicit Immediate(Label* value); 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int x_; 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode_; 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class Operand; 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class Assembler; 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class MacroAssembler; 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ----------------------------------------------------------------------------- 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Machine instruction Operands 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum ScaleFactor { 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_1 = 0, 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_2 = 1, 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_4 = 2, 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_8 = 3, 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_int_size = times_4, 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_half_pointer_size = times_2, 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_pointer_size = times_4, 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_twice_pointer_size = times_8 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Operand BASE_EMBEDDED { 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // reg 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(explicit Operand(Register reg)); 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [disp/r] 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(explicit Operand(int32_t disp, RelocInfo::Mode rmode)); 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [disp/r] 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(explicit Operand(Immediate imm)); 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [base + disp/r] 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit Operand(Register base, int32_t disp, 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode = RelocInfo::NONE32); 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [base + index*scale + disp/r] 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit Operand(Register base, 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register index, 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScaleFactor scale, 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t disp, 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode = RelocInfo::NONE32); 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [index*scale + disp/r] 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit Operand(Register index, 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScaleFactor scale, 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t disp, 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode = RelocInfo::NONE32); 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Operand JumpTable(Register index, ScaleFactor scale, Label* table) { 351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand(index, scale, reinterpret_cast<int32_t>(table), 352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::INTERNAL_REFERENCE); 353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Operand StaticVariable(const ExternalReference& ext) { 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Operand(reinterpret_cast<int32_t>(ext.address()), 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::EXTERNAL_REFERENCE); 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Operand StaticArray(Register index, 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScaleFactor scale, 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ExternalReference& arr) { 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()), 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::EXTERNAL_REFERENCE); 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Operand ForCell(Handle<Cell> cell) { 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference embedding_raw_address; 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Operand(reinterpret_cast<int32_t>(cell.location()), 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::CELL); 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Operand ForRegisterPlusImmediate(Register base, Immediate imm) { 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Operand(base, imm.x_, imm.rmode_); 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns true if this Operand is a wrapper for the specified register. 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_reg(Register reg) const; 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns true if this Operand is a wrapper for one register. 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_reg_only() const; 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Asserts that this Operand is a wrapper for one register and returns the 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // register. 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg() const; 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set the ModRM byte without an encoded 'reg' register. The 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // register is encoded later as part of the emit_operand operation. 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void set_modrm(int mod, Register rm); 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void set_sib(ScaleFactor scale, Register index, Register base); 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void set_disp8(int8_t disp); 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void set_dispr(int32_t disp, RelocInfo::Mode rmode); 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte buf_[6]; 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The number of bytes in buf_. 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned int len_; 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Only valid if len_ > 4. 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode_; 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class Assembler; 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class MacroAssembler; 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ----------------------------------------------------------------------------- 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A Displacement describes the 32bit immediate field of an instruction which 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// may be used together with a Label in order to refer to a yet unknown code 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// position. Displacements stored in the instruction stream are used to describe 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the instruction and to chain a list of instructions using the same Label. 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A Displacement contains 2 different fields: 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// next field: position of next displacement in the chain (0 = end of list) 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// type field: instruction type 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A next value of null (0) indicates the end of a chain (note that there can 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// be no displacement at position zero, because there is always at least one 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// instruction byte before the displacement). 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Displacement _data field layout 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// |31.....2|1......0| 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// [ next | type | 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Displacement BASE_EMBEDDED { 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Type { UNCONDITIONAL_JUMP, CODE_RELATIVE, OTHER, CODE_ABSOLUTE }; 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int data() const { return data_; } 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type type() const { return TypeField::decode(data_); } 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void next(Label* L) const { 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int n = NextField::decode(data_); 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch n > 0 ? L->link_to(n) : L->Unuse(); 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void link_to(Label* L) { init(L, type()); } 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit Displacement(int data) { data_ = data; } 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Displacement(Label* L, Type type) { init(L, type); } 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void print() { 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"), 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NextField::decode(data_)); 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int data_; 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class TypeField: public BitField<Type, 0, 2> {}; 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class NextField: public BitField<int, 2, 32-2> {}; 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void init(Label* L, Type type); 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Assembler : public AssemblerBase { 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We check before assembling an instruction that there is sufficient 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // space to write an instruction and its relocation information. 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The relocation writer's position must be kGap bytes above the end of 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the generated instructions. This leaves enough space for the 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // longest possible ia32 instruction, 15 bytes, and the longest possible 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // relocation information encoding, RelocInfoWriter::kMaxLength == 16. 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (There is a 15 byte limit on ia32 instruction length that rules out some 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // otherwise valid instructions.) 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This allows for a single, fast space check per instruction. 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kGap = 32; 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create an assembler. Instructions and relocation information are emitted 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // into a buffer, with the instructions starting from the beginning and the 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // relocation information starting from the end of the buffer. See CodeDesc 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for a detailed comment on the layout (globals.h). 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the provided buffer is NULL, the assembler allocates and grows its own 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // buffer, and buffer_size determines the initial buffer size. The buffer is 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // owned by the assembler and deallocated upon destruction of the assembler. 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the provided buffer is not NULL, the assembler uses the provided buffer 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for code generation and assumes its size to be buffer_size. If the buffer 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is too small, a fatal error occurs. No deallocation of the buffer is done 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // upon destruction of the assembler. 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(vitalyr): the assembler does not need an isolate. 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler(Isolate* isolate, void* buffer, int buffer_size); 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~Assembler() { } 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // GetCode emits any pending (non-emitted) code and fills the descriptor 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // desc. GetCode() is idempotent; it returns the same result if no other 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Assembler functions are invoked in between GetCode() calls. 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GetCode(CodeDesc* desc); 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Read/Modify the code target in the branch/call instruction at pc. 494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline static Address target_address_at(Address pc, Address constant_pool); 495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline static void set_target_address_at( 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address constant_pool, Address target, 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline Address target_address_at(Address pc, Code* code) { 499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return target_address_at(pc, constant_pool); 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void set_target_address_at( 503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Code* code, Address target, 504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED) { 505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_target_address_at(isolate, pc, constant_pool, target); 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the code target address at a call site from the return address 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of that call in the instruction stream. 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline static Address target_address_from_return_address(Address pc); 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This sets the branch destination (which is in the instruction on x86). 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is for calls and branches within generated code. 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline static void deserialization_set_special_target_at( 516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address instruction_payload, Code* code, 517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address target) { 518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_target_address_at(isolate, instruction_payload, code, target); 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This sets the internal reference at the pc. 522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline static void deserialization_set_target_internal_reference_at( 523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address target, 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kSpecialTargetSize = kPointerSize; 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Distance between the address of the code target in the call instruction 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and the return address 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kCallTargetAddressOffset = kPointerSize; 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kCallInstructionLength = 5; 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The debug break slot must be able to contain a call instruction. 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kDebugBreakSlotLength = kCallInstructionLength; 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Distance between start of patched debug break slot and the emitted address 538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to jump to. 539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kPatchDebugBreakSlotAddressOffset = 1; // JMP imm32. 540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // One byte opcode for test al, 0xXX. 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kTestAlByte = 0xA8; 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // One byte opcode for nop. 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kNopByte = 0x90; 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // One byte opcode for a short unconditional jump. 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kJmpShortOpcode = 0xEB; 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // One byte prefix for a short conditional jump. 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kJccShortPrefix = 0x70; 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kJncShortOpcode = kJccShortPrefix | not_carry; 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kJcShortOpcode = kJccShortPrefix | carry; 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kJnzShortOpcode = kJccShortPrefix | not_zero; 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const byte kJzShortOpcode = kJccShortPrefix | zero; 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // --------------------------------------------------------------------------- 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Code generation 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - function names correspond one-to-one to ia32 instruction mnemonics 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - unless specified otherwise, instructions operate on 32bit operands 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - instructions on 8bit (byte) operands/registers have a trailing '_b' 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - instructions on 16bit (word) operands/registers have a trailing '_w' 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // - naming conflicts with C++ keywords are resolved via a trailing '_' 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // NOTE ON INTERFACE: Currently, the interface is not very consistent 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in the sense that some operations (e.g. mov()) can be called in more 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the one way to generate the same instruction: The Register argument 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // can in some cases be replaced with an Operand(Register) argument. 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This should be cleaned up and made more orthogonal. The questions 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is: should we always use Operands instead of Registers where an 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Operand is possible, or should we have a Register (overloaded) form 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instead? We must be careful to make sure that the selected instruction 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is obvious from the parameters to avoid hard-to-find code generation 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bugs. 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Insert the smallest number of nop instructions 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // possible to align the pc offset to a multiple 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of m. m must be a power of 2. 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Align(int m); 580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Insert the smallest number of zero bytes possible to align the pc offset 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to a mulitple of m. m must be a power of 2 (>= 2). 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DataAlign(int m); 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Nop(int bytes = 1); 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Aligns code to something that's optimal for a jump target for the platform. 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CodeTargetAlign(); 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Stack 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pushad(); 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void popad(); 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pushfd(); 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void popfd(); 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void push(const Immediate& x); 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void push_imm32(int32_t imm32); 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void push(Register src); 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void push(const Operand& src); 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pop(Register dst); 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pop(const Operand& dst); 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void enter(const Immediate& size); 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void leave(); 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Moves 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov_b(Register dst, Register src) { mov_b(dst, Operand(src)); } 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov_b(Register dst, const Operand& src); 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov_b(Register dst, int8_t imm8) { mov_b(Operand(dst), imm8); } 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov_b(const Operand& dst, int8_t imm8); 610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mov_b(const Operand& dst, const Immediate& src); 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov_b(const Operand& dst, Register src); 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov_w(Register dst, const Operand& src); 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov_w(const Operand& dst, Register src); 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov_w(const Operand& dst, int16_t imm16); 616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void mov_w(const Operand& dst, const Immediate& src); 617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov(Register dst, int32_t imm32); 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov(Register dst, const Immediate& x); 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov(Register dst, Handle<Object> handle); 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov(Register dst, const Operand& src); 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov(Register dst, Register src); 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov(const Operand& dst, const Immediate& x); 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov(const Operand& dst, Handle<Object> handle); 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov(const Operand& dst, Register src); 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movsx_b(Register dst, Register src) { movsx_b(dst, Operand(src)); } 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movsx_b(Register dst, const Operand& src); 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movsx_w(Register dst, Register src) { movsx_w(dst, Operand(src)); } 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movsx_w(Register dst, const Operand& src); 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movzx_b(Register dst, Register src) { movzx_b(dst, Operand(src)); } 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movzx_b(Register dst, const Operand& src); 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movzx_w(Register dst, Register src) { movzx_w(dst, Operand(src)); } 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void movzx_w(Register dst, const Operand& src); 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Flag management. 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cld(); 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Repetitive string instructions. 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void rep_movs(); 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void rep_stos(); 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void stos(); 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Exchange 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xchg(Register dst, Register src); 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xchg(Register dst, const Operand& src); 651537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch void xchg_b(Register reg, const Operand& op); 652537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch void xchg_w(Register reg, const Operand& op); 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 65421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // Lock prefix 65521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch void lock(); 65621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 65721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // CompareExchange 65821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch void cmpxchg(const Operand& dst, Register src); 65921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch void cmpxchg_b(const Operand& dst, Register src); 66021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch void cmpxchg_w(const Operand& dst, Register src); 66121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Arithmetics 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void adc(Register dst, int32_t imm32); 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void adc(Register dst, const Operand& src); 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void add(Register dst, Register src) { add(dst, Operand(src)); } 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void add(Register dst, const Operand& src); 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void add(const Operand& dst, Register src); 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void add(Register dst, const Immediate& imm) { add(Operand(dst), imm); } 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void add(const Operand& dst, const Immediate& x); 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void and_(Register dst, int32_t imm32); 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void and_(Register dst, const Immediate& x); 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void and_(Register dst, Register src) { and_(dst, Operand(src)); } 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void and_(Register dst, const Operand& src); 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void and_(const Operand& dst, Register src); 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void and_(const Operand& dst, const Immediate& x); 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6791b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void cmpb(Register reg, Immediate imm8) { cmpb(Operand(reg), imm8); } 6801b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void cmpb(const Operand& op, Immediate imm8); 681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmpb(Register reg, const Operand& op); 682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmpb(const Operand& op, Register reg); 6831b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void cmpb(Register dst, Register src) { cmpb(Operand(dst), src); } 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmpb_al(const Operand& op); 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmpw_ax(const Operand& op); 6861b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void cmpw(const Operand& dst, Immediate src); 6871b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void cmpw(Register dst, Immediate src) { cmpw(Operand(dst), src); } 6881b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void cmpw(Register dst, const Operand& src); 6891b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void cmpw(Register dst, Register src) { cmpw(Operand(dst), src); } 6901b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void cmpw(const Operand& dst, Register src); 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmp(Register reg, int32_t imm32); 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmp(Register reg, Handle<Object> handle); 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmp(Register reg0, Register reg1) { cmp(reg0, Operand(reg1)); } 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmp(Register reg, const Operand& op); 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmp(Register reg, const Immediate& imm) { cmp(Operand(reg), imm); } 696342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch void cmp(const Operand& op, Register reg); 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmp(const Operand& op, const Immediate& imm); 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cmp(const Operand& op, Handle<Object> handle); 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dec_b(Register dst); 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dec_b(const Operand& dst); 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dec(Register dst); 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dec(const Operand& dst); 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cdq(); 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void idiv(Register src) { idiv(Operand(src)); } 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void idiv(const Operand& src); 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void div(Register src) { div(Operand(src)); } 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void div(const Operand& src); 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Signed multiply instructions. 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void imul(Register src); // edx:eax = eax * src. 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void imul(Register dst, Register src) { imul(dst, Operand(src)); } 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void imul(Register dst, const Operand& src); // dst = dst * src. 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void imul(Register dst, Register src, int32_t imm32); // dst = src * imm32. 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void imul(Register dst, const Operand& src, int32_t imm32); 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void inc(Register dst); 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void inc(const Operand& dst); 722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void lea(Register dst, const Operand& src); 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unsigned multiply instruction. 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mul(Register src); // edx:eax = eax * reg. 727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void neg(Register dst); 729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void neg(const Operand& dst); 730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void not_(Register dst); 732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void not_(const Operand& dst); 733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void or_(Register dst, int32_t imm32); 735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void or_(Register dst, Register src) { or_(dst, Operand(src)); } 736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void or_(Register dst, const Operand& src); 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void or_(const Operand& dst, Register src); 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void or_(Register dst, const Immediate& imm) { or_(Operand(dst), imm); } 739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void or_(const Operand& dst, const Immediate& x); 740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void rcl(Register dst, uint8_t imm8); 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void rcr(Register dst, uint8_t imm8); 743958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 744958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ror(Register dst, uint8_t imm8) { ror(Operand(dst), imm8); } 745958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ror(const Operand& dst, uint8_t imm8); 746958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ror_cl(Register dst) { ror_cl(Operand(dst)); } 747958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ror_cl(const Operand& dst); 748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sar(Register dst, uint8_t imm8) { sar(Operand(dst), imm8); } 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sar(const Operand& dst, uint8_t imm8); 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sar_cl(Register dst) { sar_cl(Operand(dst)); } 752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sar_cl(const Operand& dst); 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sbb(Register dst, const Operand& src); 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shl(Register dst, uint8_t imm8) { shl(Operand(dst), imm8); } 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shl(const Operand& dst, uint8_t imm8); 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shl_cl(Register dst) { shl_cl(Operand(dst)); } 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shl_cl(const Operand& dst); 7601b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void shld(Register dst, Register src, uint8_t shift); 7611b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void shld_cl(Register dst, Register src); 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shr(Register dst, uint8_t imm8) { shr(Operand(dst), imm8); } 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shr(const Operand& dst, uint8_t imm8); 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shr_cl(Register dst) { shr_cl(Operand(dst)); } 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void shr_cl(const Operand& dst); 7671b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void shrd(Register dst, Register src, uint8_t shift); 7681b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void shrd_cl(Register dst, Register src) { shrd_cl(Operand(dst), src); } 7691b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void shrd_cl(const Operand& dst, Register src); 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sub(Register dst, const Immediate& imm) { sub(Operand(dst), imm); } 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sub(const Operand& dst, const Immediate& x); 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sub(Register dst, Register src) { sub(dst, Operand(src)); } 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sub(Register dst, const Operand& src); 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sub(const Operand& dst, Register src); 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void test(Register reg, const Immediate& imm); 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void test(Register reg0, Register reg1) { test(reg0, Operand(reg1)); } 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void test(Register reg, const Operand& op); 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void test(const Operand& op, const Immediate& imm); 7811b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void test(const Operand& op, Register reg) { test(reg, op); } 7821b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void test_b(Register reg, const Operand& op); 7831b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void test_b(Register reg, Immediate imm8); 7841b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void test_b(const Operand& op, Immediate imm8); 7851b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void test_b(const Operand& op, Register reg) { test_b(reg, op); } 7861b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void test_b(Register dst, Register src) { test_b(dst, Operand(src)); } 7871b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void test_w(Register reg, const Operand& op); 7881b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void test_w(Register reg, Immediate imm16); 7891b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void test_w(const Operand& op, Immediate imm16); 7901b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void test_w(const Operand& op, Register reg) { test_w(reg, op); } 7911b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void test_w(Register dst, Register src) { test_w(dst, Operand(src)); } 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xor_(Register dst, int32_t imm32); 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xor_(Register dst, Register src) { xor_(dst, Operand(src)); } 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xor_(Register dst, const Operand& src); 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xor_(const Operand& dst, Register src); 797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xor_(Register dst, const Immediate& imm) { xor_(Operand(dst), imm); } 798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void xor_(const Operand& dst, const Immediate& x); 799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bit operations. 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bt(const Operand& dst, Register src); 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bts(Register dst, Register src) { bts(Operand(dst), src); } 803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bts(const Operand& dst, Register src); 804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bsr(Register dst, Register src) { bsr(dst, Operand(src)); } 805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bsr(Register dst, const Operand& src); 806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsf(Register dst, Register src) { bsf(dst, Operand(src)); } 807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void bsf(Register dst, const Operand& src); 808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Miscellaneous 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void hlt(); 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void int3(); 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void nop(); 813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ret(int imm16); 814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ud2(); 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Label operations & relative jumps (PPUM Appendix D) 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Takes a branch opcode (cc) and a label (L) and generates 819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // either a backward branch or a forward branch and links it 820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to the label fixup chain. Usage: 821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Label L; // unbound label 823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // j(cc, &L); // forward branch to unbound label 824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bind(&L); // bind label to the current pc 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // j(cc, &L); // backward branch to bound label 826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bind(&L); // illegal: a label may be bound only once 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Note: The same Label can be used for forward and backward branches 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // but it may be bound only once. 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bind(Label* L); // binds an unbound label L to the current code position 832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calls 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void call(Label* L); 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void call(byte* entry, RelocInfo::Mode rmode); 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int CallSize(const Operand& adr); 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void call(Register reg) { call(Operand(reg)); } 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void call(const Operand& adr); 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int CallSize(Handle<Code> code, RelocInfo::Mode mode); 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void call(Handle<Code> code, 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode, 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId id = TypeFeedbackId::None()); 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Jumps 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // unconditional jump to L 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void jmp(Label* L, Label::Distance distance = Label::kFar); 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void jmp(byte* entry, RelocInfo::Mode rmode); 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void jmp(Register reg) { jmp(Operand(reg)); } 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void jmp(const Operand& adr); 850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void jmp(Handle<Code> code, RelocInfo::Mode rmode); 851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Conditional jumps 853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void j(Condition cc, 854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* L, 855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance distance = Label::kFar); 856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void j(Condition cc, byte* entry, RelocInfo::Mode rmode); 857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void j(Condition cc, Handle<Code> code, 858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::Mode rmode = RelocInfo::CODE_TARGET); 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Floating-point operations 861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fld(int i); 862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fstp(int i); 863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fld1(); 865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fldz(); 866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fldpi(); 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fldln2(); 868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fld_s(const Operand& adr); 870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fld_d(const Operand& adr); 871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fstp_s(const Operand& adr); 873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fst_s(const Operand& adr); 874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fstp_d(const Operand& adr); 875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fst_d(const Operand& adr); 876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fild_s(const Operand& adr); 878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fild_d(const Operand& adr); 879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fist_s(const Operand& adr); 881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fistp_s(const Operand& adr); 883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fistp_d(const Operand& adr); 884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The fisttp instructions require SSE3. 886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fisttp_s(const Operand& adr); 887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fisttp_d(const Operand& adr); 888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fabs(); 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fchs(); 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fsqrt(); 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fcos(); 893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fsin(); 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fptan(); 895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fyl2x(); 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void f2xm1(); 897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fscale(); 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fninit(); 899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fadd(int i); 901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fadd_i(int i); 902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fadd_d(const Operand& adr); 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fsub(int i); 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fsub_i(int i); 905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void fsub_d(const Operand& adr); 906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void fsubr_d(const Operand& adr); 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fmul(int i); 908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void fmul_d(const Operand& adr); 909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fmul_i(int i); 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fdiv(int i); 911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void fdiv_d(const Operand& adr); 912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void fdivr_d(const Operand& adr); 913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fdiv_i(int i); 914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fisub_s(const Operand& adr); 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void faddp(int i = 1); 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fsubp(int i = 1); 919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void fsubr(int i = 1); 920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fsubrp(int i = 1); 921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fmulp(int i = 1); 922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fdivp(int i = 1); 923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fprem(); 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fprem1(); 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fxch(int i = 1); 927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fincstp(); 928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ffree(int i = 0); 929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ftst(); 931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fxam(); 932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fucomp(int i); 933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fucompp(); 934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fucomi(int i); 935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fucomip(); 936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fcompp(); 937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fnstsw_ax(); 938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fldcw(const Operand& adr); 939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fnstcw(const Operand& adr); 940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fwait(); 941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fnclex(); 942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void fnsave(const Operand& adr); 943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void frstor(const Operand& adr); 944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void frndint(); 946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void sahf(); 948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void setcc(Condition cc, Register reg); 949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void cpuid(); 951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(lrn): Need SFENCE for movnt? 953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the code size generated from label to here. 955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int SizeOfCodeGeneratedSince(Label* label) { 956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return pc_offset() - label->pos(); 957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Mark generator continuation. 960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordGeneratorContinuation(); 961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mark address of a debug break slot. 963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordDebugBreakSlot(RelocInfo::Mode mode); 964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Record a comment relocation entry that can be used by a disassembler. 966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use --code-comments to enable. 967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordComment(const char* msg); 968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Record a deoptimization reason that can be used by a log or cpu profiler. 970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use --trace-deopt to enable. 971537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch void RecordDeoptReason(const int reason, int raw_position, int id); 972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Writes a single byte or word of data in the code stream. Used for 974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inline tables, e.g., jump-tables. 975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void db(uint8_t data); 976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void dd(uint32_t data); 977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dq(uint64_t data); 978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dp(uintptr_t data) { dd(data); } 979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void dd(Label* label); 980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if there is less than kGap bytes available in the buffer. 982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If this is the case, we need to grow the buffer before emitting 983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // an instruction or relocation information. 984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool buffer_overflow() const { 985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return pc_ >= reloc_info_writer.pos() - kGap; 986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get the number of bytes available in the buffer. 989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline int available_space() const { return reloc_info_writer.pos() - pc_; } 990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsNop(Address addr); 992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9931b268ca467c924004286c97bac133db489cf43d0Ben Murdoch AssemblerPositionsRecorder* positions_recorder() { 9941b268ca467c924004286c97bac133db489cf43d0Ben Murdoch return &positions_recorder_; 9951b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } 996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int relocation_writer_size() { 998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (buffer_ + buffer_size_) - reloc_info_writer.pos(); 999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Avoid overflows for displacements etc. 1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kMaximalBufferSize = 512*MB; 1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte byte_at(int pos) { return buffer_[pos]; } 1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_byte_at(int pos, byte value) { buffer_[pos] = value; } 1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PatchConstantPoolAccessInstruction(int pc_offset, int offset, 1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Access access, 1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolEntry::Type type) { 1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // No embedded constant pool support. 1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte* addr_at(int pos) { return buffer_ + pos; } 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t long_at(int pos) { 1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return *reinterpret_cast<uint32_t*>(addr_at(pos)); 1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void long_at_put(int pos, uint32_t x) { 1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; 1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // code emission 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GrowBuffer(); 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emit(uint32_t x); 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emit(Handle<Object> handle); 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emit(uint32_t x, 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode, 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId id = TypeFeedbackId::None()); 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emit(Handle<Code> code, 1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode, 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId id = TypeFeedbackId::None()); 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emit(const Immediate& x); 10371b268ca467c924004286c97bac133db489cf43d0Ben Murdoch inline void emit_b(Immediate x); 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emit_w(const Immediate& x); 1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void emit_q(uint64_t x); 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit the code-object-relative offset of the label's position 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emit_code_relative_offset(Label* label); 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instruction generation 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_arith_b(int op1, int op2, Register dst, int imm8); 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81) 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // with a given destination expression and an immediate operand. It attempts 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to use the shortest encoding possible. 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // sel specifies the /n in the modrm byte (see the Intel PRM). 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_arith(int sel, Operand dst, const Immediate& x); 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_operand(Register reg, const Operand& adr); 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void emit_label(Label* label); 1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void emit_farith(int b1, int b2, int i); 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // labels 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void print(Label* L); 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void bind_to(Label* L, int pos); 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // displacements 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Displacement disp_at(Label* L); 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void disp_at_put(Label* L, Displacement disp); 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emit_disp(Label* L, Displacement::Type type); 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void emit_near_disp(Label* L); 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // record reloc info for current pc_ 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class CodePatcher; 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class EnsureSpace; 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Internal reference positions, required for (potential) patching in 1076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // GrowBuffer(); contains only those internal references whose labels 1077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // are already bound. 1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch std::deque<int> internal_reference_positions_; 1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // code generation 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfoWriter reloc_info_writer; 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10831b268ca467c924004286c97bac133db489cf43d0Ben Murdoch AssemblerPositionsRecorder positions_recorder_; 10841b268ca467c924004286c97bac133db489cf43d0Ben Murdoch friend class AssemblerPositionsRecorder; 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helper class that ensures that there is enough space for generating 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// instructions and relocation information. The constructor makes 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// sure that there is enough space and (in debug mode) the destructor 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// checks that we did not generate too much. 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass EnsureSpace BASE_EMBEDDED { 1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { 1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (assembler_->buffer_overflow()) assembler_->GrowBuffer(); 1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch space_before_ = assembler_->available_space(); 1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~EnsureSpace() { 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bytes_generated = space_before_ - assembler_->available_space(); 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(bytes_generated < assembler_->kGap); 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler* assembler_; 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int space_before_; 1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_X87_ASSEMBLER_X87_H_ 1119