13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Redistribution and use in source and binary forms, with or without 3b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// modification, are permitted provided that the following conditions are 4b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// met: 5b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// 6b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Redistributions of source code must retain the above copyright 7b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// notice, this list of conditions and the following disclaimer. 8b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Redistributions in binary form must reproduce the above 9b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// copyright notice, this list of conditions and the following 10b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// disclaimer in the documentation and/or other materials provided 11b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// with the distribution. 12b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Neither the name of Google Inc. nor the names of its 13b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// contributors may be used to endorse or promote products derived 14b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// from this software without specific prior written permission. 15b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// 16b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 28b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifndef V8_IA32_LITHIUM_CODEGEN_IA32_H_ 29b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define V8_IA32_LITHIUM_CODEGEN_IA32_H_ 30b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 31b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "ia32/lithium-ia32.h" 32b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 33b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "checks.h" 34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "deoptimizer.h" 35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "safepoint-table.h" 36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "scopes.h" 37b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#include "ia32/lithium-gap-resolver-ia32.h" 38b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 39b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 { 40b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal { 41b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 42b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Forward declarations. 43b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LDeferredCode; 44b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochclass LGapNode; 45b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass SafepointGenerator; 46b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 47b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LCodeGen BASE_EMBEDDED { 48b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 49b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) 50b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : chunk_(chunk), 51b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch masm_(assembler), 52b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch info_(info), 53b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch current_block_(-1), 54b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch current_instruction_(-1), 55b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch instructions_(chunk->instructions()), 56b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch deoptimizations_(4), 57b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch deoptimization_literals_(8), 58b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch inlined_function_count_(0), 59e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch scope_(info->scope()), 60b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch status_(UNUSED), 61b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch deferred_(8), 62b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch osr_pc_offset_(-1), 632b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch last_lazy_deopt_pc_(0), 648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch resolver_(this), 658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch expected_safepoint_kind_(Safepoint::kSimple) { 66b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PopulateDeoptimizationLiteralsWithInlinedFunctions(); 67b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 68b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 69b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Simple accessors. 70b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 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(); } 75b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 76b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Support for converting LOperands to assembler types. 77b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Operand ToOperand(LOperand* op) const; 78b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Register ToRegister(LOperand* op) const; 79b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch XMMRegister ToDoubleRegister(LOperand* op) const; 803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool IsInteger32(LConstantOperand* op) const; 823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Immediate ToInteger32Immediate(LOperand* op) const { 833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Immediate(ToInteger32(LConstantOperand::cast(op))); 843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> ToHandle(LConstantOperand* op) const; 87b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 88b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // The operand denoting the second word (the one with a higher address) of 89b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // a double stack slot. 90b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Operand HighOperand(LOperand* op); 91b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 92b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Try to generate code for the entire chunk, but it may fail if the 93b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // chunk contains constructs we cannot handle. Returns true if the 94b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // code generation attempt succeeded. 95b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool GenerateCode(); 96b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 97b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Finish the code by setting stack height, safepoint, and bailout 98b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // information on it. 99b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void FinishCode(Handle<Code> code); 100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Deferred code support. 102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoDeferredNumberTagD(LNumberTagD* instr); 103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoDeferredNumberTagI(LNumberTagI* instr); 104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoDeferredTaggedToI(LTaggedToI* instr); 105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr); 1063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void DoDeferredStackCheck(LStackCheck* instr); 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void DoDeferredRandom(LRandom* instr); 1081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr); 10944f0eee88ff00398ff7f715fab053374d808c90dSteve Block void DoDeferredStringCharFromCode(LStringCharFromCode* instr); 1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void DoDeferredAllocateObject(LAllocateObject* instr); 1112b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 1122b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch Label* map_check); 113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void DoCheckMapCommon(Register reg, Handle<Map> map, 1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompareMapMode mode, LEnvironment* env); 1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Parallel move support. 118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoParallelMove(LParallelMove* move); 119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void DoGap(LGap* instr); 120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 121b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Emit frame translation commands for an environment. 122b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void WriteTranslation(LEnvironment* environment, Translation* translation); 123b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 124e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void EnsureRelocSpaceForDeoptimization(); 125e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Declare methods that deal with the individual node types. 127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define DECLARE_DO(type) void Do##type(L##type* node); 128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef DECLARE_DO 130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch enum Status { 133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNUSED, 134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GENERATING, 135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DONE, 136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ABORTED 137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_unused() const { return status_ == UNUSED; } 140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_generating() const { return status_ == GENERATING; } 141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_done() const { return status_ == DONE; } 142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_aborted() const { return status_ == ABORTED; } 143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StrictModeFlag strict_mode_flag() const { 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return info()->is_classic_mode() ? kNonStrictMode : kStrictMode; 146592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 147e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LChunk* chunk() const { return chunk_; } 149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Scope* scope() const { return scope_; } 150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HGraph* graph() const { return chunk_->graph(); } 151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int GetNextEmittedBlock(int block); 153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void EmitClassOfTest(Label* if_true, 155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label* if_false, 156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<String> class_name, 157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register input, 158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register temporary, 159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register temporary2); 160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 161257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int GetStackSlotCount() const { return chunk()->spill_slot_count(); } 162257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int GetParameterCount() const { return scope()->num_parameters(); } 163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Abort(const char* format, ...); 165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Comment(const char* format, ...); 166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code); } 168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Code generation passes. Returns true if code generation should 170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // continue. 171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool GeneratePrologue(); 172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool GenerateBody(); 173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool GenerateDeferredCode(); 174e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Pad the reloc info to ensure that we have enough space to patch during 175e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // deoptimization. 176e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool GenerateRelocPadding(); 177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool GenerateSafepointTable(); 178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch enum SafepointMode { 1808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RECORD_SIMPLE_SAFEPOINT, 1818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS 1828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch }; 1838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 1848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch void CallCode(Handle<Code> code, 1858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RelocInfo::Mode mode, 1863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LInstruction* instr); 1878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 1888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch void CallCodeGeneric(Handle<Code> code, 1898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RelocInfo::Mode mode, 1908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch LInstruction* instr, 1918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch SafepointMode safepoint_mode); 1928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 1938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch void CallRuntime(const Runtime::Function* fun, 1948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int argc, 1953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LInstruction* instr); 1968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 1978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch void CallRuntime(Runtime::FunctionId id, 1988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int argc, 1993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LInstruction* instr) { 20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Runtime::Function* function = Runtime::FunctionForId(id); 2013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CallRuntime(function, argc, instr); 202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch void CallRuntimeFromDeferred(Runtime::FunctionId id, 2058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int argc, 2063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LInstruction* instr, 2073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LOperand* context); 2088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Generate a direct call to a known function. Expects the function 210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // to be in edi. 211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void CallKnownFunction(Handle<JSFunction> function, 212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int arity, 213257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LInstruction* instr, 214257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CallKind call_kind); 215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2162b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void RecordSafepointWithLazyDeopt(LInstruction* instr, 2172b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch SafepointMode safepoint_mode); 2188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 2192b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void RegisterEnvironmentForDeoptimization(LEnvironment* environment, 2202b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch Safepoint::DeoptMode mode); 221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DeoptimizeIf(Condition cc, LEnvironment* environment); 222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void AddToTranslation(Translation* translation, 224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LOperand* op, 225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_tagged); 226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void PopulateDeoptimizationData(Handle<Code> code); 227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int DefineDeoptimizationLiteral(Handle<Object> literal); 228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void PopulateDeoptimizationLiteralsWithInlinedFunctions(); 230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register ToRegister(int index) const; 232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch XMMRegister ToDoubleRegister(int index) const; 233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int ToInteger32(LConstantOperand* op) const; 2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double ToDouble(LConstantOperand* op) const; 23669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Operand BuildFastArrayOperand(LOperand* elements_pointer, 2373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LOperand* key, 238589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ElementsKind elements_kind, 2393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t offset); 240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Specific math operations - used from DoUnaryMathOperation. 2421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void EmitIntegerMathAbs(LUnaryMathOperation* instr); 243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoMathAbs(LUnaryMathOperation* instr); 244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoMathFloor(LUnaryMathOperation* instr); 245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoMathRound(LUnaryMathOperation* instr); 246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoMathSqrt(LUnaryMathOperation* instr); 247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoMathLog(LUnaryMathOperation* instr); 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void DoMathTan(LUnaryMathOperation* instr); 249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoMathCos(LUnaryMathOperation* instr); 250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoMathSin(LUnaryMathOperation* instr); 251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Support for recording safepoint and position information. 2531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void RecordSafepoint(LPointerMap* pointers, 2541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Safepoint::Kind kind, 2551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int arguments, 2562b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch Safepoint::DeoptMode mode); 2572b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode); 2582b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void RecordSafepoint(Safepoint::DeoptMode mode); 259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void RecordSafepointWithRegisters(LPointerMap* pointers, 260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int arguments, 2612b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch Safepoint::DeoptMode mode); 262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void RecordPosition(int position); 263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static Condition TokenToCondition(Token::Value op, bool is_unsigned); 2653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void EmitGoto(int block); 266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void EmitBranch(int left_block, int right_block, Condition cc); 2677d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch void EmitNumberUntagD(Register input, 2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp, 2697d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch XMMRegister result, 2707d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch bool deoptimize_on_undefined, 2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool deoptimize_on_minus_zero, 2727d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch LEnvironment* env); 273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Emits optimized code for typeof x == "y". Modifies input register. 275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Returns the condition on which a final split to 276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // true and false label should be made, to optimize fallthrough. 2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition EmitTypeofIs(Label* true_label, 2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* false_label, 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input, 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> type_name); 281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Emits optimized code for %_IsObject(x). Preserves input register. 283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Returns the condition on which a final split to 284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // true and false label should be made, to optimize fallthrough. 285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Condition EmitIsObject(Register input, 286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register temp1, 287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label* is_not_object, 288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label* is_object); 289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Emits optimized code for %_IsString(x). Preserves input register. 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Returns the condition on which a final split to 2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // true and false label should be made, to optimize fallthrough. 2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition EmitIsString(Register input, 2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp1, 2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* is_not_string); 2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Emits optimized code for %_IsConstructCall(). 2981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Caller should branch on equal condition. 2991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void EmitIsConstructCall(Register temp); 3001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 301257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void EmitLoadFieldOrConstantFunction(Register result, 302257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register object, 303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Map> type, 304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<String> name); 3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Emits optimized code to deep-copy the contents of statically known 3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // object graphs (e.g. object literal boilerplate). 3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void EmitDeepCopy(Handle<JSObject> object, 3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result, 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register source, 3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int* offset); 3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3132b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void EnsureSpaceForLazyDeopt(); 3141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Emits code for pushing either a tagged constant, a (non-double) 3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // register, or a stack slot operand. 3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void EmitPushTaggedOperand(LOperand* operand); 3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LChunk* const chunk_; 320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch MacroAssembler* const masm_; 321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompilationInfo* const info_; 322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int current_block_; 324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int current_instruction_; 325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const ZoneList<LInstruction*>* instructions_; 326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ZoneList<LEnvironment*> deoptimizations_; 327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ZoneList<Handle<Object> > deoptimization_literals_; 328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int inlined_function_count_; 329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Scope* const scope_; 330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Status status_; 331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TranslationBuffer translations_; 332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ZoneList<LDeferredCode*> deferred_; 333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int osr_pc_offset_; 3342b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch int last_lazy_deopt_pc_; 335e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Builder that keeps track of safepoints in the code. The table 337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // itself is emitted at the end of the generated code. 338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SafepointTableBuilder safepoints_; 339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 340b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Compiler from a set of parallel moves to a sequential list of moves. 341b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LGapResolver resolver_; 342b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 3438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Safepoint::Kind expected_safepoint_kind_; 3448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 3458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch class PushSafepointRegistersScope BASE_EMBEDDED { 3468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch public: 3478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit PushSafepointRegistersScope(LCodeGen* codegen) 3488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : codegen_(codegen) { 3498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple); 3508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch codegen_->masm_->PushSafepointRegisters(); 3518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters; 3528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 3538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 3548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ~PushSafepointRegistersScope() { 3558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters); 3568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch codegen_->masm_->PopSafepointRegisters(); 3578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch codegen_->expected_safepoint_kind_ = Safepoint::kSimple; 3588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 3598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 3608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch private: 3618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch LCodeGen* codegen_; 3628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch }; 3638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class LDeferredCode; 365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class LEnvironment; 366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class SafepointGenerator; 367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DISALLOW_COPY_AND_ASSIGN(LCodeGen); 368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LDeferredCode: public ZoneObject { 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch explicit LDeferredCode(LCodeGen* codegen) 3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : codegen_(codegen), 3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch external_exit_(NULL), 3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instruction_index_(codegen->current_instruction_) { 377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen->AddDeferredCode(this); 378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual ~LDeferredCode() { } 381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Generate() = 0; 3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual LInstruction* instr() = 0; 383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SetExit(Label* exit) { external_exit_ = exit; } 385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label* entry() { return &entry_; } 386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; } 3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int instruction_index() const { return instruction_index_; } 388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected: 390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LCodeGen* codegen() const { return codegen_; } 391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch MacroAssembler* masm() const { return codegen_->masm(); } 392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LCodeGen* codegen_; 395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label entry_; 396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label exit_; 397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label* external_exit_; 3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int instruction_index_; 399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} } // namespace v8::internal 402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif // V8_IA32_LITHIUM_CODEGEN_IA32_H_ 404