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) { 87e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(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) { 93e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(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 { 119e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(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) { 204e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(reg.code() != 0); 205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return reg.code() - 1; 206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 208c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org static XMMRegister FromAllocationIndex(int index) { 209e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(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) { 215e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(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) { 237e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(code >= 0); 238e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(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 { 245e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(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) { 361e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(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 4407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define ASSEMBLER_INSTRUCTION_LIST(V) \ 4417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(add) \ 4427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(and) \ 4437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(cmp) \ 4447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(dec) \ 4457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(idiv) \ 4467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(div) \ 4477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(imul) \ 4487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(inc) \ 4497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(lea) \ 4507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(mov) \ 4517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(movzxb) \ 4527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(movzxw) \ 4537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(neg) \ 4547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(not) \ 4557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(or) \ 4567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(repmovs) \ 4577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(sbb) \ 4587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(sub) \ 4597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(test) \ 4607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(xchg) \ 461895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org V(xor) 462ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 463ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 4642f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org// Shift instructions on operands/registers with kPointerSize, kInt32Size and 4652f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org// kInt64Size. 4662f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org#define SHIFT_INSTRUCTION_LIST(V) \ 4672f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(rol, 0x0) \ 4682f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(ror, 0x1) \ 4692f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(rcl, 0x2) \ 4702f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(rcr, 0x3) \ 4712f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(shl, 0x4) \ 4722f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(shr, 0x5) \ 4732f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org V(sar, 0x7) \ 4742f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 4752f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 476ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass Assembler : public AssemblerBase { 4779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org private: 4783e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // We check before assembling an instruction that there is sufficient 4793e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // space to write an instruction and its relocation information. 4803e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // The relocation writer's position must be kGap bytes above the end of 4819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // the generated instructions. This leaves enough space for the 4823e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // longest possible x64 instruction, 15 bytes, and the longest possible 4833e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // relocation information encoding, RelocInfoWriter::kMaxLength == 16. 4843e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // (There is a 15 byte limit on x64 instruction length that rules out some 4853e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // otherwise valid instructions.) 4863e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // This allows for a single, fast space check per instruction. 4879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org static const int kGap = 32; 4889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 4899085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org public: 4909085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Create an assembler. Instructions and relocation information are emitted 4919085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // into a buffer, with the instructions starting from the beginning and the 4929085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // relocation information starting from the end of the buffer. See CodeDesc 4939085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // for a detailed comment on the layout (globals.h). 4949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // 4959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // If the provided buffer is NULL, the assembler allocates and grows its own 4969085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // buffer, and buffer_size determines the initial buffer size. The buffer is 4979085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // owned by the assembler and deallocated upon destruction of the assembler. 4989085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // 4999085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // If the provided buffer is not NULL, the assembler uses the provided buffer 5009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // for code generation and assumes its size to be buffer_size. If the buffer 5019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // is too small, a fatal error occurs. No deallocation of the buffer is done 5029085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // upon destruction of the assembler. 503c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Assembler(Isolate* isolate, void* buffer, int buffer_size); 5048e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org virtual ~Assembler() { } 5059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 5069085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // GetCode emits any pending (non-emitted) code and fills the descriptor 5079085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // desc. GetCode() is idempotent; it returns the same result if no other 5089085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Assembler functions are invoked in between GetCode() calls. 5099085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void GetCode(CodeDesc* desc); 5109085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 511c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Read/Modify the code target in the relative branch/call instruction at pc. 512c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // On the x64 architecture, we use relative jumps with a 32-bit displacement 513c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // to jump to other Code objects in the Code space in the heap. 514c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Jumps to C functions are done indirectly through a 64-bit register holding 515c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // the absolute address of the target. 516c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // These functions convert between absolute Addresses of Code objects and 517c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // the relative displacements stored in the code. 51897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org static inline Address target_address_at(Address pc, 51997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool); 52097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org static inline void set_target_address_at(Address pc, 52197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool, 5226a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Address target, 5236a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org ICacheFlushMode icache_flush_mode = 5246a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org FLUSH_ICACHE_IF_NEEDED) ; 52597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org static inline Address target_address_at(Address pc, Code* code) { 52697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; 52797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return target_address_at(pc, constant_pool); 52897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org } 52997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org static inline void set_target_address_at(Address pc, 53097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org Code* code, 5316a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Address target, 5326a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org ICacheFlushMode icache_flush_mode = 5336a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org FLUSH_ICACHE_IF_NEEDED) { 53497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; 5356a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org set_target_address_at(pc, constant_pool, target, icache_flush_mode); 53697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org } 537c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 53889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org // Return the code target address at a call site from the return address 53989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org // of that call in the instruction stream. 54089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org static inline Address target_address_from_return_address(Address pc); 54189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 5429d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org // Return the code target address of the patch debug break slot 5439d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org inline static Address break_address_from_return_address(Address pc); 5449d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 5453811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // This sets the branch destination (which is in the instruction on x64). 546c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org // This is for calls and branches within generated code. 54788aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org inline static void deserialization_set_special_target_at( 54897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org Address instruction_payload, Code* code, Address target) { 54997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org set_target_address_at(instruction_payload, code, target); 5503811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 551c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 552af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org static inline RelocInfo::Mode RelocInfoNone() { 553af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (kPointerSize == kInt64Size) { 554af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org return RelocInfo::NONE64; 555af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } else { 556e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kPointerSize == kInt32Size); 557af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org return RelocInfo::NONE32; 558af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } 559af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } 560af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org 561c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org inline Handle<Object> code_target_object_handle_at(Address pc); 5626e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org inline Address runtime_entry_at(Address pc); 5633811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Number of bytes taken up by the branch target in the code. 56488aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org static const int kSpecialTargetSize = 4; // Use 32-bit displacement. 5659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Distance between the address of the code target in the call instruction 566c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // and the return address pushed on the stack. 567c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement. 568594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // The length of call(kScratchRegister). 569594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kCallScratchRegisterInstructionLength = 3; 570594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // The length of call(Immediate32). 571abafe3dbcc62abc040625a8356be42bbd0cf7608danno@chromium.org static const int kShortCallInstructionLength = 5; 572594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // The length of movq(kScratchRegister, address). 573594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kMoveAddressIntoScratchRegisterInstructionLength = 574594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 2 + kPointerSize; 575594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // The length of movq(kScratchRegister, address) and call(kScratchRegister). 576594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kCallSequenceLength = 577594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org kMoveAddressIntoScratchRegisterInstructionLength + 578594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org kCallScratchRegisterInstructionLength; 579594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 580594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // The js return and debug break slot must be able to contain an indirect 581594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // call sequence, some x64 JS code is padded with int3 to make it large 582594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // enough to hold an instruction when the debugger patches it. 583594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kJSReturnSequenceLength = kCallSequenceLength; 584594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kDebugBreakSlotLength = kCallSequenceLength; 585594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kPatchDebugBreakSlotReturnOffset = kCallTargetAddressOffset; 586594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // Distance between the start of the JS return sequence and where the 587594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // 32-bit displacement of a short call would be. The short call is from 588594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // SetDebugBreakAtIC from debug-x64.cc. 589594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kPatchReturnSequenceAddressOffset = 590594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org kJSReturnSequenceLength - kPatchDebugBreakSlotReturnOffset; 591594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // Distance between the start of the JS return sequence and where the 592594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // 32-bit displacement of a short call would be. The short call is from 593594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // SetDebugBreakAtIC from debug-x64.cc. 594594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kPatchDebugBreakSlotAddressOffset = 595594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org kDebugBreakSlotLength - kPatchDebugBreakSlotReturnOffset; 596594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org static const int kRealPatchReturnSequenceAddressOffset = 597594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org kMoveAddressIntoScratchRegisterInstructionLength - kPointerSize; 5982356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 5995d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // One byte opcode for test eax,0xXXXXXXXX. 6005d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org static const byte kTestEaxByte = 0xA9; 601d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // One byte opcode for test al, 0xXX. 602d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com static const byte kTestAlByte = 0xA8; 603496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // One byte opcode for nop. 604496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org static const byte kNopByte = 0x90; 605496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 606496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // One byte prefix for a short conditional jump. 607496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org static const byte kJccShortPrefix = 0x70; 608496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org static const byte kJncShortOpcode = kJccShortPrefix | not_carry; 609496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org static const byte kJcShortOpcode = kJccShortPrefix | carry; 610212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org static const byte kJnzShortOpcode = kJccShortPrefix | not_zero; 611212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org static const byte kJzShortOpcode = kJccShortPrefix | zero; 612496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 6132356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 6149085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 6159085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Code generation 6169085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // 61771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Function names correspond one-to-one to x64 instruction mnemonics. 61871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Unless specified otherwise, instructions operate on 64-bit operands. 61971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // 62071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // If we need versions of an assembly instruction that operate on different 62171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // width arguments, we add a single-letter suffix specifying the width. 622eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // This is done for the following instructions: mov, cmp, inc, dec, 623eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // add, sub, and test. 62471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // There are no versions of these instructions without the suffix. 62571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. 62671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. 62771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // - Instructions on 32-bit (doubleword) operands/registers use 'l'. 62871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // - Instructions on 64-bit (quadword) operands/registers use 'q'. 629895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // - Instructions on operands/registers with pointer size use 'p'. 6309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 6312f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size); 6322f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 633ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org#define DECLARE_INSTRUCTION(instruction) \ 634fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org template<class P1> \ 635fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void instruction##p(P1 p1) { \ 636fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org emit_##instruction(p1, kPointerSize); \ 637fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } \ 638fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org \ 639fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org template<class P1> \ 640fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void instruction##l(P1 p1) { \ 641fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org emit_##instruction(p1, kInt32Size); \ 642fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } \ 643fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org \ 644fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org template<class P1> \ 645fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void instruction##q(P1 p1) { \ 646fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org emit_##instruction(p1, kInt64Size); \ 647fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } \ 648fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org \ 649ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org template<class P1, class P2> \ 650ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org void instruction##p(P1 p1, P2 p2) { \ 651ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_##instruction(p1, p2, kPointerSize); \ 652ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } \ 653ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org \ 654ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org template<class P1, class P2> \ 655ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org void instruction##l(P1 p1, P2 p2) { \ 656ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_##instruction(p1, p2, kInt32Size); \ 657ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } \ 658ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org \ 659ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org template<class P1, class P2> \ 660ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org void instruction##q(P1 p1, P2 p2) { \ 661ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_##instruction(p1, p2, kInt64Size); \ 662fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } \ 663fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org \ 664fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org template<class P1, class P2, class P3> \ 665fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void instruction##p(P1 p1, P2 p2, P3 p3) { \ 666fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org emit_##instruction(p1, p2, p3, kPointerSize); \ 667fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } \ 668fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org \ 669fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org template<class P1, class P2, class P3> \ 670fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void instruction##l(P1 p1, P2 p2, P3 p3) { \ 671fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org emit_##instruction(p1, p2, p3, kInt32Size); \ 672fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } \ 673fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org \ 674fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org template<class P1, class P2, class P3> \ 675fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void instruction##q(P1 p1, P2 p2, P3 p3) { \ 676fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org emit_##instruction(p1, p2, p3, kInt64Size); \ 677ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 678ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION) 679ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org#undef DECLARE_INSTRUCTION 680ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 6819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Insert the smallest number of nop instructions 6829085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // possible to align the pc offset to a multiple 68383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // of m, where m must be a power of 2. 6849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void Align(int m); 68564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org void Nop(int bytes = 1); 6865ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org // Aligns code to something that's optimal for a jump target for the platform. 6875ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org void CodeTargetAlign(); 6889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 6899085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Stack 690e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void pushfq(); 691e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void popfq(); 6929085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 693763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void pushq(Immediate value); 6940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Push a 32 bit integer, and guarantee that it is actually pushed as a 6950ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // 32 bit value, the normal push will optimize the 8 bit case. 696763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void pushq_imm32(int32_t imm32); 697763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void pushq(Register src); 698763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void pushq(const Operand& src); 6999085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 700763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void popq(Register dst); 701763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void popq(const Operand& dst); 7029085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 703e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void enter(Immediate size); 7049085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void leave(); 7059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 7069085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Moves 707755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void movb(Register dst, const Operand& src); 708e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void movb(Register dst, Immediate imm); 709755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void movb(const Operand& dst, Register src); 710e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org void movb(const Operand& dst, Immediate imm); 711755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 7123811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Move the low 16 bits of a 64-bit register value to a 16-bit 7133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // memory location. 714e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org void movw(Register dst, const Operand& src); 7153811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void movw(const Operand& dst, Register src); 716e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org void movw(const Operand& dst, Immediate imm); 7173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 718911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Move the offset of the label location relative to the current 719911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // position (after the move) to the destination. 720911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void movl(const Operand& dst, Label* src); 721e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 722e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Loads a pointer into a register with a relocation mode. 7239cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org void movp(Register dst, void* ptr, RelocInfo::Mode rmode); 7249cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 725e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Loads a 64-bit immediate into a register. 726e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org void movq(Register dst, int64_t value); 727ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org void movq(Register dst, uint64_t value); 728755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 7292ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org void movsxbl(Register dst, const Operand& src); 7303811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void movsxbq(Register dst, const Operand& src); 7312ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org void movsxwl(Register dst, const Operand& src); 7323811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void movsxwq(Register dst, const Operand& src); 7335aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void movsxlq(Register dst, Register src); 7343e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void movsxlq(Register dst, const Operand& src); 7355aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 736b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Repeated moves. 737b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 738b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void repmovsb(); 739b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void repmovsw(); 740895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void repmovsp() { emit_repmovs(kPointerSize); } 741895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void repmovsl() { emit_repmovs(kInt32Size); } 742895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void repmovsq() { emit_repmovs(kInt64Size); } 743b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 744badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // Instruction to load from an immediate 64-bit pointer into RAX. 745755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void load_rax(void* ptr, RelocInfo::Mode rmode); 746e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void load_rax(ExternalReference ext); 7479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 7483e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // Conditional moves. 7493e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cmovq(Condition cc, Register dst, Register src); 7503e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cmovq(Condition cc, Register dst, const Operand& src); 7513e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cmovl(Condition cc, Register dst, Register src); 7523e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cmovl(Condition cc, Register dst, const Operand& src); 7539085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 7543e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cmpb(Register dst, Immediate src) { 7553e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org immediate_arithmetic_op_8(0x7, dst, src); 7563e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org } 7573e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 758911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpb_al(Immediate src); 759911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 760911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpb(Register dst, Register src) { 7612f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op_8(0x3A, dst, src); 762911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 763911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 764911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpb(Register dst, const Operand& src) { 7652f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op_8(0x3A, dst, src); 766911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 767911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 768911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpb(const Operand& dst, Register src) { 7692f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op_8(0x38, src, dst); 770911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 771911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 772eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void cmpb(const Operand& dst, Immediate src) { 773eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org immediate_arithmetic_op_8(0x7, dst, src); 774eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 775eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 776911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpw(const Operand& 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, Immediate src) { 781911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org immediate_arithmetic_op_16(0x7, dst, src); 782911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 783911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 784911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpw(Register dst, const Operand& src) { 785911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org arithmetic_op_16(0x3B, dst, src); 786911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 787911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 788911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpw(Register dst, Register src) { 789911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org arithmetic_op_16(0x3B, dst, src); 790911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 791911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 792911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void cmpw(const Operand& dst, Register src) { 793911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org arithmetic_op_16(0x39, src, dst); 794911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 795911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 796b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void andb(Register dst, Immediate src) { 797b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org immediate_arithmetic_op_8(0x4, dst, src); 798b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 7999d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 8009d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void decb(Register dst); 8019d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void decb(const Operand& dst); 8029085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 803e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Sign-extends rax into rdx:rax. 804e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void cqo(); 8050b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Sign-extends eax into edx:eax. 8060b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org void cdq(); 8079085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 808e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Multiply rax by src, put the result in rdx:rax. 8099085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void mul(Register src); 8109085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 8112f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode) \ 8122f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void instruction##p(Register dst, Immediate imm8) { \ 8132f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shift(dst, imm8, subcode, kPointerSize); \ 8142f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org } \ 8152f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org \ 8162f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void instruction##l(Register dst, Immediate imm8) { \ 8172f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shift(dst, imm8, subcode, kInt32Size); \ 8182f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org } \ 8192f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org \ 8202f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void instruction##q(Register dst, Immediate imm8) { \ 8212f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shift(dst, imm8, subcode, kInt64Size); \ 8222f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org } \ 8232f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org \ 8242f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void instruction##p_cl(Register dst) { \ 8252f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shift(dst, subcode, kPointerSize); \ 8262f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org } \ 8272f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org \ 8282f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void instruction##l_cl(Register dst) { \ 8292f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shift(dst, subcode, kInt32Size); \ 8302f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org } \ 8312f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org \ 8322f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void instruction##q_cl(Register dst) { \ 8332f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shift(dst, subcode, kInt64Size); \ 8342f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org } 8352f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION) 8362f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org#undef DECLARE_SHIFT_INSTRUCTION 837e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 838e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Shifts dst:src left by cl bits, affecting only dst. 839e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void shld(Register dst, Register src); 840e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 841e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Shifts src:dst right by cl bits, affecting only dst. 842e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void shrd(Register dst, Register src); 843e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 844e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void store_rax(void* dst, RelocInfo::Mode mode); 845e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void store_rax(ExternalReference ref); 8469085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 847911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void subb(Register dst, Immediate src) { 848911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org immediate_arithmetic_op_8(0x5, dst, src); 849911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 850911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 8519d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void testb(Register dst, Register src); 852755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void testb(Register reg, Immediate mask); 853755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void testb(const Operand& op, Immediate mask); 854b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void testb(const Operand& op, Register reg); 855755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 8569085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Bit operations. 8579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void bt(const Operand& dst, Register src); 8589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void bts(const Operand& dst, Register src); 859f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void bsrl(Register dst, Register src); 8609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 8619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Miscellaneous 8629d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void clc(); 8637979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org void cld(); 864eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void cpuid(); 8659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void hlt(); 8669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void int3(); 8679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void nop(); 8689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void ret(int imm16); 869eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void setcc(Condition cc, Register reg); 8709085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 8719085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Label operations & relative jumps (PPUM Appendix D) 8729085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // 8739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Takes a branch opcode (cc) and a label (L) and generates 8749085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // either a backward branch or a forward branch and links it 8759085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // to the label fixup chain. Usage: 8769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // 8779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Label L; // unbound label 8789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // j(cc, &L); // forward branch to unbound label 8799085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // bind(&L); // bind label to the current pc 8809085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // j(cc, &L); // backward branch to bound label 8819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // bind(&L); // illegal: a label may be bound only once 8829085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // 8839085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Note: The same Label can be used for forward and backward branches 8849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // but it may be bound only once. 8859085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 8869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void bind(Label* L); // binds an unbound label L to the current code position 8879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 8889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Calls 889e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Call near relative 32-bit displacement, relative to next instruction. 8909085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void call(Label* L); 8916e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org void call(Address entry, RelocInfo::Mode rmode); 8928e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org void call(Handle<Code> target, 8934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org RelocInfo::Mode rmode = RelocInfo::CODE_TARGET, 894471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TypeFeedbackId ast_id = TypeFeedbackId::None()); 895e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 89683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // Calls directly to the given address using a relative offset. 89783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // Should only ever be used in Code objects for calls within the 89883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // same Code object. Should not be used when generating new code (use labels), 89983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // but only when patching existing code. 90083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org void call(Address target); 90183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 902e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Call near absolute indirect, address in register 903e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void call(Register adr); 904e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 9059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Jumps 906e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Jump short or near relative. 907c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Use a 32-bit signed displacement. 90883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Unconditional jump to L 90983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void jmp(Label* L, Label::Distance distance = Label::kFar); 9106e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org void jmp(Address entry, RelocInfo::Mode rmode); 911c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org void jmp(Handle<Code> target, RelocInfo::Mode rmode); 912e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 913e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Jump near absolute indirect (r64) 914e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void jmp(Register adr); 9159085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9169085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Conditional jumps 91783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void j(Condition cc, 91883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* L, 91983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance distance = Label::kFar); 9206e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org void j(Condition cc, Address entry, RelocInfo::Mode rmode); 921c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode); 9229085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9239085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Floating-point operations 9249085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fld(int i); 9259085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9269085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fld1(); 9279085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fldz(); 928ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org void fldpi(); 929a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void fldln2(); 9309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9319085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fld_s(const Operand& adr); 9329085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fld_d(const Operand& adr); 9339085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9349085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fstp_s(const Operand& adr); 9359085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fstp_d(const Operand& adr); 9363811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void fstp(int index); 9379085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9389085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fild_s(const Operand& adr); 9399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fild_d(const Operand& adr); 9409085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9419085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fist_s(const Operand& adr); 9429085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9439085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fistp_s(const Operand& adr); 9449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fistp_d(const Operand& adr); 9459085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9469085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fisttp_s(const Operand& adr); 947b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void fisttp_d(const Operand& adr); 9489085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9499085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fabs(); 9509085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fchs(); 9519085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fadd(int i); 9539085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fsub(int i); 9549085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fmul(int i); 9559085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fdiv(int i); 9569085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fisub_s(const Operand& adr); 9589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void faddp(int i = 1); 9609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fsubp(int i = 1); 9619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fsubrp(int i = 1); 9629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fmulp(int i = 1); 9639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fdivp(int i = 1); 9649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fprem(); 9659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fprem1(); 9669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fxch(int i = 1); 9689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fincstp(); 9699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void ffree(int i = 0); 9709085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9719085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void ftst(); 9729085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fucomp(int i); 9739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fucompp(); 9743811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void fucomi(int i); 9753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void fucomip(); 9763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 9779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fcompp(); 9789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fnstsw_ax(); 9799085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fwait(); 9809085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void fnclex(); 9819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9825aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void fsin(); 9835aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void fcos(); 9841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org void fptan(); 985a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void fyl2x(); 98664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org void f2xm1(); 98764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org void fscale(); 98864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org void fninit(); 9895aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 9909085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void frndint(); 9919085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9923e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void sahf(); 9933e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 994ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org // SSE instructions 995ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void movaps(XMMRegister dst, XMMRegister src); 996ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void movss(XMMRegister dst, const Operand& src); 997ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void movss(const Operand& dst, XMMRegister src); 998af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void shufps(XMMRegister dst, XMMRegister src, byte imm8); 999ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1000ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void cvttss2si(Register dst, const Operand& src); 1001ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void cvttss2si(Register dst, XMMRegister src); 1002ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void cvtlsi2ss(XMMRegister dst, Register src); 1003ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1004ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void andps(XMMRegister dst, XMMRegister src); 1005af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void andps(XMMRegister dst, const Operand& src); 1006057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org void orps(XMMRegister dst, XMMRegister src); 1007af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void orps(XMMRegister dst, const Operand& src); 1008057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org void xorps(XMMRegister dst, XMMRegister src); 1009af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void xorps(XMMRegister dst, const Operand& src); 1010af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 1011af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void addps(XMMRegister dst, XMMRegister src); 1012af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void addps(XMMRegister dst, const Operand& src); 1013af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void subps(XMMRegister dst, XMMRegister src); 1014af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void subps(XMMRegister dst, const Operand& src); 1015af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void mulps(XMMRegister dst, XMMRegister src); 1016af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void mulps(XMMRegister dst, const Operand& src); 1017af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void divps(XMMRegister dst, XMMRegister src); 1018af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org void divps(XMMRegister dst, const Operand& src); 1019ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1020ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void movmskps(Register dst, XMMRegister src); 1021ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 10223e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // SSE2 instructions 1023357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org void movd(XMMRegister dst, Register src); 1024ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org void movd(Register dst, XMMRegister src); 1025ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org void movq(XMMRegister dst, Register src); 1026ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org void movq(Register dst, XMMRegister src); 1027160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org void movq(XMMRegister dst, XMMRegister src); 1028357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 1029160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // Don't use this unless it's important to keep the 1030160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // top half of the destination register unchanged. 1031160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // Used movaps when moving double values and movq for integer 1032160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // values in xmm registers. 1033357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org void movsd(XMMRegister dst, XMMRegister src); 1034160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 1035160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org void movsd(const Operand& dst, XMMRegister src); 1036357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org void movsd(XMMRegister dst, const Operand& src); 10373e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 10380ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void movdqa(const Operand& dst, XMMRegister src); 10390ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void movdqa(XMMRegister dst, const Operand& src); 10400ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 1041e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void movdqu(const Operand& dst, XMMRegister src); 1042e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void movdqu(XMMRegister dst, const Operand& src); 1043e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1044160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org void movapd(XMMRegister dst, XMMRegister src); 104540b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org 1046ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org void psllq(XMMRegister reg, byte imm8); 1047ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 10489085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void cvttsd2si(Register dst, const Operand& src); 10490a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org void cvttsd2si(Register dst, XMMRegister src); 1050dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org void cvttsd2siq(Register dst, XMMRegister src); 1051a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void cvttsd2siq(Register dst, const Operand& src); 10529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 10533e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cvtlsi2sd(XMMRegister dst, const Operand& src); 10543e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cvtlsi2sd(XMMRegister dst, Register src); 10553e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cvtqsi2sd(XMMRegister dst, const Operand& src); 10563e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void cvtqsi2sd(XMMRegister dst, Register src); 10579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 105840b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org 1059357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org void cvtss2sd(XMMRegister dst, XMMRegister src); 106040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org void cvtss2sd(XMMRegister dst, const Operand& src); 106140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org void cvtsd2ss(XMMRegister dst, XMMRegister src); 106240b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org 106340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org void cvtsd2si(Register dst, XMMRegister src); 106440b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org void cvtsd2siq(Register dst, XMMRegister src); 1065357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 10669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void addsd(XMMRegister dst, XMMRegister src); 10671f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org void addsd(XMMRegister dst, const Operand& src); 10689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void subsd(XMMRegister dst, XMMRegister src); 10699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void mulsd(XMMRegister dst, XMMRegister src); 10701f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org void mulsd(XMMRegister dst, const Operand& src); 10719085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void divsd(XMMRegister dst, XMMRegister src); 10729085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 10735d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org void andpd(XMMRegister dst, XMMRegister src); 10745d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org void orpd(XMMRegister dst, XMMRegister src); 10755c838251403b0be9a882540f1922577abba4c872ager@chromium.org void xorpd(XMMRegister dst, XMMRegister src); 10764111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org void sqrtsd(XMMRegister dst, XMMRegister src); 10777e6132b924829c353864933f29124419916db550machenbach@chromium.org void sqrtsd(XMMRegister dst, const Operand& src); 10785c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10795c838251403b0be9a882540f1922577abba4c872ager@chromium.org void ucomisd(XMMRegister dst, XMMRegister src); 108040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org void ucomisd(XMMRegister dst, const Operand& src); 1081ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void cmpltsd(XMMRegister dst, XMMRegister src); 1082ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1083ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void movmskpd(Register dst, XMMRegister src); 1084ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1085ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org // SSE 4.1 instruction 1086ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void extractps(Register dst, XMMRegister src, byte imm8); 10873e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 1088160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org enum RoundingMode { 1089160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org kRoundToNearest = 0x0, 1090160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org kRoundDown = 0x1, 1091160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org kRoundUp = 0x2, 1092160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org kRoundToZero = 0x3 1093160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org }; 1094160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 1095160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode); 1096160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 10979085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Debugging 10989085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void Print(); 10999085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Check the code size generated from label to here. 11014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int SizeOfCodeGeneratedSince(Label* label) { 11024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return pc_offset() - label->pos(); 11034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 11049085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Mark address of the ExitJSFrame code. 11069085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void RecordJSReturn(); 11079085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11082356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Mark address of a debug break slot. 11092356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org void RecordDebugBreakSlot(); 11102356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 11119085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Record a comment relocation entry that can be used by a disassembler. 1112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Use --code-comments to enable. 11133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org void RecordComment(const char* msg, bool force = false); 11149085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1115763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org // Allocate a constant pool of the correct size for the generated code. 11169fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); 1117763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 1118763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org // Generate the constant pool for the generated code. 1119763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void PopulateConstantPool(ConstantPoolArray* constant_pool); 1120763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 1121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Writes a single word of data in the code stream. 1122a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Used for inline tables, e.g., jump-tables. 11230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void db(uint8_t data); 1124a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void dd(uint32_t data); 1125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1126f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org PositionsRecorder* positions_recorder() { return &positions_recorder_; } 11279085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11289085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Check if there is less than kGap bytes available in the buffer. 11299085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // If this is the case, we need to grow the buffer before emitting 11309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // an instruction or relocation information. 11314af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org inline bool buffer_overflow() const { 11324af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org return pc_ >= reloc_info_writer.pos() - kGap; 11334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 11349085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11359085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Get the number of bytes available in the buffer. 1136c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org inline int available_space() const { 1137c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org return static_cast<int>(reloc_info_writer.pos() - pc_); 1138c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org } 11399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 114064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org static bool IsNop(Address addr); 11412356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 11429085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Avoid overflows for displacements etc. 11439085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org static const int kMaximalBufferSize = 512*MB; 11449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com byte byte_at(int pos) { return buffer_[pos]; } 1146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void set_byte_at(int pos, byte value) { buffer_[pos] = value; } 1147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1148f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org protected: 1149f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Call near indirect 1150f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void call(const Operand& operand); 1151f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 1152f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Jump near absolute indirect (m64) 1153f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void jmp(const Operand& src); 1154f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 11559085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org private: 11569085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org byte* addr_at(int pos) { return buffer_ + pos; } 11579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org uint32_t long_at(int pos) { 11589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return *reinterpret_cast<uint32_t*>(addr_at(pos)); 11599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 11609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void long_at_put(int pos, uint32_t x) { 11619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; 11629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 11639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // code emission 11659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void GrowBuffer(); 1166755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 1167755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void emit(byte x) { *pc_++ = x; } 1168755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org inline void emitl(uint32_t x); 1169fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org inline void emitp(void* x, RelocInfo::Mode rmode); 1170c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org inline void emitq(uint64_t x); 1171e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emitw(uint16_t x); 11728e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org inline void emit_code_target(Handle<Code> target, 11738e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org RelocInfo::Mode rmode, 1174471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TypeFeedbackId ast_id = TypeFeedbackId::None()); 11756e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode); 1176755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org void emit(Immediate x) { emitl(x.value_); } 11779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 117871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Emits a REX prefix that encodes a 64-bit operand size and 117971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // the top bit of both register codes. 1180755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1181755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // REX.W is set. 11823e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org inline void emit_rex_64(XMMRegister reg, Register rm_reg); 1183ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org inline void emit_rex_64(Register reg, XMMRegister rm_reg); 1184ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org inline void emit_rex_64(Register reg, Register rm_reg); 118571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 118671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Emits a REX prefix that encodes a 64-bit operand size and 118771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // the top bit of the destination, index, and base register codes. 1188755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // The high bit of reg is used for REX.R, the high bit of op's base 1189755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // register is used for REX.B, and the high bit of op's index register 1190755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // is used for REX.X. REX.W is set. 119171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org inline void emit_rex_64(Register reg, const Operand& op); 11923e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org inline void emit_rex_64(XMMRegister reg, const Operand& op); 1193e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1194e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emits a REX prefix that encodes a 64-bit operand size and 1195e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // the top bit of the register code. 1196e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // The high bit of register is used for REX.B. 1197e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // REX.W is set and REX.R and REX.X are clear. 1198e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emit_rex_64(Register rm_reg); 1199e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1200e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emits a REX prefix that encodes a 64-bit operand size and 1201e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // the top bit of the index and base register codes. 1202e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // The high bit of op's base register is used for REX.B, and the high 1203e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // bit of op's index register is used for REX.X. 1204e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // REX.W is set and REX.R clear. 1205e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emit_rex_64(const Operand& op); 1206e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1207e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size. 1208e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void emit_rex_64() { emit(0x48); } 1209755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 1210755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1211e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // REX.W is clear. 1212755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org inline void emit_rex_32(Register reg, Register rm_reg); 1213755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 1214755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // The high bit of reg is used for REX.R, the high bit of op's base 1215755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // register is used for REX.B, and the high bit of op's index register 1216755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // is used for REX.X. REX.W is cleared. 1217755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org inline void emit_rex_32(Register reg, const Operand& op); 1218755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 1219e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // High bit of rm_reg goes to REX.B. 1220e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // REX.W, REX.R and REX.X are clear. 1221e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emit_rex_32(Register rm_reg); 1222e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1223e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // High bit of base goes to REX.B and high bit of index to REX.X. 1224e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // REX.W and REX.R are clear. 1225e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emit_rex_32(const Operand& op); 1226e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1227755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1228755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // REX.W is cleared. If no REX bits are set, no byte is emitted. 1229755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org inline void emit_optional_rex_32(Register reg, Register rm_reg); 1230755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 1231755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // The high bit of reg is used for REX.R, the high bit of op's base 1232755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // register is used for REX.B, and the high bit of op's index register 1233755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing 1234755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // is emitted. 1235755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org inline void emit_optional_rex_32(Register reg, const Operand& op); 1236755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 12373e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // As for emit_optional_rex_32(Register, Register), except that 12383e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // the registers are XMM registers. 12393e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base); 12403e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 12413e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // As for emit_optional_rex_32(Register, Register), except that 1242ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // one of the registers is an XMM registers. 12433e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org inline void emit_optional_rex_32(XMMRegister reg, Register base); 12443e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 1245ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // As for emit_optional_rex_32(Register, Register), except that 1246ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // one of the registers is an XMM registers. 1247ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org inline void emit_optional_rex_32(Register reg, XMMRegister base); 1248ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 12493e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // As for emit_optional_rex_32(Register, const Operand&), except that 12503e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // the register is an XMM register. 12513e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org inline void emit_optional_rex_32(XMMRegister reg, const Operand& op); 12523e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 1253e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Optionally do as emit_rex_32(Register) if the register number has 1254e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // the high bit set. 1255e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emit_optional_rex_32(Register rm_reg); 1256e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1257e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Optionally do as emit_rex_32(const Operand&) if the operand register 1258e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // numbers have a high bit set. 1259e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org inline void emit_optional_rex_32(const Operand& op); 1260e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1261895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_rex(int size) { 1262895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org if (size == kInt64Size) { 1263895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org emit_rex_64(); 1264895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } else { 1265e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(size == kInt32Size); 1266895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1267895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1268895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1269ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org template<class P1> 1270ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org void emit_rex(P1 p1, int size) { 1271ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (size == kInt64Size) { 1272ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_rex_64(p1); 1273ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else { 1274e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(size == kInt32Size); 1275ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_optional_rex_32(p1); 1276ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 1277ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 1278ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 1279ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org template<class P1, class P2> 1280ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org void emit_rex(P1 p1, P2 p2, int size) { 1281ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (size == kInt64Size) { 1282ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_rex_64(p1, p2); 1283ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else { 1284e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(size == kInt32Size); 1285ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org emit_optional_rex_32(p1, p2); 1286ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 1287ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 1288e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1289e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emit the ModR/M byte, and optionally the SIB byte and 1290755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // 1- or 4-byte offset for a memory operand. Also encodes 1291755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // the second operand of the operation, a register or operation 1292e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // subcode, into the reg field of the ModR/M byte. 1293e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void emit_operand(Register reg, const Operand& adr) { 12945aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org emit_operand(reg.low_bits(), adr); 1295e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } 1296e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1297e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emit the ModR/M byte, and optionally the SIB byte and 1298e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // 1- or 4-byte offset for a memory operand. Also used to encode 1299e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // a three-bit opcode extension into the ModR/M byte. 1300e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void emit_operand(int rm, const Operand& adr); 1301e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1302e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emit a ModR/M byte with registers coded in the reg and rm_reg fields. 1303e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void emit_modrm(Register reg, Register rm_reg) { 13045aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits()); 1305e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } 1306e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1307e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emit a ModR/M byte with an operation subcode in the reg field and 1308e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // a register in the rm_reg field. 1309e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void emit_modrm(int code, Register rm_reg) { 1310e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_uint3(code)); 13115aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org emit(0xC0 | code << 3 | rm_reg.low_bits()); 1312755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org } 131371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 13149085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Emit the code-object-relative offset of the label's position 13159085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org inline void emit_code_relative_offset(Label* label); 13169085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1317ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org // The first argument is the reg field, the second argument is the r/m field. 1318ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void emit_sse_operand(XMMRegister dst, XMMRegister src); 1319ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void emit_sse_operand(XMMRegister reg, const Operand& adr); 1320a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void emit_sse_operand(Register reg, const Operand& adr); 1321ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void emit_sse_operand(XMMRegister dst, Register src); 1322ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void emit_sse_operand(Register dst, XMMRegister src); 1323ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1324755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Emit machine code for one of the operations ADD, ADC, SUB, SBC, 1325755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // AND, OR, XOR, or CMP. The encodings of these operations are all 1326755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // similar, differing just in the opcode or in the reg field of the 1327e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // ModR/M byte. 13282f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void arithmetic_op_8(byte opcode, Register reg, Register rm_reg); 13292f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg); 1330911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void arithmetic_op_16(byte opcode, Register reg, Register rm_reg); 1331911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg); 13322f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // Operate on operands/registers with pointer size, 32-bit or 64-bit size. 13332f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size); 13342f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void arithmetic_op(byte opcode, 13352f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org Register reg, 13362f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org const Operand& rm_reg, 13372f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org int size); 13383e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org // Operate on a byte in memory or register. 1339eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void immediate_arithmetic_op_8(byte subcode, 1340911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Register dst, 13413e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org Immediate src); 13423e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void immediate_arithmetic_op_8(byte subcode, 1343911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org const Operand& dst, 13443e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org Immediate src); 1345911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Operate on a word in memory or register. 1346911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void immediate_arithmetic_op_16(byte subcode, 1347911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Register dst, 1348911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Immediate src); 1349911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org void immediate_arithmetic_op_16(byte subcode, 1350911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org const Operand& dst, 1351911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Immediate src); 13522f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // Operate on operands/registers with pointer size, 32-bit or 64-bit size. 13532f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void immediate_arithmetic_op(byte subcode, 13542f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org Register dst, 13552f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org Immediate src, 13562f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org int size); 13572f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void immediate_arithmetic_op(byte subcode, 13582f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org const Operand& dst, 13592f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org Immediate src, 13602f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org int size); 1361911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1362e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Emit machine code for a shift operation. 13632f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void shift(Register dst, Immediate shift_amount, int subcode, int size); 1364e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org // Shift dst by cl % 64 bits. 13652f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org void shift(Register dst, int subcode, int size); 13669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13675aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void emit_farith(int b1, int b2, int i); 13689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // labels 1370eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // void print(Label* L); 13719085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void bind_to(Label* L, int pos); 13729085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // record reloc info for current pc_ 13749085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 13759085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1376fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // Arithmetics 1377fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_add(Register dst, Register src, int size) { 13782f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x03, dst, src, size); 1379fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1380fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1381fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_add(Register dst, Immediate src, int size) { 13822f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x0, dst, src, size); 1383fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1384fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1385fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_add(Register dst, const Operand& src, int size) { 13862f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x03, dst, src, size); 1387fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1388fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1389fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_add(const Operand& dst, Register src, int size) { 13902f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x1, src, dst, size); 1391fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1392fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1393fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_add(const Operand& dst, Immediate src, int size) { 13942f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x0, dst, src, size); 1395fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1396fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1397895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_and(Register dst, Register src, int size) { 13982f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x23, dst, src, size); 1399895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1400895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1401895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_and(Register dst, const Operand& src, int size) { 14022f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x23, dst, src, size); 1403895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1404895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1405895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_and(const Operand& dst, Register src, int size) { 14062f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x21, src, dst, size); 1407895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1408895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1409895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_and(Register dst, Immediate src, int size) { 14102f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x4, dst, src, size); 1411895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1412895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1413895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_and(const Operand& dst, Immediate src, int size) { 14142f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x4, dst, src, size); 1415895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1416895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 14177a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_cmp(Register dst, Register src, int size) { 14182f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x3B, dst, src, size); 14197a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org } 14207a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 14217a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_cmp(Register dst, const Operand& src, int size) { 14222f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x3B, dst, src, size); 14237a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org } 14247a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 14257a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_cmp(const Operand& dst, Register src, int size) { 14262f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x39, src, dst, size); 14277a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org } 14287a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 14297a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_cmp(Register dst, Immediate src, int size) { 14302f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x7, dst, src, size); 14317a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org } 14327a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 14337a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_cmp(const Operand& dst, Immediate src, int size) { 14342f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x7, dst, src, size); 14357a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org } 14367a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 14377a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_dec(Register dst, int size); 14387a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_dec(const Operand& dst, int size); 14397a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 1440fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // Divide rdx:rax by src. Quotient in rax, remainder in rdx when size is 64. 1441fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // Divide edx:eax by lower 32 bits of src. Quotient in eax, remainder in edx 1442fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // when size is 32. 1443fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_idiv(Register src, int size); 14447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void emit_div(Register src, int size); 1445fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1446fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // Signed multiply instructions. 1447fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32. 1448fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_imul(Register src, int size); 1449fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_imul(Register dst, Register src, int size); 1450fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_imul(Register dst, const Operand& src, int size); 1451fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_imul(Register dst, Register src, Immediate imm, int size); 1452fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 14537a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_inc(Register dst, int size); 14547a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_inc(const Operand& dst, int size); 14557a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 1456895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_lea(Register dst, const Operand& src, int size); 1457895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 14587a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_mov(Register dst, const Operand& src, int size); 14597a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_mov(Register dst, Register src, int size); 14607a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_mov(const Operand& dst, Register src, int size); 14617a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_mov(Register dst, Immediate value, int size); 14627a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_mov(const Operand& dst, Immediate value, int size); 14637a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 1464895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_movzxb(Register dst, const Operand& src, int size); 14657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void emit_movzxb(Register dst, Register src, int size); 1466895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_movzxw(Register dst, const Operand& src, int size); 1467895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_movzxw(Register dst, Register src, int size); 1468895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 14697a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_neg(Register dst, int size); 14707a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_neg(const Operand& dst, int size); 14717a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 1472895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_not(Register dst, int size); 1473895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_not(const Operand& dst, int size); 1474895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1475895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_or(Register dst, Register src, int size) { 14762f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x0B, dst, src, size); 1477895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1478895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1479895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_or(Register dst, const Operand& src, int size) { 14802f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x0B, dst, src, size); 1481895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1482895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1483895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_or(const Operand& dst, Register src, int size) { 14842f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x9, src, dst, size); 1485895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1486895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1487895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_or(Register dst, Immediate src, int size) { 14882f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x1, dst, src, size); 1489895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1490895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1491895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_or(const Operand& dst, Immediate src, int size) { 14922f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x1, dst, src, size); 1493895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1494895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1495895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_repmovs(int size); 1496895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 14977a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_sbb(Register dst, Register src, int size) { 14982f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x1b, dst, src, size); 14997a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org } 15007a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 1501fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_sub(Register dst, Register src, int size) { 15022f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x2B, dst, src, size); 1503fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1504fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1505fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_sub(Register dst, Immediate src, int size) { 15062f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x5, dst, src, size); 1507fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1508fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1509fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_sub(Register dst, const Operand& src, int size) { 15102f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x2B, dst, src, size); 1511fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1512fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1513fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_sub(const Operand& dst, Register src, int size) { 15142f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x29, src, dst, size); 1515fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1516fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 1517fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void emit_sub(const Operand& dst, Immediate src, int size) { 15182f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x5, dst, src, size); 1519fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 1520fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org 15217a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_test(Register dst, Register src, int size); 15227a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_test(Register reg, Immediate mask, int size); 15237a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_test(const Operand& op, Register reg, int size); 15247a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org void emit_test(const Operand& op, Immediate mask, int size); 15257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void emit_test(Register reg, const Operand& op, int size) { 15267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return emit_test(op, reg, size); 15277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1528ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 1529895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_xchg(Register dst, Register src, int size); 15307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void emit_xchg(Register dst, const Operand& src, int size); 1531895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1532895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_xor(Register dst, Register src, int size) { 15332f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org if (size == kInt64Size && dst.code() == src.code()) { 15342f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore 15352f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // there is no need to make this a 64 bit operation. 15362f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x33, dst, src, kInt32Size); 1537895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } else { 15382f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x33, dst, src, size); 1539895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1540895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1541895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1542895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_xor(Register dst, const Operand& src, int size) { 15432f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x33, dst, src, size); 1544895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1545895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1546895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_xor(Register dst, Immediate src, int size) { 15472f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x6, dst, src, size); 1548895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1549895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1550895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_xor(const Operand& dst, Immediate src, int size) { 15512f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org immediate_arithmetic_op(0x6, dst, src, size); 1552895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1553895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 1554895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org void emit_xor(const Operand& dst, Register src, int size) { 15552f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org arithmetic_op(0x31, src, dst, size); 1556895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 1557895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 15589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org friend class CodePatcher; 15599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org friend class EnsureSpace; 1560911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org friend class RegExpMacroAssemblerX64; 15619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // code generation 15639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org RelocInfoWriter reloc_info_writer; 15649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1565c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org List< Handle<Code> > code_targets_; 15669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1567f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org PositionsRecorder positions_recorder_; 1568f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org friend class PositionsRecorder; 15699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}; 15709085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15719085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15729085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Helper class that ensures that there is enough space for generating 15739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// instructions and relocation information. The constructor makes 15749085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// sure that there is enough space and (in debug mode) the destructor 15759085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// checks that we did not generate too much. 15769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgclass EnsureSpace BASE_EMBEDDED { 15779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org public: 15789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { 15794af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (assembler_->buffer_overflow()) assembler_->GrowBuffer(); 15809085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifdef DEBUG 15819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org space_before_ = assembler_->available_space(); 15829085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif 15839085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 15849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15859085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifdef DEBUG 15869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org ~EnsureSpace() { 15879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org int bytes_generated = space_before_ - assembler_->available_space(); 1588e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(bytes_generated < assembler_->kGap); 15899085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 15909085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif 15919085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15929085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org private: 15939085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Assembler* assembler_; 15949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifdef DEBUG 15959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org int space_before_; 15969085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif 15979085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}; 15989085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15999085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} } // namespace v8::internal 16005ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 16019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif // V8_X64_ASSEMBLER_X64_H_ 1602