19085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Copyright (c) 1994-2006 Sun Microsystems Inc. 29085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// All Rights Reserved. 39085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// 45ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// Redistribution and use in source and binary forms, with or without 55ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// modification, are permitted provided that the following conditions are 65ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// met: 75ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// 89085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// - Redistributions of source code must retain the above copyright notice, 99085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// this list of conditions and the following disclaimer. 109085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// 119085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// - Redistribution in binary form must reproduce the above copyright 129085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// notice, this list of conditions and the following disclaimer in the 139085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// documentation and/or other materials provided with the distribution. 149085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// 159085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// - Neither the name of Sun Microsystems or the names of contributors may 169085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// be used to endorse or promote products derived from this software without 179085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// specific prior written permission. 189085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// 199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 209085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 219085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 229085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 239085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 249085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 259085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 269085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 279085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 289085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 299085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 319085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// The original source code covered by the above license above has been 329085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// modified significantly by Google Inc. 3356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 349085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 359085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// A lightweight X64 Assembler. 369085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 379085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifndef V8_X64_ASSEMBLER_X64_H_ 389085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define V8_X64_ASSEMBLER_X64_H_ 399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 40196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/serialize.h" 41c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 4271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 4371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 45e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org// Utility functions 46e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// CPU Registers. 489085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// 499085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// 1) We would prefer to use an enum, but enum values are assignment- 509085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// compatible with int, which has caused code-generation bugs. 519085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// 529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// 2) We would prefer to use a class instead of a struct but we don't like 539085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// the register initialization to depend on the particular initialization 549085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// order (which appears to be different on OS X, Linux, and Windows for the 559085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// installed versions of C++ we tried). Using a struct permits C-style 569085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// "initialization". Also, the Register objects cannot be const as this 579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// forces initialization stubs in MSVC, making us dependent on initialization 589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// order. 599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// 609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// 3) By not using an enum, we are possibly preventing the compiler from 619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// doing certain constant folds, which may significantly reduce the 629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// code generated for some assembly instructions (because they boil down 639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// to a few constants). If this is a problem, we could change the code 649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// such that we use an enum in optimized mode, and the struct in debug 659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// mode. This way we get the compile-time error checking in debug mode 669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// and best performance in optimized code. 679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// 689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgstruct Register { 70a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // The non-allocatable registers are: 71a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // rsp - stack pointer 72a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // rbp - frame pointer 73a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // r10 - fixed scratch register 74b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // r12 - smi constant register 75a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // r13 - root register 76935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org static const int kMaxNumAllocatableRegisters = 11; 77a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org static int NumAllocatableRegisters() { 78a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return kMaxNumAllocatableRegisters; 79a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 80a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org static const int kNumRegisters = 16; 81a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 82c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org static int ToAllocationIndex(Register reg) { 833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return kAllocationIndexByRegisterCode[reg.code()]; 84c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 85c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 86c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org static Register FromAllocationIndex(int index) { 87a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); 883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register result = { kRegisterCodeByAllocationIndex[index] }; 89c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return result; 90c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 91c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 92a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org static const char* AllocationIndexToString(int index) { 93a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); 94a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const char* const names[] = { 95a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "rax", 96a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "rbx", 97c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org "rdx", 98c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org "rcx", 99935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org "rsi", 100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "rdi", 101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "r8", 102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "r9", 103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "r11", 104c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org "r14", 105b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org "r15" 106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org }; 107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return names[index]; 108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org static Register from_code(int code) { 111eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org Register r = { code }; 112755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org return r; 113755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org } 114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } 1154a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org bool is(Register reg) const { return code_ == reg.code_; } 11656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org // rax, rbx, rcx and rdx are byte registers, the rest are not. 11756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org bool is_byte_register() const { return code_ <= 3; } 1184a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org int code() const { 1199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org ASSERT(is_valid()); 1209085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return code_; 1219085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 1224a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org int bit() const { 123eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org return 1 << code_; 1249085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 1259085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1265aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org // Return the high bit of the register code as a 0 or 1. Used often 1275aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org // when constructing the REX prefix byte. 1285aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org int high_bit() const { 1295aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org return code_ >> 3; 1305aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org } 1315aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org // Return the 3 low bits of the register code. Used when encoding registers 1325aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org // in modR/M, SIB, and opcode bytes. 1335aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org int low_bits() const { 1345aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org return code_ & 0x7; 1355aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org } 1365aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 1375c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Unfortunately we can't make this private in a struct when initializing 1385c838251403b0be9a882540f1922577abba4c872ager@chromium.org // by assignment. 1399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org int code_; 1400ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 141c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org private: 142a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org static const int kRegisterCodeByAllocationIndex[kMaxNumAllocatableRegisters]; 1433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org static const int kAllocationIndexByRegisterCode[kNumRegisters]; 1449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}; 1459085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1461456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_rax_Code = 0; 1471456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_rcx_Code = 1; 1481456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_rdx_Code = 2; 1491456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_rbx_Code = 3; 1501456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_rsp_Code = 4; 1511456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_rbp_Code = 5; 1521456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_rsi_Code = 6; 1531456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_rdi_Code = 7; 1541456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_r8_Code = 8; 1551456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_r9_Code = 9; 1561456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_r10_Code = 10; 1571456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_r11_Code = 11; 1581456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_r12_Code = 12; 1591456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_r13_Code = 13; 1601456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_r14_Code = 14; 1611456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_r15_Code = 15; 1621456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int kRegister_no_reg_Code = -1; 1631456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register rax = { kRegister_rax_Code }; 1651456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register rcx = { kRegister_rcx_Code }; 1661456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register rdx = { kRegister_rdx_Code }; 1671456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register rbx = { kRegister_rbx_Code }; 1681456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register rsp = { kRegister_rsp_Code }; 1691456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register rbp = { kRegister_rbp_Code }; 1701456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register rsi = { kRegister_rsi_Code }; 1711456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register rdi = { kRegister_rdi_Code }; 1721456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r8 = { kRegister_r8_Code }; 1731456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r9 = { kRegister_r9_Code }; 1741456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r10 = { kRegister_r10_Code }; 1751456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r11 = { kRegister_r11_Code }; 1761456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r12 = { kRegister_r12_Code }; 1771456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r13 = { kRegister_r13_Code }; 1781456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r14 = { kRegister_r14_Code }; 1791456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register r15 = { kRegister_r15_Code }; 1801456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst Register no_reg = { kRegister_no_reg_Code }; 1815aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 182ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org#ifdef _WIN64 183ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Windows calling convention 1846b0169a99e75f4821ce4168e5e0d3cc8f6526a83danno@chromium.org const Register arg_reg_1 = { kRegister_rcx_Code }; 1856b0169a99e75f4821ce4168e5e0d3cc8f6526a83danno@chromium.org const Register arg_reg_2 = { kRegister_rdx_Code }; 1866b0169a99e75f4821ce4168e5e0d3cc8f6526a83danno@chromium.org const Register arg_reg_3 = { kRegister_r8_Code }; 1876b0169a99e75f4821ce4168e5e0d3cc8f6526a83danno@chromium.org const Register arg_reg_4 = { kRegister_r9_Code }; 188ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org#else 189ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // AMD64 calling convention 1906b0169a99e75f4821ce4168e5e0d3cc8f6526a83danno@chromium.org const Register arg_reg_1 = { kRegister_rdi_Code }; 1916b0169a99e75f4821ce4168e5e0d3cc8f6526a83danno@chromium.org const Register arg_reg_2 = { kRegister_rsi_Code }; 1926b0169a99e75f4821ce4168e5e0d3cc8f6526a83danno@chromium.org const Register arg_reg_3 = { kRegister_rdx_Code }; 1936b0169a99e75f4821ce4168e5e0d3cc8f6526a83danno@chromium.org const Register arg_reg_4 = { kRegister_rcx_Code }; 194ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org#endif // _WIN64 1955aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 1969085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgstruct XMMRegister { 19794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org static const int kMaxNumRegisters = 16; 198a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org static const int kMaxNumAllocatableRegisters = 15; 199a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org static int NumAllocatableRegisters() { 200a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return kMaxNumAllocatableRegisters; 201a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 202a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 203a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org static int ToAllocationIndex(XMMRegister reg) { 204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(reg.code() != 0); 205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return reg.code() - 1; 206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 208c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org static XMMRegister FromAllocationIndex(int index) { 209a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(0 <= index && index < kMaxNumAllocatableRegisters); 210c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org XMMRegister result = { index + 1 }; 211c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return result; 212c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 213c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org static const char* AllocationIndexToString(int index) { 215a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); 216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const char* const names[] = { 217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm1", 218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm2", 219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm3", 220a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm4", 221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm5", 222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm6", 223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm7", 224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm8", 225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm9", 226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm10", 227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm11", 228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm12", 229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm13", 230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm14", 231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "xmm15" 232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org }; 233a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return names[index]; 234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static XMMRegister from_code(int code) { 237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(code >= 0); 23894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ASSERT(code < kMaxNumRegisters); 239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XMMRegister r = { code }; 240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return r; 241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 24294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters; } 243c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org bool is(XMMRegister reg) const { return code_ == reg.code_; } 2444a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org int code() const { 2459085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org ASSERT(is_valid()); 2469085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return code_; 2479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 2489085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 24986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Return the high bit of the register code as a 0 or 1. Used often 25086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // when constructing the REX prefix byte. 25186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org int high_bit() const { 25286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org return code_ >> 3; 25386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 25486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Return the 3 low bits of the register code. Used when encoding registers 25586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // in modR/M, SIB, and opcode bytes. 25686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org int low_bits() const { 25786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org return code_ & 0x7; 25886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org } 25986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 2609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org int code_; 2619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}; 2629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 263b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm0 = { 0 }; 264b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm1 = { 1 }; 265b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm2 = { 2 }; 266b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm3 = { 3 }; 267b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm4 = { 4 }; 268b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm5 = { 5 }; 269b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm6 = { 6 }; 270b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm7 = { 7 }; 271b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm8 = { 8 }; 272b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm9 = { 9 }; 273b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm10 = { 10 }; 274b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm11 = { 11 }; 275b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm12 = { 12 }; 276b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm13 = { 13 }; 277b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm14 = { 14 }; 278b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgconst XMMRegister xmm15 = { 15 }; 2799085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtypedef XMMRegister DoubleRegister; 282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgenum Condition { 2859085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // any value < 0 is considered no_condition 2869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org no_condition = -1, 2879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 2889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org overflow = 0, 2899085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org no_overflow = 1, 2909085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org below = 2, 2919085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org above_equal = 3, 2929085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org equal = 4, 2939085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org not_equal = 5, 2949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org below_equal = 6, 2959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org above = 7, 2969085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org negative = 8, 2979085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org positive = 9, 2989085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org parity_even = 10, 2999085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org parity_odd = 11, 3009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org less = 12, 3019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org greater_equal = 13, 3029085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org less_equal = 14, 3039085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org greater = 15, 3049085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3059d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Fake conditions that are handled by the 3069d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // opcodes using them. 3079d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com always = 16, 3089d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com never = 17, 3099085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // aliases 3109085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org carry = below, 3119085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org not_carry = above_equal, 3129085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org zero = equal, 3139085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org not_zero = not_equal, 3149085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org sign = negative, 3159d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com not_sign = positive, 3169d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com last_condition = greater 3179085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}; 3189085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3209085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Returns the equivalent of !cc. 3219085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Negation of the default no_condition (-1) results in a non-default 3229085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// no_condition value (-2). As long as tests for no_condition check 3239085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// for condition < 0, this will work as expected. 3245ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orginline Condition NegateCondition(Condition cc) { 3255ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org return static_cast<Condition>(cc ^ 1); 3265ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org} 3275ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 3289085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3291e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org// Commute a condition such that {a cond b == b cond' a}. 33038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orginline Condition CommuteCondition(Condition cc) { 3319085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org switch (cc) { 3329085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org case below: 3339085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return above; 3349085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org case above: 3359085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return below; 3369085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org case above_equal: 3379085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return below_equal; 3389085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org case below_equal: 3399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return above_equal; 3409085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org case less: 3419085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return greater; 3429085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org case greater: 3439085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return less; 3449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org case greater_equal: 3459085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return less_equal; 3469085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org case less_equal: 3479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return greater_equal; 3489085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org default: 3499085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return cc; 3503c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org } 3519085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} 3529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3535ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 3549085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// ----------------------------------------------------------------------------- 3559085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Machine instruction Immediates 3569085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgclass Immediate BASE_EMBEDDED { 3589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org public: 359755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org explicit Immediate(int32_t value) : value_(value) {} 36004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org explicit Immediate(Smi* value) { 36104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); // Only available for 31-bit SMI. 36204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org value_ = static_cast<int32_t>(reinterpret_cast<intptr_t>(value)); 36304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } 3649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org private: 366755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org int32_t value_; 3679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org friend class Assembler; 3699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}; 3709085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3719085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3729085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// ----------------------------------------------------------------------------- 3739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Machine instruction Operands 3749085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3759085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgenum ScaleFactor { 3763e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org times_1 = 0, 3773e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org times_2 = 1, 3783e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org times_4 = 2, 3793e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org times_8 = 3, 3803e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org times_int_size = times_4, 38125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org times_pointer_size = (kPointerSize == 8) ? times_8 : times_4 3829085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}; 3839085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3859085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgclass Operand BASE_EMBEDDED { 3869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org public: 3879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // [base + disp/r] 388eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org Operand(Register base, int32_t disp); 3899085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3909085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // [base + index*scale + disp/r] 391755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org Operand(Register base, 392755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org Register index, 393755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org ScaleFactor scale, 394755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org int32_t disp); 3959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3969085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // [index*scale + disp/r] 397755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org Operand(Register index, 398755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org ScaleFactor scale, 399755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org int32_t disp); 4009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 4019155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // Offset from existing memory operand. 4029155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // Offset is added to existing displacement as 32-bit signed values and 4039155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // this must not overflow. 4049155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org Operand(const Operand& base, int32_t offset); 4059155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org 4060ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Checks whether either base or index register is the given register. 4070ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Does not check the "reg" part of the Operand. 4080ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org bool AddressUsesRegister(Register reg) const; 4090ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 410eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org // Queries related to the size of the generated instruction. 411eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org // Whether the generated instruction will have a REX prefix. 412eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org bool requires_rex() const { return rex_ != 0; } 413eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org // Size of the ModR/M, SIB and displacement parts of the generated 414eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org // instruction. 415eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org int operand_size() const { return len_; } 416eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org 4179085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org private: 4189085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org byte rex_; 41930ce411529579186181838984710b0b0980857aaricow@chromium.org byte buf_[6]; 4200ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // The number of bytes of buf_ in use. 4210ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org byte len_; 4229085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 423e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Set the ModR/M byte without an encoded 'reg' register. The 4249085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // register is encoded later as part of the emit_operand operation. 425755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // set_modrm can be called before or after set_sib and set_disp*. 4269085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org inline void set_modrm(int mod, Register rm); 4279085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 428755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Set the SIB byte if one is needed. Sets the length to 2 rather than 1. 4299085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org inline void set_sib(ScaleFactor scale, Register index, Register base); 4309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 431755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Adds operand displacement fields (offsets added to the memory address). 432755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Needs to be called after set_sib, not before it. 433755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org inline void set_disp8(int disp); 434755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org inline void set_disp32(int disp); 4359085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 436755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org friend class Assembler; 4379085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}; 4389085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 4399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 440fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#define ASSEMBLER_INSTRUCTION_LIST(V) \ 441fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org V(add) \ 442895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org V(and) \ 4437a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org V(cmp) \ 4447a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org V(dec) \ 445fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org V(idiv) \ 446fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org V(imul) \ 4477a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org V(inc) \ 448895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org V(lea) \ 449fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org V(mov) \ 450895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org V(movzxb) \ 451895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org V(movzxw) \ 4527a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org V(neg) \ 453895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org V(not) \ 454895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org V(or) \ 455895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org V(repmovs) \ 4567a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org V(sbb) \ 4577a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org V(sub) \ 458895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org V(test) \ 459895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org V(xchg) \ 460895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org V(xor) 461ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 462ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 4632f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org// Shift instructions on operands/registers with kPointerSize, kInt32Size and 4642f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org// kInt64Size. 4652f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org#define SHIFT_INSTRUCTION_LIST(V) \ 4662f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(rol, 0x0) \ 4672f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(ror, 0x1) \ 4682f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(rcl, 0x2) \ 4692f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(rcr, 0x3) \ 4702f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(shl, 0x4) \ 4712f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(shr, 0x5) \ 4722f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(sar, 0x7) \ 4732f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 4742f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 475ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass Assembler : public AssemblerBase { 4769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org private: 4773e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // We check before assembling an instruction that there is sufficient 4783e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // space to write an instruction and its relocation information. 4793e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // The relocation writer's position must be kGap bytes above the end of 4809085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // the generated instructions. This leaves enough space for the 4813e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // longest possible x64 instruction, 15 bytes, and the longest possible 4823e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // relocation information encoding, RelocInfoWriter::kMaxLength == 16. 4833e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // (There is a 15 byte limit on x64 instruction length that rules out some 4843e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // otherwise valid instructions.) 4853e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // This allows for a single, fast space check per instruction. 4869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org static const int kGap = 32; 4879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 4889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org public: 4899085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Create an assembler. Instructions and relocation information are emitted 4909085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // into a buffer, with the instructions starting from the beginning and the 4919085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // relocation information starting from the end of the buffer. See CodeDesc 4929085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // for a detailed comment on the layout (globals.h). 4939085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // 4949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // If the provided buffer is NULL, the assembler allocates and grows its own 4959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // buffer, and buffer_size determines the initial buffer size. The buffer is 4969085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // owned by the assembler and deallocated upon destruction of the assembler. 4979085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // 4989085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // If the provided buffer is not NULL, the assembler uses the provided buffer 4999085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // for code generation and assumes its size to be buffer_size. If the buffer 5009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // is too small, a fatal error occurs. No deallocation of the buffer is done 5019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // upon destruction of the assembler. 502c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Assembler(Isolate* isolate, void* buffer, int buffer_size); 5038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org virtual ~Assembler() { } 5049085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 5059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // GetCode emits any pending (non-emitted) code and fills the descriptor 5069085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // desc. GetCode() is idempotent; it returns the same result if no other 5079085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Assembler functions are invoked in between GetCode() calls. 5089085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void GetCode(CodeDesc* desc); 5099085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 510c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Read/Modify the code target in the relative branch/call instruction at pc. 511c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // On the x64 architecture, we use relative jumps with a 32-bit displacement 512c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // to jump to other Code objects in the Code space in the heap. 513c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Jumps to C functions are done indirectly through a 64-bit register holding 514c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // the absolute address of the target. 515c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // These functions convert between absolute Addresses of Code objects and 516c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // the relative displacements stored in the code. 51797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org static inline Address target_address_at(Address pc, 51897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool); 51997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org static inline void set_target_address_at(Address pc, 52097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool, 5216a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Address target, 5226a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org ICacheFlushMode icache_flush_mode = 5236a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org FLUSH_ICACHE_IF_NEEDED) ; 52497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org static inline Address target_address_at(Address pc, Code* code) { 52597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; 52697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return target_address_at(pc, constant_pool); 52797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org } 52897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org static inline void set_target_address_at(Address pc, 52997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org Code* code, 5306a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Address target, 5316a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org ICacheFlushMode icache_flush_mode = 5326a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org FLUSH_ICACHE_IF_NEEDED) { 53397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; 5346a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org set_target_address_at(pc, constant_pool, target, icache_flush_mode); 53597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org } 536c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 53789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org // Return the code target address at a call site from the return address 53889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org // of that call in the instruction stream. 53989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org static inline Address target_address_from_return_address(Address pc); 54089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 5413811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // This sets the branch destination (which is in the instruction on x64). 542c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org // This is for calls and branches within generated code. 54388aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org inline static void deserialization_set_special_target_at( 54497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org Address instruction_payload, Code* code, Address target) { 54597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org set_target_address_at(instruction_payload, code, target); 5463811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 547c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 548af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org static inline RelocInfo::Mode RelocInfoNone() { 549af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (kPointerSize == kInt64Size) { 550af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org return RelocInfo::NONE64; 551af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } else { 552af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org ASSERT(kPointerSize == kInt32Size); 553af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org return RelocInfo::NONE32; 554af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } 555af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } 556af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org 557c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org inline Handle<Object> code_target_object_handle_at(Address pc); 5586e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org inline Address runtime_entry_at(Address pc); 5593811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Number of bytes taken up by the branch target in the code. 56088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org static const int kSpecialTargetSize = 4; // Use 32-bit displacement. 5619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Distance between the address of the code target in the call instruction 562c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // and the return address pushed on the stack. 563c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement. 564594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // The length of call(kScratchRegister). 565594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kCallScratchRegisterInstructionLength = 3; 566594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // The length of call(Immediate32). 567abafe3dbcc62abc040625a8356be42bbd0cf7608danno@chromium.org static const int kShortCallInstructionLength = 5; 568594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // The length of movq(kScratchRegister, address). 569594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kMoveAddressIntoScratchRegisterInstructionLength = 570594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 2 + kPointerSize; 571594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // The length of movq(kScratchRegister, address) and call(kScratchRegister). 572594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kCallSequenceLength = 573594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org kMoveAddressIntoScratchRegisterInstructionLength + 574594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org kCallScratchRegisterInstructionLength; 575594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 576594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // The js return and debug break slot must be able to contain an indirect 577594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // call sequence, some x64 JS code is padded with int3 to make it large 578594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // enough to hold an instruction when the debugger patches it. 579594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kJSReturnSequenceLength = kCallSequenceLength; 580594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kDebugBreakSlotLength = kCallSequenceLength; 581594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kPatchDebugBreakSlotReturnOffset = kCallTargetAddressOffset; 582594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // Distance between the start of the JS return sequence and where the 583594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // 32-bit displacement of a short call would be. The short call is from 584594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // SetDebugBreakAtIC from debug-x64.cc. 585594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kPatchReturnSequenceAddressOffset = 586594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org kJSReturnSequenceLength - kPatchDebugBreakSlotReturnOffset; 587594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // Distance between the start of the JS return sequence and where the 588594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // 32-bit displacement of a short call would be. The short call is from 589594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // SetDebugBreakAtIC from debug-x64.cc. 590594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kPatchDebugBreakSlotAddressOffset = 591594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org kDebugBreakSlotLength - kPatchDebugBreakSlotReturnOffset; 592594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kRealPatchReturnSequenceAddressOffset = 593594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org kMoveAddressIntoScratchRegisterInstructionLength - kPointerSize; 5942356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 5955d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // One byte opcode for test eax,0xXXXXXXXX. 5965d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org static const byte kTestEaxByte = 0xA9; 597d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // One byte opcode for test al, 0xXX. 598d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com static const byte kTestAlByte = 0xA8; 599496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // One byte opcode for nop. 600496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org static const byte kNopByte = 0x90; 601496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 602496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // One byte prefix for a short conditional jump. 603496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org static const byte kJccShortPrefix = 0x70; 604496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org static const byte kJncShortOpcode = kJccShortPrefix | not_carry; 605496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org static const byte kJcShortOpcode = kJccShortPrefix | carry; 606212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org static const byte kJnzShortOpcode = kJccShortPrefix | not_zero; 607212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org static const byte kJzShortOpcode = kJccShortPrefix | zero; 608496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 6092356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 6109085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 6119085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Code generation 6129085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // 61371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Function names correspond one-to-one to x64 instruction mnemonics. 61471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Unless specified otherwise, instructions operate on 64-bit operands. 61571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // 61671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // If we need versions of an assembly instruction that operate on different 61771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // width arguments, we add a single-letter suffix specifying the width. 618eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // This is done for the following instructions: mov, cmp, inc, dec, 619eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // add, sub, and test. 62071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // There are no versions of these instructions without the suffix. 62171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. 62271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. 62371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // - Instructions on 32-bit (doubleword) operands/registers use 'l'. 62471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // - Instructions on 64-bit (quadword) operands/registers use 'q'. 625895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // - Instructions on operands/registers with pointer size use 'p'. 6269085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 6272f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size); 6282f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 629ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org#define DECLARE_INSTRUCTION(instruction) \ 630fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org template<class P1> \ 631fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void instruction##p(P1 p1) { \ 632fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org emit_##instruction(p1, kPointerSize); \ 633fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } \ 634fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org \ 635fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org template<class P1> \ 636fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void instruction##l(P1 p1) { \ 637fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org emit_##instruction(p1, kInt32Size); \ 638fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } \ 639fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org \ 640fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org template<class P1> \ 641fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void instruction##q(P1 p1) { \ 642fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org emit_##instruction(p1, kInt64Size); \ 643fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } \ 644fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org \ 645ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org template<class P1, class P2> \ 646ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org void instruction##p(P1 p1, P2 p2) { \ 647ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_##instruction(p1, p2, kPointerSize); \ 648ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } \ 649ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org \ 650ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org template<class P1, class P2> \ 651ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org void instruction##l(P1 p1, P2 p2) { \ 652ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_##instruction(p1, p2, kInt32Size); \ 653ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } \ 654ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org \ 655ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org template<class P1, class P2> \ 656ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org void instruction##q(P1 p1, P2 p2) { \ 657ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_##instruction(p1, p2, kInt64Size); \ 658fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } \ 659fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org \ 660fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org template<class P1, class P2, class P3> \ 661fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void instruction##p(P1 p1, P2 p2, P3 p3) { \ 662fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org emit_##instruction(p1, p2, p3, kPointerSize); \ 663fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } \ 664fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org \ 665fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org template<class P1, class P2, class P3> \ 666fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void instruction##l(P1 p1, P2 p2, P3 p3) { \ 667fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org emit_##instruction(p1, p2, p3, kInt32Size); \ 668fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } \ 669fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org \ 670fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org template<class P1, class P2, class P3> \ 671fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void instruction##q(P1 p1, P2 p2, P3 p3) { \ 672fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org emit_##instruction(p1, p2, p3, kInt64Size); \ 673ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 674ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION) 675ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org#undef DECLARE_INSTRUCTION 676ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 6779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Insert the smallest number of nop instructions 6789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // possible to align the pc offset to a multiple 67983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // of m, where m must be a power of 2. 6809085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void Align(int m); 68164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org void Nop(int bytes = 1); 6825ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org // Aligns code to something that's optimal for a jump target for the platform. 6835ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org void CodeTargetAlign(); 6849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 6859085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Stack 686e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void pushfq(); 687e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void popfq(); 6889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 689763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void pushq(Immediate value); 6900ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Push a 32 bit integer, and guarantee that it is actually pushed as a 6910ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // 32 bit value, the normal push will optimize the 8 bit case. 692763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void pushq_imm32(int32_t imm32); 693763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void pushq(Register src); 694763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void pushq(const Operand& src); 6959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 696763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void popq(Register dst); 697763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void popq(const Operand& dst); 6989085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 699e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void enter(Immediate size); 7009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void leave(); 7019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 7029085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Moves 703755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void movb(Register dst, const Operand& src); 704e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void movb(Register dst, Immediate imm); 705755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void movb(const Operand& dst, Register src); 706e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org void movb(const Operand& dst, Immediate imm); 707755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 7083811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Move the low 16 bits of a 64-bit register value to a 16-bit 7093811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // memory location. 710e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org void movw(Register dst, const Operand& src); 7113811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void movw(const Operand& dst, Register src); 712e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org void movw(const Operand& dst, Immediate imm); 7133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 714911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Move the offset of the label location relative to the current 715911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // position (after the move) to the destination. 716911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void movl(const Operand& dst, Label* src); 717e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 718e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Loads a pointer into a register with a relocation mode. 7199cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org void movp(Register dst, void* ptr, RelocInfo::Mode rmode); 7209cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 721e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Loads a 64-bit immediate into a register. 722e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org void movq(Register dst, int64_t value); 723ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org void movq(Register dst, uint64_t value); 724755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 7252ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org void movsxbl(Register dst, const Operand& src); 7263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void movsxbq(Register dst, const Operand& src); 7272ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org void movsxwl(Register dst, const Operand& src); 7283811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void movsxwq(Register dst, const Operand& src); 7295aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void movsxlq(Register dst, Register src); 7303e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void movsxlq(Register dst, const Operand& src); 7315aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 732b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Repeated moves. 733b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 734b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void repmovsb(); 735b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void repmovsw(); 736895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void repmovsp() { emit_repmovs(kPointerSize); } 737895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void repmovsl() { emit_repmovs(kInt32Size); } 738895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void repmovsq() { emit_repmovs(kInt64Size); } 739b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 740badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // Instruction to load from an immediate 64-bit pointer into RAX. 741755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void load_rax(void* ptr, RelocInfo::Mode rmode); 742e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void load_rax(ExternalReference ext); 7439085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 7443e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // Conditional moves. 7453e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cmovq(Condition cc, Register dst, Register src); 7463e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cmovq(Condition cc, Register dst, const Operand& src); 7473e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cmovl(Condition cc, Register dst, Register src); 7483e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cmovl(Condition cc, Register dst, const Operand& src); 7499085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 7503e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cmpb(Register dst, Immediate src) { 7513e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org immediate_arithmetic_op_8(0x7, dst, src); 7523e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org } 7533e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 754911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpb_al(Immediate src); 755911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 756911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpb(Register dst, Register src) { 7572f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op_8(0x3A, dst, src); 758911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 759911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 760911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpb(Register dst, const Operand& src) { 7612f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op_8(0x3A, dst, src); 762911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 763911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 764911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpb(const Operand& dst, Register src) { 7652f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op_8(0x38, src, dst); 766911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 767911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 768eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void cmpb(const Operand& dst, Immediate src) { 769eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org immediate_arithmetic_op_8(0x7, dst, src); 770eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 771eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 772911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpw(const Operand& dst, Immediate src) { 773911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org immediate_arithmetic_op_16(0x7, dst, src); 774911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 775911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 776911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpw(Register dst, Immediate src) { 777911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org immediate_arithmetic_op_16(0x7, dst, src); 778911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 779911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 780911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpw(Register dst, const Operand& src) { 781911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org arithmetic_op_16(0x3B, dst, src); 782911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 783911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 784911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpw(Register dst, Register src) { 785911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org arithmetic_op_16(0x3B, dst, src); 786911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 787911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 788911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpw(const Operand& dst, Register src) { 789911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org arithmetic_op_16(0x39, src, dst); 790911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 791911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 792b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void andb(Register dst, Immediate src) { 793b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org immediate_arithmetic_op_8(0x4, dst, src); 794b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 7959d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 7969d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void decb(Register dst); 7979d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void decb(const Operand& dst); 7989085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 799e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Sign-extends rax into rdx:rax. 800e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void cqo(); 8010b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Sign-extends eax into edx:eax. 8020b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org void cdq(); 8039085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 804e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Multiply rax by src, put the result in rdx:rax. 8059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void mul(Register src); 8069085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 8072f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode) \ 8082f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void instruction##p(Register dst, Immediate imm8) { \ 8092f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shift(dst, imm8, subcode, kPointerSize); \ 8102f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org } \ 8112f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org \ 8122f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void instruction##l(Register dst, Immediate imm8) { \ 8132f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shift(dst, imm8, subcode, kInt32Size); \ 8142f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org } \ 8152f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org \ 8162f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void instruction##q(Register dst, Immediate imm8) { \ 8172f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shift(dst, imm8, subcode, kInt64Size); \ 8182f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org } \ 8192f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org \ 8202f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void instruction##p_cl(Register dst) { \ 8212f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shift(dst, subcode, kPointerSize); \ 8222f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org } \ 8232f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org \ 8242f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void instruction##l_cl(Register dst) { \ 8252f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shift(dst, subcode, kInt32Size); \ 8262f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org } \ 8272f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org \ 8282f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void instruction##q_cl(Register dst) { \ 8292f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shift(dst, subcode, kInt64Size); \ 8302f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org } 8312f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION) 8322f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org#undef DECLARE_SHIFT_INSTRUCTION 833e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 834e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Shifts dst:src left by cl bits, affecting only dst. 835e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void shld(Register dst, Register src); 836e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 837e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Shifts src:dst right by cl bits, affecting only dst. 838e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void shrd(Register dst, Register src); 839e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 840e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void store_rax(void* dst, RelocInfo::Mode mode); 841e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void store_rax(ExternalReference ref); 8429085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 843911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void subb(Register dst, Immediate src) { 844911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org immediate_arithmetic_op_8(0x5, dst, src); 845911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 846911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 8479d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void testb(Register dst, Register src); 848755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void testb(Register reg, Immediate mask); 849755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void testb(const Operand& op, Immediate mask); 850b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void testb(const Operand& op, Register reg); 851755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 8529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Bit operations. 8539085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void bt(const Operand& dst, Register src); 8549085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void bts(const Operand& dst, Register src); 855f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void bsrl(Register dst, Register src); 8569085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 8579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Miscellaneous 8589d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void clc(); 8597979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org void cld(); 860eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void cpuid(); 8619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void hlt(); 8629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void int3(); 8639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void nop(); 8649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void ret(int imm16); 865eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void setcc(Condition cc, Register reg); 8669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 8679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Label operations & relative jumps (PPUM Appendix D) 8689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // 8699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Takes a branch opcode (cc) and a label (L) and generates 8709085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // either a backward branch or a forward branch and links it 8719085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // to the label fixup chain. Usage: 8729085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // 8739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Label L; // unbound label 8749085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // j(cc, &L); // forward branch to unbound label 8759085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // bind(&L); // bind label to the current pc 8769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // j(cc, &L); // backward branch to bound label 8779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // bind(&L); // illegal: a label may be bound only once 8789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // 8799085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Note: The same Label can be used for forward and backward branches 8809085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // but it may be bound only once. 8819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 8829085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void bind(Label* L); // binds an unbound label L to the current code position 8839085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 8849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Calls 885e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Call near relative 32-bit displacement, relative to next instruction. 8869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void call(Label* L); 8876e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org void call(Address entry, RelocInfo::Mode rmode); 8888e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org void call(Handle<Code> target, 8894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org RelocInfo::Mode rmode = RelocInfo::CODE_TARGET, 890471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TypeFeedbackId ast_id = TypeFeedbackId::None()); 891e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 89283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // Calls directly to the given address using a relative offset. 89383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // Should only ever be used in Code objects for calls within the 89483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // same Code object. Should not be used when generating new code (use labels), 89583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // but only when patching existing code. 89683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org void call(Address target); 89783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 898e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Call near absolute indirect, address in register 899e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void call(Register adr); 900e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 9019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Jumps 902e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Jump short or near relative. 903c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Use a 32-bit signed displacement. 90483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Unconditional jump to L 90583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void jmp(Label* L, Label::Distance distance = Label::kFar); 9066e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org void jmp(Address entry, RelocInfo::Mode rmode); 907c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org void jmp(Handle<Code> target, RelocInfo::Mode rmode); 908e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 909e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Jump near absolute indirect (r64) 910e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void jmp(Register adr); 9119085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9129085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Conditional jumps 91383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void j(Condition cc, 91483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* L, 91583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance distance = Label::kFar); 9166e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org void j(Condition cc, Address entry, RelocInfo::Mode rmode); 917c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode); 9189085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Floating-point operations 9209085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fld(int i); 9219085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9229085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fld1(); 9239085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fldz(); 924ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org void fldpi(); 925a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void fldln2(); 9269085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9279085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fld_s(const Operand& adr); 9289085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fld_d(const Operand& adr); 9299085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fstp_s(const Operand& adr); 9319085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fstp_d(const Operand& adr); 9323811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void fstp(int index); 9339085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9349085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fild_s(const Operand& adr); 9359085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fild_d(const Operand& adr); 9369085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9379085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fist_s(const Operand& adr); 9389085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fistp_s(const Operand& adr); 9409085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fistp_d(const Operand& adr); 9419085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9429085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fisttp_s(const Operand& adr); 943b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void fisttp_d(const Operand& adr); 9449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9459085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fabs(); 9469085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fchs(); 9479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9489085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fadd(int i); 9499085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fsub(int i); 9509085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fmul(int i); 9519085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fdiv(int i); 9529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9539085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fisub_s(const Operand& adr); 9549085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9559085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void faddp(int i = 1); 9569085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fsubp(int i = 1); 9579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fsubrp(int i = 1); 9589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fmulp(int i = 1); 9599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fdivp(int i = 1); 9609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fprem(); 9619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fprem1(); 9629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fxch(int i = 1); 9649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fincstp(); 9659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void ffree(int i = 0); 9669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void ftst(); 9689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fucomp(int i); 9699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fucompp(); 9703811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void fucomi(int i); 9713811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void fucomip(); 9723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 9739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fcompp(); 9749085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fnstsw_ax(); 9759085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fwait(); 9769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fnclex(); 9779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9785aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void fsin(); 9795aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void fcos(); 9801b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org void fptan(); 981a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void fyl2x(); 98264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org void f2xm1(); 98364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org void fscale(); 98464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org void fninit(); 9855aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 9869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void frndint(); 9879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9883e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void sahf(); 9893e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 990ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org // SSE instructions 991ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void movaps(XMMRegister dst, XMMRegister src); 992ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void movss(XMMRegister dst, const Operand& src); 993ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void movss(const Operand& dst, XMMRegister src); 994af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void shufps(XMMRegister dst, XMMRegister src, byte imm8); 995ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 996ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void cvttss2si(Register dst, const Operand& src); 997ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void cvttss2si(Register dst, XMMRegister src); 998ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void cvtlsi2ss(XMMRegister dst, Register src); 999ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1000ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void andps(XMMRegister dst, XMMRegister src); 1001af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void andps(XMMRegister dst, const Operand& src); 1002057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org void orps(XMMRegister dst, XMMRegister src); 1003af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void orps(XMMRegister dst, const Operand& src); 1004057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org void xorps(XMMRegister dst, XMMRegister src); 1005af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void xorps(XMMRegister dst, const Operand& src); 1006af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 1007af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void addps(XMMRegister dst, XMMRegister src); 1008af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void addps(XMMRegister dst, const Operand& src); 1009af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void subps(XMMRegister dst, XMMRegister src); 1010af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void subps(XMMRegister dst, const Operand& src); 1011af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void mulps(XMMRegister dst, XMMRegister src); 1012af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void mulps(XMMRegister dst, const Operand& src); 1013af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void divps(XMMRegister dst, XMMRegister src); 1014af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void divps(XMMRegister dst, const Operand& src); 1015ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1016ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void movmskps(Register dst, XMMRegister src); 1017ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 10183e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // SSE2 instructions 1019357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org void movd(XMMRegister dst, Register src); 1020ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org void movd(Register dst, XMMRegister src); 1021ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org void movq(XMMRegister dst, Register src); 1022ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org void movq(Register dst, XMMRegister src); 1023160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org void movq(XMMRegister dst, XMMRegister src); 1024357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 1025160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // Don't use this unless it's important to keep the 1026160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // top half of the destination register unchanged. 1027160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // Used movaps when moving double values and movq for integer 1028160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // values in xmm registers. 1029357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org void movsd(XMMRegister dst, XMMRegister src); 1030160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 1031160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org void movsd(const Operand& dst, XMMRegister src); 1032357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org void movsd(XMMRegister dst, const Operand& src); 10333e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 10340ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void movdqa(const Operand& dst, XMMRegister src); 10350ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void movdqa(XMMRegister dst, const Operand& src); 10360ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 1037e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void movdqu(const Operand& dst, XMMRegister src); 1038e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void movdqu(XMMRegister dst, const Operand& src); 1039e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1040160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org void movapd(XMMRegister dst, XMMRegister src); 104140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org 1042ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org void psllq(XMMRegister reg, byte imm8); 1043ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 10449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void cvttsd2si(Register dst, const Operand& src); 10450a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org void cvttsd2si(Register dst, XMMRegister src); 1046dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org void cvttsd2siq(Register dst, XMMRegister src); 10479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 10483e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cvtlsi2sd(XMMRegister dst, const Operand& src); 10493e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cvtlsi2sd(XMMRegister dst, Register src); 10503e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cvtqsi2sd(XMMRegister dst, const Operand& src); 10513e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cvtqsi2sd(XMMRegister dst, Register src); 10529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 105340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org 1054357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org void cvtss2sd(XMMRegister dst, XMMRegister src); 105540b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org void cvtss2sd(XMMRegister dst, const Operand& src); 105640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org void cvtsd2ss(XMMRegister dst, XMMRegister src); 105740b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org 105840b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org void cvtsd2si(Register dst, XMMRegister src); 105940b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org void cvtsd2siq(Register dst, XMMRegister src); 1060357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 10619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void addsd(XMMRegister dst, XMMRegister src); 10621f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org void addsd(XMMRegister dst, const Operand& src); 10639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void subsd(XMMRegister dst, XMMRegister src); 10649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void mulsd(XMMRegister dst, XMMRegister src); 10651f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org void mulsd(XMMRegister dst, const Operand& src); 10669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void divsd(XMMRegister dst, XMMRegister src); 10679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 10685d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org void andpd(XMMRegister dst, XMMRegister src); 10695d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org void orpd(XMMRegister dst, XMMRegister src); 10705c838251403b0be9a882540f1922577abba4c872ager@chromium.org void xorpd(XMMRegister dst, XMMRegister src); 10714111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org void sqrtsd(XMMRegister dst, XMMRegister src); 10727e6132b924829c353864933f29124419916db550machenbach@chromium.org void sqrtsd(XMMRegister dst, const Operand& src); 10735c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10745c838251403b0be9a882540f1922577abba4c872ager@chromium.org void ucomisd(XMMRegister dst, XMMRegister src); 107540b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org void ucomisd(XMMRegister dst, const Operand& src); 1076ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void cmpltsd(XMMRegister dst, XMMRegister src); 1077ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1078ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void movmskpd(Register dst, XMMRegister src); 1079ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1080ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org // SSE 4.1 instruction 1081ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void extractps(Register dst, XMMRegister src, byte imm8); 10823e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 1083160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org enum RoundingMode { 1084160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org kRoundToNearest = 0x0, 1085160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org kRoundDown = 0x1, 1086160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org kRoundUp = 0x2, 1087160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org kRoundToZero = 0x3 1088160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org }; 1089160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 1090160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode); 1091160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 10929085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Debugging 10939085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void Print(); 10949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 10959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Check the code size generated from label to here. 10964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int SizeOfCodeGeneratedSince(Label* label) { 10974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return pc_offset() - label->pos(); 10984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 10999085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Mark address of the ExitJSFrame code. 11019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void RecordJSReturn(); 11029085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11032356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Mark address of a debug break slot. 11042356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org void RecordDebugBreakSlot(); 11052356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 11069085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Record a comment relocation entry that can be used by a disassembler. 1107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Use --code-comments to enable. 11083a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org void RecordComment(const char* msg, bool force = false); 11099085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1110763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org // Allocate a constant pool of the correct size for the generated code. 11119fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); 1112763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 1113763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org // Generate the constant pool for the generated code. 1114763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void PopulateConstantPool(ConstantPoolArray* constant_pool); 1115763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 1116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Writes a single word of data in the code stream. 1117a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Used for inline tables, e.g., jump-tables. 11180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void db(uint8_t data); 1119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void dd(uint32_t data); 1120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1121f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org PositionsRecorder* positions_recorder() { return &positions_recorder_; } 11229085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11239085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Check if there is less than kGap bytes available in the buffer. 11249085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // If this is the case, we need to grow the buffer before emitting 11259085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // an instruction or relocation information. 11264af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org inline bool buffer_overflow() const { 11274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org return pc_ >= reloc_info_writer.pos() - kGap; 11284af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 11299085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Get the number of bytes available in the buffer. 1131c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org inline int available_space() const { 1132c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org return static_cast<int>(reloc_info_writer.pos() - pc_); 1133c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org } 11349085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 113564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org static bool IsNop(Address addr); 11362356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 11379085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Avoid overflows for displacements etc. 11389085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org static const int kMaximalBufferSize = 512*MB; 11399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com byte byte_at(int pos) { return buffer_[pos]; } 1141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void set_byte_at(int pos, byte value) { buffer_[pos] = value; } 1142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1143f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org protected: 1144f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Call near indirect 1145f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void call(const Operand& operand); 1146f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 1147f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Jump near absolute indirect (m64) 1148f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void jmp(const Operand& src); 1149f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 11509085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org private: 11519085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org byte* addr_at(int pos) { return buffer_ + pos; } 11529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org uint32_t long_at(int pos) { 11539085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return *reinterpret_cast<uint32_t*>(addr_at(pos)); 11549085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 11559085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void long_at_put(int pos, uint32_t x) { 11569085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; 11579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 11589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // code emission 11609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void GrowBuffer(); 1161755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 1162755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void emit(byte x) { *pc_++ = x; } 1163755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org inline void emitl(uint32_t x); 1164fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org inline void emitp(void* x, RelocInfo::Mode rmode); 1165c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org inline void emitq(uint64_t x); 1166e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emitw(uint16_t x); 11678e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org inline void emit_code_target(Handle<Code> target, 11688e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org RelocInfo::Mode rmode, 1169471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TypeFeedbackId ast_id = TypeFeedbackId::None()); 11706e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode); 1171755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void emit(Immediate x) { emitl(x.value_); } 11729085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 117371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Emits a REX prefix that encodes a 64-bit operand size and 117471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // the top bit of both register codes. 1175755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1176755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // REX.W is set. 11773e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org inline void emit_rex_64(XMMRegister reg, Register rm_reg); 1178ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org inline void emit_rex_64(Register reg, XMMRegister rm_reg); 1179ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org inline void emit_rex_64(Register reg, Register rm_reg); 118071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 118171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Emits a REX prefix that encodes a 64-bit operand size and 118271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // the top bit of the destination, index, and base register codes. 1183755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // The high bit of reg is used for REX.R, the high bit of op's base 1184755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // register is used for REX.B, and the high bit of op's index register 1185755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // is used for REX.X. REX.W is set. 118671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org inline void emit_rex_64(Register reg, const Operand& op); 11873e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org inline void emit_rex_64(XMMRegister reg, const Operand& op); 1188e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1189e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emits a REX prefix that encodes a 64-bit operand size and 1190e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // the top bit of the register code. 1191e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // The high bit of register is used for REX.B. 1192e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // REX.W is set and REX.R and REX.X are clear. 1193e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emit_rex_64(Register rm_reg); 1194e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1195e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emits a REX prefix that encodes a 64-bit operand size and 1196e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // the top bit of the index and base register codes. 1197e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // The high bit of op's base register is used for REX.B, and the high 1198e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // bit of op's index register is used for REX.X. 1199e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // REX.W is set and REX.R clear. 1200e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emit_rex_64(const Operand& op); 1201e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1202e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size. 1203e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void emit_rex_64() { emit(0x48); } 1204755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 1205755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1206e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // REX.W is clear. 1207755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org inline void emit_rex_32(Register reg, Register rm_reg); 1208755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 1209755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // The high bit of reg is used for REX.R, the high bit of op's base 1210755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // register is used for REX.B, and the high bit of op's index register 1211755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // is used for REX.X. REX.W is cleared. 1212755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org inline void emit_rex_32(Register reg, const Operand& op); 1213755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 1214e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // High bit of rm_reg goes to REX.B. 1215e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // REX.W, REX.R and REX.X are clear. 1216e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emit_rex_32(Register rm_reg); 1217e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1218e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // High bit of base goes to REX.B and high bit of index to REX.X. 1219e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // REX.W and REX.R are clear. 1220e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emit_rex_32(const Operand& op); 1221e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1222755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1223755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // REX.W is cleared. If no REX bits are set, no byte is emitted. 1224755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org inline void emit_optional_rex_32(Register reg, Register rm_reg); 1225755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 1226755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // The high bit of reg is used for REX.R, the high bit of op's base 1227755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // register is used for REX.B, and the high bit of op's index register 1228755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing 1229755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // is emitted. 1230755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org inline void emit_optional_rex_32(Register reg, const Operand& op); 1231755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 12323e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // As for emit_optional_rex_32(Register, Register), except that 12333e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // the registers are XMM registers. 12343e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base); 12353e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 12363e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // As for emit_optional_rex_32(Register, Register), except that 1237ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // one of the registers is an XMM registers. 12383e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org inline void emit_optional_rex_32(XMMRegister reg, Register base); 12393e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 1240ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // As for emit_optional_rex_32(Register, Register), except that 1241ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // one of the registers is an XMM registers. 1242ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org inline void emit_optional_rex_32(Register reg, XMMRegister base); 1243ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 12443e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // As for emit_optional_rex_32(Register, const Operand&), except that 12453e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // the register is an XMM register. 12463e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org inline void emit_optional_rex_32(XMMRegister reg, const Operand& op); 12473e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 1248e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Optionally do as emit_rex_32(Register) if the register number has 1249e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // the high bit set. 1250e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emit_optional_rex_32(Register rm_reg); 1251e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1252e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Optionally do as emit_rex_32(const Operand&) if the operand register 1253e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // numbers have a high bit set. 1254e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emit_optional_rex_32(const Operand& op); 1255e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1256895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_rex(int size) { 1257895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org if (size == kInt64Size) { 1258895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org emit_rex_64(); 1259895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } else { 1260895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ASSERT(size == kInt32Size); 1261895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1262895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1263895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1264ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org template<class P1> 1265ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org void emit_rex(P1 p1, int size) { 1266ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (size == kInt64Size) { 1267ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_rex_64(p1); 1268ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else { 1269ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ASSERT(size == kInt32Size); 1270ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_optional_rex_32(p1); 1271ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 1272ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 1273ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 1274ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org template<class P1, class P2> 1275ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org void emit_rex(P1 p1, P2 p2, int size) { 1276ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (size == kInt64Size) { 1277ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_rex_64(p1, p2); 1278ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else { 1279ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ASSERT(size == kInt32Size); 1280ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_optional_rex_32(p1, p2); 1281ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 1282ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 1283e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1284e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emit the ModR/M byte, and optionally the SIB byte and 1285755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // 1- or 4-byte offset for a memory operand. Also encodes 1286755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // the second operand of the operation, a register or operation 1287e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // subcode, into the reg field of the ModR/M byte. 1288e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void emit_operand(Register reg, const Operand& adr) { 12895aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org emit_operand(reg.low_bits(), adr); 1290e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } 1291e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1292e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emit the ModR/M byte, and optionally the SIB byte and 1293e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // 1- or 4-byte offset for a memory operand. Also used to encode 1294e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // a three-bit opcode extension into the ModR/M byte. 1295e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void emit_operand(int rm, const Operand& adr); 1296e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1297e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emit a ModR/M byte with registers coded in the reg and rm_reg fields. 1298e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void emit_modrm(Register reg, Register rm_reg) { 12995aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits()); 1300e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } 1301e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1302e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emit a ModR/M byte with an operation subcode in the reg field and 1303e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // a register in the rm_reg field. 1304e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void emit_modrm(int code, Register rm_reg) { 13055aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org ASSERT(is_uint3(code)); 13065aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org emit(0xC0 | code << 3 | rm_reg.low_bits()); 1307755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org } 130871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 13099085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Emit the code-object-relative offset of the label's position 13109085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org inline void emit_code_relative_offset(Label* label); 13119085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1312ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org // The first argument is the reg field, the second argument is the r/m field. 1313ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void emit_sse_operand(XMMRegister dst, XMMRegister src); 1314ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void emit_sse_operand(XMMRegister reg, const Operand& adr); 1315ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void emit_sse_operand(XMMRegister dst, Register src); 1316ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void emit_sse_operand(Register dst, XMMRegister src); 1317ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1318755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Emit machine code for one of the operations ADD, ADC, SUB, SBC, 1319755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // AND, OR, XOR, or CMP. The encodings of these operations are all 1320755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // similar, differing just in the opcode or in the reg field of the 1321e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // ModR/M byte. 13222f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void arithmetic_op_8(byte opcode, Register reg, Register rm_reg); 13232f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg); 1324911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void arithmetic_op_16(byte opcode, Register reg, Register rm_reg); 1325911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg); 13262f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // Operate on operands/registers with pointer size, 32-bit or 64-bit size. 13272f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size); 13282f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void arithmetic_op(byte opcode, 13292f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org Register reg, 13302f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org const Operand& rm_reg, 13312f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org int size); 13323e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // Operate on a byte in memory or register. 1333eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void immediate_arithmetic_op_8(byte subcode, 1334911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Register dst, 13353e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org Immediate src); 13363e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void immediate_arithmetic_op_8(byte subcode, 1337911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org const Operand& dst, 13383e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org Immediate src); 1339911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Operate on a word in memory or register. 1340911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void immediate_arithmetic_op_16(byte subcode, 1341911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Register dst, 1342911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Immediate src); 1343911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void immediate_arithmetic_op_16(byte subcode, 1344911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org const Operand& dst, 1345911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Immediate src); 13462f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // Operate on operands/registers with pointer size, 32-bit or 64-bit size. 13472f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void immediate_arithmetic_op(byte subcode, 13482f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org Register dst, 13492f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org Immediate src, 13502f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org int size); 13512f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void immediate_arithmetic_op(byte subcode, 13522f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org const Operand& dst, 13532f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org Immediate src, 13542f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org int size); 1355911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1356e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emit machine code for a shift operation. 13572f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void shift(Register dst, Immediate shift_amount, int subcode, int size); 1358e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Shift dst by cl % 64 bits. 13592f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void shift(Register dst, int subcode, int size); 13609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13615aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void emit_farith(int b1, int b2, int i); 13629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // labels 1364eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // void print(Label* L); 13659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void bind_to(Label* L, int pos); 13669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // record reloc info for current pc_ 13689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 13699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1370fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // Arithmetics 1371fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_add(Register dst, Register src, int size) { 13722f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x03, dst, src, size); 1373fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1374fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1375fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_add(Register dst, Immediate src, int size) { 13762f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x0, dst, src, size); 1377fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1378fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1379fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_add(Register dst, const Operand& src, int size) { 13802f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x03, dst, src, size); 1381fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1382fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1383fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_add(const Operand& dst, Register src, int size) { 13842f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x1, src, dst, size); 1385fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1386fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1387fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_add(const Operand& dst, Immediate src, int size) { 13882f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x0, dst, src, size); 1389fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1390fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1391895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_and(Register dst, Register src, int size) { 13922f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x23, dst, src, size); 1393895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1394895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1395895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_and(Register dst, const Operand& src, int size) { 13962f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x23, dst, src, size); 1397895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1398895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1399895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_and(const Operand& dst, Register src, int size) { 14002f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x21, src, dst, size); 1401895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1402895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1403895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_and(Register dst, Immediate src, int size) { 14042f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x4, dst, src, size); 1405895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1406895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1407895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_and(const Operand& dst, Immediate src, int size) { 14082f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x4, dst, src, size); 1409895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1410895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 14117a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_cmp(Register dst, Register src, int size) { 14122f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x3B, dst, src, size); 14137a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org } 14147a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 14157a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_cmp(Register dst, const Operand& src, int size) { 14162f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x3B, dst, src, size); 14177a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org } 14187a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 14197a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_cmp(const Operand& dst, Register src, int size) { 14202f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x39, src, dst, size); 14217a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org } 14227a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 14237a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_cmp(Register dst, Immediate src, int size) { 14242f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x7, dst, src, size); 14257a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org } 14267a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 14277a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_cmp(const Operand& dst, Immediate src, int size) { 14282f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x7, dst, src, size); 14297a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org } 14307a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 14317a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_dec(Register dst, int size); 14327a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_dec(const Operand& dst, int size); 14337a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 1434fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // Divide rdx:rax by src. Quotient in rax, remainder in rdx when size is 64. 1435fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // Divide edx:eax by lower 32 bits of src. Quotient in eax, remainder in edx 1436fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // when size is 32. 1437fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_idiv(Register src, int size); 1438fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1439fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // Signed multiply instructions. 1440fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32. 1441fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_imul(Register src, int size); 1442fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_imul(Register dst, Register src, int size); 1443fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_imul(Register dst, const Operand& src, int size); 1444fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_imul(Register dst, Register src, Immediate imm, int size); 1445fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 14467a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_inc(Register dst, int size); 14477a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_inc(const Operand& dst, int size); 14487a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 1449895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_lea(Register dst, const Operand& src, int size); 1450895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 14517a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_mov(Register dst, const Operand& src, int size); 14527a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_mov(Register dst, Register src, int size); 14537a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_mov(const Operand& dst, Register src, int size); 14547a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_mov(Register dst, Immediate value, int size); 14557a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_mov(const Operand& dst, Immediate value, int size); 14567a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 1457895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_movzxb(Register dst, const Operand& src, int size); 1458895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_movzxw(Register dst, const Operand& src, int size); 1459895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_movzxw(Register dst, Register src, int size); 1460895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 14617a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_neg(Register dst, int size); 14627a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_neg(const Operand& dst, int size); 14637a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 1464895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_not(Register dst, int size); 1465895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_not(const Operand& dst, int size); 1466895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1467895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_or(Register dst, Register src, int size) { 14682f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x0B, dst, src, size); 1469895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1470895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1471895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_or(Register dst, const Operand& src, int size) { 14722f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x0B, dst, src, size); 1473895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1474895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1475895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_or(const Operand& dst, Register src, int size) { 14762f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x9, src, dst, size); 1477895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1478895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1479895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_or(Register dst, Immediate src, int size) { 14802f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x1, dst, src, size); 1481895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1482895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1483895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_or(const Operand& dst, Immediate src, int size) { 14842f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x1, dst, src, size); 1485895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1486895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1487895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_repmovs(int size); 1488895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 14897a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_sbb(Register dst, Register src, int size) { 14902f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x1b, dst, src, size); 14917a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org } 14927a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 1493fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_sub(Register dst, Register src, int size) { 14942f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x2B, dst, src, size); 1495fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1496fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1497fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_sub(Register dst, Immediate src, int size) { 14982f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x5, dst, src, size); 1499fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1500fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1501fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_sub(Register dst, const Operand& src, int size) { 15022f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x2B, dst, src, size); 1503fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1504fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1505fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_sub(const Operand& dst, Register src, int size) { 15062f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x29, src, dst, size); 1507fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1508fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1509fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_sub(const Operand& dst, Immediate src, int size) { 15102f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x5, dst, src, size); 1511fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1512fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 15137a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_test(Register dst, Register src, int size); 15147a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_test(Register reg, Immediate mask, int size); 15157a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_test(const Operand& op, Register reg, int size); 15167a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_test(const Operand& op, Immediate mask, int size); 1517ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 1518895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // Exchange two registers 1519895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_xchg(Register dst, Register src, int size); 1520895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1521895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_xor(Register dst, Register src, int size) { 15222f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org if (size == kInt64Size && dst.code() == src.code()) { 15232f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore 15242f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // there is no need to make this a 64 bit operation. 15252f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x33, dst, src, kInt32Size); 1526895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } else { 15272f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x33, dst, src, size); 1528895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1529895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1530895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1531895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_xor(Register dst, const Operand& src, int size) { 15322f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x33, dst, src, size); 1533895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1534895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1535895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_xor(Register dst, Immediate src, int size) { 15362f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x6, dst, src, size); 1537895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1538895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1539895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_xor(const Operand& dst, Immediate src, int size) { 15402f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x6, dst, src, size); 1541895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1542895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1543895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_xor(const Operand& dst, Register src, int size) { 15442f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x31, src, dst, size); 1545895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1546895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 15479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org friend class CodePatcher; 15489085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org friend class EnsureSpace; 1549911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org friend class RegExpMacroAssemblerX64; 15509085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15519085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // code generation 15529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org RelocInfoWriter reloc_info_writer; 15539085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1554c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org List< Handle<Code> > code_targets_; 15559085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1556f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org PositionsRecorder positions_recorder_; 1557f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org friend class PositionsRecorder; 15589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}; 15599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Helper class that ensures that there is enough space for generating 15629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// instructions and relocation information. The constructor makes 15639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// sure that there is enough space and (in debug mode) the destructor 15649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// checks that we did not generate too much. 15659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgclass EnsureSpace BASE_EMBEDDED { 15669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org public: 15679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { 15684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (assembler_->buffer_overflow()) assembler_->GrowBuffer(); 15699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifdef DEBUG 15709085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org space_before_ = assembler_->available_space(); 15719085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif 15729085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 15739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15749085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifdef DEBUG 15759085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org ~EnsureSpace() { 15769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org int bytes_generated = space_before_ - assembler_->available_space(); 15779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org ASSERT(bytes_generated < assembler_->kGap); 15789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 15799085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif 15809085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org private: 15829085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Assembler* assembler_; 15839085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifdef DEBUG 15849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org int space_before_; 15859085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif 15869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}; 15879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} } // namespace v8::internal 15895ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 15909085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif // V8_X64_ASSEMBLER_X64_H_ 1591