1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved. 2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be 3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file. 4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_CRANKSHAFT_PPC_LITHIUM_CODEGEN_PPC_H_ 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_CRANKSHAFT_PPC_LITHIUM_CODEGEN_PPC_H_ 7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/scopes.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/lithium-codegen.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/ppc/lithium-gap-resolver-ppc.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/ppc/lithium-ppc.h" 12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/deoptimizer.h" 13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/safepoint-table.h" 14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/utils.h" 15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Forward declarations. 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass LDeferredCode; 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass SafepointGenerator; 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass LCodeGen : public LCodeGenBase { 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : LCodeGenBase(chunk, assembler, info), 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier jump_table_(4, info->zone()), 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier scope_(info->scope()), 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier deferred_(8, info->zone()), 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier frame_is_built_(false), 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier safepoints_(info->zone()), 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier resolver_(this), 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier expected_safepoint_kind_(Safepoint::kSimple) { 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PopulateDeoptimizationLiteralsWithInlinedFunctions(); 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int LookupDestination(int block_id) const { 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return chunk()->LookupDestination(block_id); 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool IsNextEmittedBlock(int block_id) const { 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return LookupDestination(block_id) == GetNextEmittedBlock(); 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool NeedsEagerFrame() const { 47109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return HasAllocatedStackSlots() || info()->is_non_deferred_calling() || 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !info()->IsStub() || info()->requires_frame(); 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool NeedsDeferredFrame() const { 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return !NeedsEagerFrame() && info()->is_deferred_calling(); 52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LinkRegisterStatus GetLinkRegisterState() const { 55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return frame_is_built_ ? kLRHasBeenSaved : kLRHasNotBeenSaved; 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Support for converting LOperands to assembler types. 59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // LOperand must be a register. 60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register ToRegister(LOperand* op) const; 61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // LOperand is loaded into scratch, unless already a register. 63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register EmitLoadRegister(LOperand* op, Register scratch); 64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 65958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // LConstantOperand must be an Integer32 or Smi 66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EmitLoadIntegerConstant(LConstantOperand* const_op, Register dst); 67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // LOperand must be a double register. 69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DoubleRegister ToDoubleRegister(LOperand* op) const; 70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t ToRepresentation(LConstantOperand* op, 72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const Representation& r) const; 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t ToInteger32(LConstantOperand* op) const; 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Smi* ToSmi(LConstantOperand* op) const; 75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double ToDouble(LConstantOperand* op) const; 76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Operand ToOperand(LOperand* op); 77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MemOperand ToMemOperand(LOperand* op) const; 78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Returns a MemOperand pointing to the high word of a DoubleStackSlot. 79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MemOperand ToHighMemOperand(LOperand* op) const; 80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool IsInteger32(LConstantOperand* op) const; 82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool IsSmi(LConstantOperand* op) const; 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> ToHandle(LConstantOperand* op) const; 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Try to generate code for the entire chunk, but it may fail if the 86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // chunk contains constructs we cannot handle. Returns true if the 87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // code generation attempt succeeded. 88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool GenerateCode(); 89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Finish the code by setting stack height, safepoint, and bailout 91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // information on it. 92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void FinishCode(Handle<Code> code); 93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Deferred code support. 95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoDeferredNumberTagD(LNumberTagD* instr); 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 }; 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoDeferredNumberTagIU(LInstruction* instr, LOperand* value, 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LOperand* temp1, LOperand* temp2, 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier IntegerSignedness signedness); 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoDeferredTaggedToI(LTaggedToI* instr); 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr); 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoDeferredStackCheck(LStackCheck* instr); 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DoDeferredMaybeGrowElements(LMaybeGrowElements* instr); 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr); 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoDeferredStringCharFromCode(LStringCharFromCode* instr); 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoDeferredAllocate(LAllocate* instr); 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoDeferredInstanceMigration(LCheckMaps* instr, Register object); 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, Register result, 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register object, Register index); 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Parallel move support. 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoParallelMove(LParallelMove* move); 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoGap(LGap* instr); 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MemOperand PrepareKeyedOperand(Register key, Register base, 118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool key_is_constant, bool key_is_tagged, 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int constant_key, int element_size_shift, 120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int base_offset); 121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Emit frame translation commands for an environment. 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void WriteTranslation(LEnvironment* environment, Translation* translation); 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Declare methods that deal with the individual node types. 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define DECLARE_DO(type) void Do##type(L##type* node); 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef DECLARE_DO 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Scope* scope() const { return scope_; } 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch0() { return kLithiumScratch; } 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DoubleRegister double_scratch0() { return kScratchDoubleReg; } 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LInstruction* GetNextInstruction(); 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EmitClassOfTest(Label* if_true, Label* if_false, 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<String> class_name, Register input, 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register temporary, Register temporary2); 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 142109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bool HasAllocatedStackSlots() const { 143109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return chunk()->HasAllocatedStackSlots(); 144109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 145109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int GetStackSlotCount() const { return chunk()->GetSpillSlotCount(); } 146109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int GetTotalFrameSlotCount() const { 147109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return chunk()->GetTotalFrameSlotCount(); 148109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void SaveCallerDoubles(); 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void RestoreCallerDoubles(); 154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Code generation passes. Returns true if code generation should 156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // continue. 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void GenerateBodyInstructionPre(LInstruction* instr) override; 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool GeneratePrologue(); 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool GenerateDeferredCode(); 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool GenerateJumpTable(); 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool GenerateSafepointTable(); 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Generates the custom OSR entrypoint and sets the osr_pc_offset. 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void GenerateOsrPrologue(); 165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier enum SafepointMode { 167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RECORD_SIMPLE_SAFEPOINT, 168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS 169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; 170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void CallCode(Handle<Code> code, RelocInfo::Mode mode, LInstruction* instr); 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void CallCodeGeneric(Handle<Code> code, RelocInfo::Mode mode, 174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LInstruction* instr, SafepointMode safepoint_mode); 175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void CallRuntime(const Runtime::Function* function, int num_arguments, 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LInstruction* instr, 178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SaveFPRegsMode save_doubles = kDontSaveFPRegs); 179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void CallRuntime(Runtime::FunctionId id, int num_arguments, 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LInstruction* instr) { 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const Runtime::Function* function = Runtime::FunctionForId(id); 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CallRuntime(function, num_arguments, instr); 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void CallRuntime(Runtime::FunctionId id, LInstruction* instr) { 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Runtime::Function* function = Runtime::FunctionForId(id); 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallRuntime(function, function->nargs, instr); 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void LoadContextFromDeferred(LOperand* context); 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void CallRuntimeFromDeferred(Runtime::FunctionId id, int argc, 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LInstruction* instr, LOperand* context); 194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void PrepareForTailCall(const ParameterCount& actual, Register scratch1, 1963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch2, Register scratch3); 1973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Generate a direct call to a known function. Expects the function 199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // to be in r4. 200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void CallKnownFunction(Handle<JSFunction> function, 201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int formal_parameter_count, int arity, 2023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bool is_tail_call, LInstruction* instr); 203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void RecordSafepointWithLazyDeopt(LInstruction* instr, 205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SafepointMode safepoint_mode); 206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void RegisterEnvironmentForDeoptimization(LEnvironment* environment, 208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Safepoint::DeoptMode mode); 209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DeoptimizeIf(Condition condition, LInstruction* instr, 210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason deopt_reason, 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Deoptimizer::BailoutType bailout_type, CRegister cr = cr7); 212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DeoptimizeIf(Condition condition, LInstruction* instr, 213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason deopt_reason, CRegister cr = cr7); 214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void AddToTranslation(LEnvironment* environment, Translation* translation, 216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LOperand* op, bool is_tagged, bool is_uint32, 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int* object_index_pointer, 218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int* dematerialized_index_pointer); 219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register ToRegister(int index) const; 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DoubleRegister ToDoubleRegister(int index) const; 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MemOperand BuildSeqStringOperand(Register string, LOperand* index, 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier String::Encoding encoding); 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EmitMathAbs(LMathAbs* instr); 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EmitInteger32MathAbs(LMathAbs* instr); 229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Support for recording safepoint information. 232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void RecordSafepoint(LPointerMap* pointers, Safepoint::Kind kind, 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int arguments, Safepoint::DeoptMode mode); 234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode); 235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void RecordSafepoint(Safepoint::DeoptMode mode); 236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void RecordSafepointWithRegisters(LPointerMap* pointers, int arguments, 237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Safepoint::DeoptMode mode); 238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static Condition TokenToCondition(Token::Value op); 240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EmitGoto(int block); 241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // EmitBranch expects to be the last instruction of a block. 243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier template <class InstrType> 244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EmitBranch(InstrType instr, Condition condition, CRegister cr = cr7); 245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier template <class InstrType> 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EmitTrueBranch(InstrType instr, Condition condition, CRegister cr = cr7); 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <class InstrType> 248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EmitFalseBranch(InstrType instr, Condition condition, 249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CRegister cr = cr7); 250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EmitNumberUntagD(LNumberUntagD* instr, Register input, 251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DoubleRegister result, NumberUntagDMode mode); 252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Emits optimized code for typeof x == "y". Modifies input register. 254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Returns the condition on which a final split to 255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // true and false label should be made, to optimize fallthrough. 256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Condition EmitTypeofIs(Label* true_label, Label* false_label, Register input, 257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<String> type_name); 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Emits optimized code for %_IsString(x). Preserves input register. 260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Returns the condition on which a final split to 261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // true and false label should be made, to optimize fallthrough. 262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Condition EmitIsString(Register input, Register temp1, Label* is_not_string, 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SmiCheck check_needed); 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Emits optimized code to deep-copy the contents of statically known 266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // object graphs (e.g. object literal boilerplate). 267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EmitDeepCopy(Handle<JSObject> object, Register result, Register source, 268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int* offset, AllocationSiteMode mode); 269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EnsureSpaceForLazyDeopt(int space_needed) override; 271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoLoadKeyedExternalArray(LLoadKeyed* instr); 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr); 273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoLoadKeyedFixedArray(LLoadKeyed* instr); 274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoStoreKeyedExternalArray(LStoreKeyed* instr); 275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr); 276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DoStoreKeyedFixedArray(LStoreKeyed* instr); 277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier template <class T> 279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EmitVectorLoadICRegisters(T* instr); 280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ZoneList<Deoptimizer::JumpTableEntry> jump_table_; 282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Scope* const scope_; 283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ZoneList<LDeferredCode*> deferred_; 284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool frame_is_built_; 285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Builder that keeps track of safepoints in the code. The table 287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // itself is emitted at the end of the generated code. 288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SafepointTableBuilder safepoints_; 289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Compiler from a set of parallel moves to a sequential list of moves. 291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LGapResolver resolver_; 292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Safepoint::Kind expected_safepoint_kind_; 294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class PushSafepointRegistersScope final BASE_EMBEDDED { 296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 297c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch explicit PushSafepointRegistersScope(LCodeGen* codegen); 298c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 299c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ~PushSafepointRegistersScope(); 300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LCodeGen* codegen_; 303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; 304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier friend class LDeferredCode; 306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier friend class LEnvironment; 307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier friend class SafepointGenerator; 308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DISALLOW_COPY_AND_ASSIGN(LCodeGen); 309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass LDeferredCode : public ZoneObject { 313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit LDeferredCode(LCodeGen* codegen) 315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : codegen_(codegen), 316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier external_exit_(NULL), 317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier instruction_index_(codegen->current_instruction_) { 318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier codegen->AddDeferredCode(this); 319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier virtual ~LDeferredCode() {} 322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier virtual void Generate() = 0; 323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier virtual LInstruction* instr() = 0; 324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void SetExit(Label* exit) { external_exit_ = exit; } 326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label* entry() { return &entry_; } 327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; } 328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int instruction_index() const { return instruction_index_; } 329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier protected: 331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LCodeGen* codegen() const { return codegen_; } 332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MacroAssembler* masm() const { return codegen_->masm(); } 333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LCodeGen* codegen_; 336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label entry_; 337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label exit_; 338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label* external_exit_; 339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int instruction_index_; 340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif // V8_CRANKSHAFT_PPC_LITHIUM_CODEGEN_PPC_H_ 345