13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifndef V8_ARM_LITHIUM_CODEGEN_ARM_H_ 6b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define V8_ARM_LITHIUM_CODEGEN_ARM_H_ 7b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm/lithium-arm.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm/lithium-gap-resolver-arm.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/deoptimizer.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/lithium-codegen.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/safepoint-table.h" 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/scopes.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/utils.h" 16b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 17b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 { 18b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal { 19b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Forward declarations. 21b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LDeferredCode; 22b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass SafepointGenerator; 23b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LCodeGen: public LCodeGenBase { 25b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 26b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : LCodeGenBase(chunk, assembler, info), 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deoptimizations_(4, info->zone()), 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jump_table_(4, info->zone()), 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deoptimization_literals_(8, info->zone()), 31b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch inlined_function_count_(0), 32e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch scope_(info->scope()), 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch translations_(info->zone()), 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deferred_(8, info->zone()), 35e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch osr_pc_offset_(-1), 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch frame_is_built_(false), 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch safepoints_(info->zone()), 388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch resolver_(this), 398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch expected_safepoint_kind_(Safepoint::kSimple) { 40b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PopulateDeoptimizationLiteralsWithInlinedFunctions(); 41b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 42b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 43e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int LookupDestination(int block_id) const { 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return chunk()->LookupDestination(block_id); 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsNextEmittedBlock(int block_id) const { 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return LookupDestination(block_id) == GetNextEmittedBlock(); 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool NeedsEagerFrame() const { 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetStackSlotCount() > 0 || 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info()->is_non_deferred_calling() || 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !info()->IsStub() || 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info()->requires_frame(); 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool NeedsDeferredFrame() const { 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return !NeedsEagerFrame() && info()->is_deferred_calling(); 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LinkRegisterStatus GetLinkRegisterState() const { 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return frame_is_built_ ? kLRHasBeenSaved : kLRHasNotBeenSaved; 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 65e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 66e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Support for converting LOperands to assembler types. 67e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // LOperand must be a register. 68e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Register ToRegister(LOperand* op) const; 69e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 70e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // LOperand is loaded into scratch, unless already a register. 71e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Register EmitLoadRegister(LOperand* op, Register scratch); 72e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 73e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // LOperand must be a double register. 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DwVfpRegister ToDoubleRegister(LOperand* op) const; 75e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 76e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // LOperand is loaded into dbl_scratch, unless already a double register. 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DwVfpRegister EmitLoadDoubleRegister(LOperand* op, 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SwVfpRegister flt_scratch, 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DwVfpRegister dbl_scratch); 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const; 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t ToInteger32(LConstantOperand* op) const; 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Smi* ToSmi(LConstantOperand* op) const; 833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double ToDouble(LConstantOperand* op) const; 84e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Operand ToOperand(LOperand* op); 85e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MemOperand ToMemOperand(LOperand* op) const; 86e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Returns a MemOperand pointing to the high word of a DoubleStackSlot. 87e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MemOperand ToHighMemOperand(LOperand* op) const; 88e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool IsInteger32(LConstantOperand* op) const; 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsSmi(LConstantOperand* op) const; 913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> ToHandle(LConstantOperand* op) const; 923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 93b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Try to generate code for the entire chunk, but it may fail if the 94b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // chunk contains constructs we cannot handle. Returns true if the 95b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // code generation attempt succeeded. 96b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool GenerateCode(); 97b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 98b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Finish the code by setting stack height, safepoint, and bailout 99b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // information on it. 100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void FinishCode(Handle<Code> code); 101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Deferred code support. 103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoDeferredNumberTagD(LNumberTagD* instr); 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 }; 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredNumberTagIU(LInstruction* instr, 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* value, 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* temp1, 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* temp2, 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IntegerSignedness signedness); 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoDeferredTaggedToI(LTaggedToI* instr); 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr); 1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void DoDeferredStackCheck(LStackCheck* instr); 1151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr); 11644f0eee88ff00398ff7f715fab053374d808c90dSteve Block void DoDeferredStringCharFromCode(LStringCharFromCode* instr); 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredAllocate(LAllocate* instr); 1182b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* map_check, Label* bool_load); 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredInstanceMigration(LCheckMaps* instr, Register object); 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register index); 1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Parallel move support. 127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void DoParallelMove(LParallelMove* move); 128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void DoGap(LGap* instr); 129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemOperand PrepareKeyedOperand(Register key, 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register base, 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool key_is_constant, 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int constant_key, 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int element_size, 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int shift_size, 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int base_offset); 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 138b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Emit frame translation commands for an environment. 139b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void WriteTranslation(LEnvironment* environment, Translation* translation); 140b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Declare methods that deal with the individual node types. 142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define DECLARE_DO(type) void Do##type(L##type* node); 143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef DECLARE_DO 145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StrictMode strict_mode() const { return info()->strict_mode(); } 148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Scope* scope() const { return scope_; } 150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1519fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block Register scratch0() { return r9; } 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LowDwVfpRegister double_scratch0() { return kScratchDoubleReg; } 1539fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LInstruction* GetNextInstruction(); 155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void EmitClassOfTest(Label* if_true, 157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label* if_false, 158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<String> class_name, 159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register input, 160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register temporary, 161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register temporary2); 162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 163257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int GetStackSlotCount() const { return chunk()->spill_slot_count(); } 164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } 166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SaveCallerDoubles(); 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RestoreCallerDoubles(); 169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Code generation passes. Returns true if code generation should 171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // continue. 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GenerateBodyInstructionPre(LInstruction* instr) OVERRIDE; 173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool GeneratePrologue(); 174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool GenerateDeferredCode(); 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool GenerateJumpTable(); 176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool GenerateSafepointTable(); 177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generates the custom OSR entrypoint and sets the osr_pc_offset. 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GenerateOsrPrologue(); 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch enum SafepointMode { 1828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RECORD_SIMPLE_SAFEPOINT, 1838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS 1848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch }; 1858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int CallCodeSize(Handle<Code> code, RelocInfo::Mode mode); 1878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallCode( 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code, 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode mode, 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LInstruction* instr, 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TargetAddressStorageMode storage_mode = CAN_INLINE_TARGET_ADDRESS); 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallCodeGeneric( 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code, 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode mode, 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LInstruction* instr, 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SafepointMode safepoint_mode, 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TargetAddressStorageMode storage_mode = CAN_INLINE_TARGET_ADDRESS); 2008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 20144f0eee88ff00398ff7f715fab053374d808c90dSteve Block void CallRuntime(const Runtime::Function* function, 202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int num_arguments, 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LInstruction* instr, 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_doubles = kDontSaveFPRegs); 2058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void CallRuntime(Runtime::FunctionId id, 207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int num_arguments, 208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LInstruction* instr) { 20944f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Runtime::Function* function = Runtime::FunctionForId(id); 210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CallRuntime(function, num_arguments, instr); 211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LoadContextFromDeferred(LOperand* context); 2148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch void CallRuntimeFromDeferred(Runtime::FunctionId id, 2158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int argc, 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LInstruction* instr, 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* context); 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum R1State { 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch R1_UNINITIALIZED, 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch R1_CONTAINS_TARGET 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 2238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Generate a direct call to a known function. Expects the function 2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // to be in r1. 226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void CallKnownFunction(Handle<JSFunction> function, 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int formal_parameter_count, 228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int arity, 229257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LInstruction* instr, 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch R1State r1_state); 231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2322b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void RecordSafepointWithLazyDeopt(LInstruction* instr, 2332b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch SafepointMode safepoint_mode); 2348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 2352b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void RegisterEnvironmentForDeoptimization(LEnvironment* environment, 2362b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch Safepoint::DeoptMode mode); 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DeoptimizeIf(Condition condition, LInstruction* instr, 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* detail, Deoptimizer::BailoutType bailout_type); 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DeoptimizeIf(Condition condition, LInstruction* instr, 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* detail = NULL); 241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddToTranslation(LEnvironment* environment, 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Translation* translation, 244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LOperand* op, 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_tagged, 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_uint32, 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int* object_index_pointer, 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int* dematerialized_index_pointer); 249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void PopulateDeoptimizationData(Handle<Code> code); 250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int DefineDeoptimizationLiteral(Handle<Object> literal); 251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void PopulateDeoptimizationLiteralsWithInlinedFunctions(); 253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register ToRegister(int index) const; 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DwVfpRegister ToDoubleRegister(int index) const; 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemOperand BuildSeqStringOperand(Register string, 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* index, 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::Encoding encoding); 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitIntegerMathAbs(LMathAbs* instr); 262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Support for recording safepoint and position information. 2641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void RecordSafepoint(LPointerMap* pointers, 2651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Safepoint::Kind kind, 2661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int arguments, 2672b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch Safepoint::DeoptMode mode); 2682b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode); 2692b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void RecordSafepoint(Safepoint::DeoptMode mode); 270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void RecordSafepointWithRegisters(LPointerMap* pointers, 271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int arguments, 2722b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch Safepoint::DeoptMode mode); 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordAndWritePosition(int position) OVERRIDE; 275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static Condition TokenToCondition(Token::Value op, bool is_unsigned); 2773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void EmitGoto(int block); 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // EmitBranch expects to be the last instruction of a block. 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class InstrType> 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitBranch(InstrType instr, Condition condition); 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class InstrType> 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitFalseBranch(InstrType instr, Condition condition); 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitNumberUntagD(LNumberUntagD* instr, Register input, 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DwVfpRegister result, NumberUntagDMode mode); 286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Emits optimized code for typeof x == "y". Modifies input register. 288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Returns the condition on which a final split to 289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // true and false label should be made, to optimize fallthrough. 2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition EmitTypeofIs(Label* true_label, 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* false_label, 2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input, 2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> type_name); 294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Emits optimized code for %_IsObject(x). Preserves input register. 296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Returns the condition on which a final split to 297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // true and false label should be made, to optimize fallthrough. 298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Condition EmitIsObject(Register input, 299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register temp1, 300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label* is_not_object, 301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label* is_object); 302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Emits optimized code for %_IsString(x). Preserves input register. 3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Returns the condition on which a final split to 3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // true and false label should be made, to optimize fallthrough. 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition EmitIsString(Register input, 3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp1, 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* is_not_string, 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck check_needed); 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Emits optimized code for %_IsConstructCall(). 3121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Caller should branch on equal condition. 3131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void EmitIsConstructCall(Register temp1, Register temp2); 3141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Emits optimized code to deep-copy the contents of statically known 3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // object graphs (e.g. object literal boilerplate). 3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void EmitDeepCopy(Handle<JSObject> object, 3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result, 3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register source, 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int* offset, 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteMode mode); 32244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE; 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoLoadKeyedExternalArray(LLoadKeyed* instr); 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr); 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoLoadKeyedFixedArray(LLoadKeyed* instr); 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoStoreKeyedExternalArray(LStoreKeyed* instr); 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr); 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoStoreKeyedFixedArray(LStoreKeyed* instr); 3302b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template <class T> 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitVectorLoadICRegisters(T* instr); 333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ZoneList<LEnvironment*> deoptimizations_; 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Deoptimizer::JumpTableEntry> jump_table_; 336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ZoneList<Handle<Object> > deoptimization_literals_; 337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int inlined_function_count_; 338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Scope* const scope_; 339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TranslationBuffer translations_; 340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ZoneList<LDeferredCode*> deferred_; 341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int osr_pc_offset_; 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool frame_is_built_; 343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Builder that keeps track of safepoints in the code. The table 345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // itself is emitted at the end of the generated code. 346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SafepointTableBuilder safepoints_; 347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 348b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Compiler from a set of parallel moves to a sequential list of moves. 349b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LGapResolver resolver_; 350b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 3518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Safepoint::Kind expected_safepoint_kind_; 3528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class PushSafepointRegistersScope FINAL BASE_EMBEDDED { 3548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch public: 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit PushSafepointRegistersScope(LCodeGen* codegen) 3568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : codegen_(codegen) { 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(codegen_->info()->is_calling()); 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple); 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters; 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch codegen_->masm_->PushSafepointRegisters(); 3618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 3628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 3638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ~PushSafepointRegistersScope() { 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters); 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch codegen_->masm_->PopSafepointRegisters(); 3668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch codegen_->expected_safepoint_kind_ = Safepoint::kSimple; 3678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 3688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 3698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch private: 3708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch LCodeGen* codegen_; 3718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch }; 3728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class LDeferredCode; 374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class LEnvironment; 375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class SafepointGenerator; 376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DISALLOW_COPY_AND_ASSIGN(LCodeGen); 377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LDeferredCode : public ZoneObject { 381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch explicit LDeferredCode(LCodeGen* codegen) 3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : codegen_(codegen), 3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch external_exit_(NULL), 3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instruction_index_(codegen->current_instruction_) { 386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen->AddDeferredCode(this); 387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~LDeferredCode() {} 390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Generate() = 0; 3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual LInstruction* instr() = 0; 392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SetExit(Label* exit) { external_exit_ = exit; } 394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label* entry() { return &entry_; } 395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; } 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int instruction_index() const { return instruction_index_; } 397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected: 399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LCodeGen* codegen() const { return codegen_; } 400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch MacroAssembler* masm() const { return codegen_->masm(); } 401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LCodeGen* codegen_; 404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label entry_; 405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label exit_; 406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label* external_exit_; 4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int instruction_index_; 408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} } // namespace v8::internal 411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif // V8_ARM_LITHIUM_CODEGEN_ARM_H_ 413