13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 281362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// Redistribution and use in source and binary forms, with or without 381362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// modification, are permitted provided that the following conditions are 481362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// met: 581362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// 681362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// * Redistributions of source code must retain the above copyright 781362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// notice, this list of conditions and the following disclaimer. 881362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// * Redistributions in binary form must reproduce the above 981362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// copyright notice, this list of conditions and the following 1081362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// disclaimer in the documentation and/or other materials provided 1181362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// with the distribution. 1281362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// * Neither the name of Google Inc. nor the names of its 1381362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// contributors may be used to endorse or promote products derived 1481362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// from this software without specific prior written permission. 1581362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// 1681362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1781362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1881362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1981362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2081362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2181362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2281362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2381362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2481362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2581362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2681362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2781362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen 28b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifndef V8_X64_LITHIUM_CODEGEN_X64_H_ 29b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define V8_X64_LITHIUM_CODEGEN_X64_H_ 3081362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen 31b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "x64/lithium-x64.h" 3281362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen 33b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#include "checks.h" 34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "deoptimizer.h" 35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "safepoint-table.h" 36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "scopes.h" 371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include "x64/lithium-gap-resolver-x64.h" 3881362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen 39b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 { 40b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal { 4181362e16c30e9e970af6b17592f627ad8cdee4d8Kristian Monsen 42b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Forward declarations. 43b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LDeferredCode; 44b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochclass SafepointGenerator; 45b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 46b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LCodeGen BASE_EMBEDDED { 47b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 48b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) 49b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch : chunk_(chunk), 50b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch masm_(assembler), 51b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch info_(info), 52b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch current_block_(-1), 53b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch current_instruction_(-1), 54b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch instructions_(chunk->instructions()), 55b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch deoptimizations_(4), 56e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch jump_table_(4), 57b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch deoptimization_literals_(8), 58b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch inlined_function_count_(0), 59e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch scope_(info->scope()), 60b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch status_(UNUSED), 61b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch deferred_(8), 621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block osr_pc_offset_(-1), 632b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch last_lazy_deopt_pc_(0), 648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch resolver_(this), 658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch expected_safepoint_kind_(Safepoint::kSimple) { 66b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch PopulateDeoptimizationLiteralsWithInlinedFunctions(); 67b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 68b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Simple accessors. 701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block MacroAssembler* masm() const { return masm_; } 71e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch CompilationInfo* info() const { return info_; } 7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate() const { return info_->isolate(); } 7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Factory* factory() const { return isolate()->factory(); } 7444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Heap* heap() const { return isolate()->heap(); } 751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Support for converting LOperands to assembler types. 771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Register ToRegister(LOperand* op) const; 781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block XMMRegister ToDoubleRegister(LOperand* op) const; 791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool IsInteger32Constant(LConstantOperand* op) const; 801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int ToInteger32(LConstantOperand* op) const; 813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double ToDouble(LConstantOperand* op) const; 821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool IsTaggedConstant(LConstantOperand* op) const; 831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Handle<Object> ToHandle(LConstantOperand* op) const; 841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Operand ToOperand(LOperand* op) const; 851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 86b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Try to generate code for the entire chunk, but it may fail if the 87b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // chunk contains constructs we cannot handle. Returns true if the 88b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // code generation attempt succeeded. 89b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool GenerateCode(); 90b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 91b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Finish the code by setting stack height, safepoint, and bailout 92b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // information on it. 93b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void FinishCode(Handle<Code> code); 94b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 95b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Deferred code support. 96b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DoDeferredNumberTagD(LNumberTagD* instr); 97b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DoDeferredTaggedToI(LTaggedToI* instr); 98b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr); 993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void DoDeferredStackCheck(LStackCheck* instr); 1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void DoDeferredRandom(LRandom* instr); 101e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr); 10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block void DoDeferredStringCharFromCode(LStringCharFromCode* instr); 1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void DoDeferredAllocateObject(LAllocateObject* instr); 1042b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 1052b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch Label* map_check); 106b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void DoCheckMapCommon(Register reg, Handle<Map> map, 1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompareMapMode mode, LEnvironment* env); 1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Parallel move support. 111b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DoParallelMove(LParallelMove* move); 112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void DoGap(LGap* instr); 113b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 114b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Emit frame translation commands for an environment. 115b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void WriteTranslation(LEnvironment* environment, Translation* translation); 116b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 117b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Declare methods that deal with the individual node types. 118b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#define DECLARE_DO(type) void Do##type(L##type* node); 119b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 120b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#undef DECLARE_DO 121b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 122b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 123b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch enum Status { 124b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch UNUSED, 125b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch GENERATING, 126b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DONE, 127b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ABORTED 128b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 129b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 130b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool is_unused() const { return status_ == UNUSED; } 131b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool is_generating() const { return status_ == GENERATING; } 132b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool is_done() const { return status_ == DONE; } 133b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool is_aborted() const { return status_ == ABORTED; } 134b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StrictModeFlag strict_mode_flag() const { 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return info()->is_classic_mode() ? kNonStrictMode : kStrictMode; 137e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 138e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 139b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LChunk* chunk() const { return chunk_; } 140b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Scope* scope() const { return scope_; } 141b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch HGraph* graph() const { return chunk_->graph(); } 142b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 143b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int GetNextEmittedBlock(int block); 144b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 145b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void EmitClassOfTest(Label* if_true, 146b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Label* if_false, 147b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Handle<String> class_name, 148b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Register input, 1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temporary, 1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch); 151b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 152257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int GetStackSlotCount() const { return chunk()->spill_slot_count(); } 153257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int GetParameterCount() const { return scope()->num_parameters(); } 154b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 155b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void Abort(const char* format, ...); 156b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void Comment(const char* format, ...); 157b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 158b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code); } 159b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 160b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Code generation passes. Returns true if code generation should 161b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // continue. 162b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool GeneratePrologue(); 163b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool GenerateBody(); 164b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool GenerateDeferredCode(); 165e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool GenerateJumpTable(); 166b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool GenerateSafepointTable(); 167b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch enum SafepointMode { 1698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RECORD_SIMPLE_SAFEPOINT, 1708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RECORD_SAFEPOINT_WITH_REGISTERS 1718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch }; 1728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 1738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch void CallCodeGeneric(Handle<Code> code, 1748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RelocInfo::Mode mode, 1758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch LInstruction* instr, 1768b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch SafepointMode safepoint_mode, 1778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int argc); 1788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 1798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 180b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void CallCode(Handle<Code> code, 181b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch RelocInfo::Mode mode, 182b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LInstruction* instr); 1838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 18444f0eee88ff00398ff7f715fab053374d808c90dSteve Block void CallRuntime(const Runtime::Function* function, 185b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int num_arguments, 186b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LInstruction* instr); 1878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 188b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void CallRuntime(Runtime::FunctionId id, 189b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int num_arguments, 190b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LInstruction* instr) { 19144f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Runtime::Function* function = Runtime::FunctionForId(id); 192b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch CallRuntime(function, num_arguments, instr); 193b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 194b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch void CallRuntimeFromDeferred(Runtime::FunctionId id, 1968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int argc, 1978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch LInstruction* instr); 1988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 199b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Generate a direct call to a known function. Expects the function 2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // to be in rdi. 201b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void CallKnownFunction(Handle<JSFunction> function, 202b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int arity, 203257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LInstruction* instr, 204257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CallKind call_kind); 205b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 206b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2072b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void RecordSafepointWithLazyDeopt(LInstruction* instr, 2082b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch SafepointMode safepoint_mode, 2092b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch int argc); 2102b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void RegisterEnvironmentForDeoptimization(LEnvironment* environment, 2112b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch Safepoint::DeoptMode mode); 212b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DeoptimizeIf(Condition cc, LEnvironment* environment); 213b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 214b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void AddToTranslation(Translation* translation, 215b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LOperand* op, 216b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool is_tagged); 217b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void PopulateDeoptimizationData(Handle<Code> code); 218b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int DefineDeoptimizationLiteral(Handle<Object> literal); 219b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 220b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void PopulateDeoptimizationLiteralsWithInlinedFunctions(); 221b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 222b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Register ToRegister(int index) const; 223b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch XMMRegister ToDoubleRegister(int index) const; 2243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Operand BuildFastArrayOperand( 22569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LOperand* elements_pointer, 2263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LOperand* key, 227589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ElementsKind elements_kind, 2283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t offset); 229b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 230b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Specific math operations - used from DoUnaryMathOperation. 231e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void EmitIntegerMathAbs(LUnaryMathOperation* instr); 232b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DoMathAbs(LUnaryMathOperation* instr); 233b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DoMathFloor(LUnaryMathOperation* instr); 234b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DoMathRound(LUnaryMathOperation* instr); 235b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DoMathSqrt(LUnaryMathOperation* instr); 236b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DoMathPowHalf(LUnaryMathOperation* instr); 237b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DoMathLog(LUnaryMathOperation* instr); 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void DoMathTan(LUnaryMathOperation* instr); 239b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DoMathCos(LUnaryMathOperation* instr); 240b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DoMathSin(LUnaryMathOperation* instr); 241b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 242b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Support for recording safepoint and position information. 2431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void RecordSafepoint(LPointerMap* pointers, 2441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Safepoint::Kind kind, 2451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int arguments, 2462b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch Safepoint::DeoptMode mode); 2472b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode); 2482b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void RecordSafepoint(Safepoint::DeoptMode mode); 249b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void RecordSafepointWithRegisters(LPointerMap* pointers, 250b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int arguments, 2512b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch Safepoint::DeoptMode mode); 252b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void RecordPosition(int position); 253b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 254b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch static Condition TokenToCondition(Token::Value op, bool is_unsigned); 2553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void EmitGoto(int block); 256b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void EmitBranch(int left_block, int right_block, Condition cc); 2577d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch void EmitNumberUntagD(Register input, 2587d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch XMMRegister result, 2597d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch bool deoptimize_on_undefined, 2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool deoptimize_on_minus_zero, 2617d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch LEnvironment* env); 262b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 263b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Emits optimized code for typeof x == "y". Modifies input register. 264b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Returns the condition on which a final split to 265b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // true and false label should be made, to optimize fallthrough. 2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition EmitTypeofIs(Label* true_label, 2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* false_label, 2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input, 2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> type_name); 270b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 271b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Emits optimized code for %_IsObject(x). Preserves input register. 272b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Returns the condition on which a final split to 273b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // true and false label should be made, to optimize fallthrough. 274b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Condition EmitIsObject(Register input, 275b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Label* is_not_object, 276b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Label* is_object); 277b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Emits optimized code for %_IsString(x). Preserves input register. 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Returns the condition on which a final split to 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // true and false label should be made, to optimize fallthrough. 2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition EmitIsString(Register input, 2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp1, 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* is_not_string); 2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Emits optimized code for %_IsConstructCall(). 2861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Caller should branch on equal condition. 2871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void EmitIsConstructCall(Register temp); 2881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void EmitLoadFieldOrConstantFunction(Register result, 290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register object, 291257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Map> type, 292257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<String> name); 29344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 294257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Emits code for pushing either a tagged constant, a (non-double) 295257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // register, or a stack slot operand. 296257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void EmitPushTaggedOperand(LOperand* operand); 297e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Emits optimized code to deep-copy the contents of statically known 2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // object graphs (e.g. object literal boilerplate). 3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void EmitDeepCopy(Handle<JSObject> object, 3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result, 3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register source, 3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int* offset); 3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 305e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch struct JumpTableEntry { 3068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit inline JumpTableEntry(Address entry) 30744f0eee88ff00398ff7f715fab053374d808c90dSteve Block : label(), 30844f0eee88ff00398ff7f715fab053374d808c90dSteve Block address(entry) { } 30944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Label label; 31044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address address; 311e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch }; 312e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3132b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void EnsureSpaceForLazyDeopt(int space_needed); 3142b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch 315b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LChunk* const chunk_; 316b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch MacroAssembler* const masm_; 317b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch CompilationInfo* const info_; 318b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 319b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int current_block_; 320b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int current_instruction_; 321b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch const ZoneList<LInstruction*>* instructions_; 322b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ZoneList<LEnvironment*> deoptimizations_; 32344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ZoneList<JumpTableEntry> jump_table_; 324b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ZoneList<Handle<Object> > deoptimization_literals_; 325b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int inlined_function_count_; 326b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Scope* const scope_; 327b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Status status_; 328b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TranslationBuffer translations_; 329b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ZoneList<LDeferredCode*> deferred_; 330b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int osr_pc_offset_; 3312b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch int last_lazy_deopt_pc_; 332b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 333b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Builder that keeps track of safepoints in the code. The table 334b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // itself is emitted at the end of the generated code. 335b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch SafepointTableBuilder safepoints_; 336b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 337b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Compiler from a set of parallel moves to a sequential list of moves. 338b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LGapResolver resolver_; 339b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 3408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Safepoint::Kind expected_safepoint_kind_; 3418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 3428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch class PushSafepointRegistersScope BASE_EMBEDDED { 3438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch public: 3448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit PushSafepointRegistersScope(LCodeGen* codegen) 3458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : codegen_(codegen) { 3468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple); 3478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch codegen_->masm_->PushSafepointRegisters(); 3488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters; 3498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 3508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 3518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ~PushSafepointRegistersScope() { 3528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters); 3538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch codegen_->masm_->PopSafepointRegisters(); 3548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch codegen_->expected_safepoint_kind_ = Safepoint::kSimple; 3558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 3568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 3578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch private: 3588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch LCodeGen* codegen_; 3598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch }; 3608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 361b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch friend class LDeferredCode; 362b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch friend class LEnvironment; 363b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch friend class SafepointGenerator; 364b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DISALLOW_COPY_AND_ASSIGN(LCodeGen); 365b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 366b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 367b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 368b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochclass LDeferredCode: public ZoneObject { 369b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 370b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch explicit LDeferredCode(LCodeGen* codegen) 3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : codegen_(codegen), 3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch external_exit_(NULL), 3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instruction_index_(codegen->current_instruction_) { 374b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch codegen->AddDeferredCode(this); 375b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 376b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 377b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch virtual ~LDeferredCode() { } 378b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch virtual void Generate() = 0; 3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual LInstruction* instr() = 0; 380b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SetExit(Label* exit) { external_exit_ = exit; } 382b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Label* entry() { return &entry_; } 383b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; } 3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int instruction_index() const { return instruction_index_; } 385b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 386b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch protected: 387b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LCodeGen* codegen() const { return codegen_; } 388b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch MacroAssembler* masm() const { return codegen_->masm(); } 389b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 390b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 391b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LCodeGen* codegen_; 392b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Label entry_; 393b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Label exit_; 394b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Label* external_exit_; 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int instruction_index_; 396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} } // namespace v8::internal 399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif // V8_X64_LITHIUM_CODEGEN_X64_H_ 401