1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Redistribution and use in source and binary forms, with or without 344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// modification, are permitted provided that the following conditions are 444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// met: 544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// 644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// * Redistributions of source code must retain the above copyright 744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// notice, this list of conditions and the following disclaimer. 844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// * Redistributions in binary form must reproduce the above 944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// copyright notice, this list of conditions and the following 1044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// disclaimer in the documentation and/or other materials provided 1144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// with the distribution. 1244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// * Neither the name of Google Inc. nor the names of its 1344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// contributors may be used to endorse or promote products derived 1444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// from this software without specific prior written permission. 1544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// 1644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifndef V8_MIPS_CODE_STUBS_ARM_H_ 2944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define V8_MIPS_CODE_STUBS_ARM_H_ 3044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "ic-inl.h" 3244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3444f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace v8 { 3544f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace internal { 3644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Compute a transcendental math function natively, or call the 3944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// TranscendentalCache runtime function. 4044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass TranscendentalCacheStub: public CodeStub { 4144f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 42257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch enum ArgumentType { 43257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch TAGGED = 0 << TranscendentalCache::kTranscendentalTypeBits, 44257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits 45257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch }; 46257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 47257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch TranscendentalCacheStub(TranscendentalCache::Type type, 48257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ArgumentType argument_type) 49257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch : type_(type), argument_type_(argument_type) { } 5044f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Generate(MacroAssembler* masm); 5144f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block TranscendentalCache::Type type_; 53257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ArgumentType argument_type_; 54257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateCallCFunction(MacroAssembler* masm, Register scratch); 55257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Major MajorKey() { return TranscendentalCache; } 57257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int MinorKey() { return type_ | argument_type_; } 5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Runtime::FunctionId RuntimeFunction(); 5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass StoreBufferOverflowStub: public CodeStub { 633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp) 653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : save_doubles_(save_fp) { } 663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Generate(MacroAssembler* masm); 683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool IsPregenerated(); 703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateFixedRegStubsAheadOfTime(); 713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool SometimesSetsUpAFrame() { return false; } 723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode save_doubles_; 753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Major MajorKey() { return StoreBufferOverflow; } 773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; } 783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 81257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass UnaryOpStub: public CodeStub { 8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch UnaryOpStub(Token::Value op, 843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch UnaryOverwriteMode mode, 853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED) 8644f0eee88ff00398ff7f715fab053374d808c90dSteve Block : op_(op), 8744f0eee88ff00398ff7f715fab053374d808c90dSteve Block mode_(mode), 883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch operand_type_(operand_type) { 89257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 9044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9144f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 9244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Token::Value op_; 93257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UnaryOverwriteMode mode_; 9444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 95257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Operand type information determined at runtime. 96257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UnaryOpIC::TypeInfo operand_type_; 9744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual void PrintName(StringStream* stream); 9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 100257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {}; 101257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class OpBits: public BitField<Token::Value, 1, 7> {}; 102257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class OperandTypeInfoBits: public BitField<UnaryOpIC::TypeInfo, 8, 3> {}; 10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 104257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Major MajorKey() { return UnaryOp; } 105257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int MinorKey() { 106257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return ModeBits::encode(mode_) 107257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch | OpBits::encode(op_) 108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch | OperandTypeInfoBits::encode(operand_type_); 10944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 11044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Note: A lot of the helper functions below will vanish when we use virtual 112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // function instead of switch more often. 113257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void Generate(MacroAssembler* masm); 11444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateTypeTransition(MacroAssembler* masm); 11644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 117257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateSmiStub(MacroAssembler* masm); 118257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateSmiStubSub(MacroAssembler* masm); 119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateSmiStubBitNot(MacroAssembler* masm); 120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateSmiCodeSub(MacroAssembler* masm, Label* non_smi, Label* slow); 121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateSmiCodeBitNot(MacroAssembler* masm, Label* slow); 12244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 123257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateHeapNumberStub(MacroAssembler* masm); 124257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateHeapNumberStubSub(MacroAssembler* masm); 125257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateHeapNumberStubBitNot(MacroAssembler* masm); 126257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateHeapNumberCodeSub(MacroAssembler* masm, Label* slow); 127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateHeapNumberCodeBitNot(MacroAssembler* masm, Label* slow); 12844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateGenericStub(MacroAssembler* masm); 130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateGenericStubSub(MacroAssembler* masm); 131257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateGenericStubBitNot(MacroAssembler* masm); 132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateGenericCodeFallback(MacroAssembler* masm); 13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 134257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual int GetCodeKind() { return Code::UNARY_OP_IC; } 13544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 13644f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual InlineCacheState GetICState() { 137257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return UnaryOpIC::ToState(operand_type_); 13844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 13944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void FinishCode(Handle<Code> code) { 141257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch code->set_unary_op_type(operand_type_); 14244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 14344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 14444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 145257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 146257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass BinaryOpStub: public CodeStub { 14744f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 148257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpStub(Token::Value op, OverwriteMode mode) 14944f0eee88ff00398ff7f715fab053374d808c90dSteve Block : op_(op), 15044f0eee88ff00398ff7f715fab053374d808c90dSteve Block mode_(mode), 151257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch operands_type_(BinaryOpIC::UNINITIALIZED), 1523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch result_type_(BinaryOpIC::UNINITIALIZED) { 153257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch use_fpu_ = CpuFeatures::IsSupported(FPU); 154257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); 15544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 15644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 157257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpStub( 15844f0eee88ff00398ff7f715fab053374d808c90dSteve Block int key, 159257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpIC::TypeInfo operands_type, 160257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED) 16144f0eee88ff00398ff7f715fab053374d808c90dSteve Block : op_(OpBits::decode(key)), 16244f0eee88ff00398ff7f715fab053374d808c90dSteve Block mode_(ModeBits::decode(key)), 16344f0eee88ff00398ff7f715fab053374d808c90dSteve Block use_fpu_(FPUBits::decode(key)), 16444f0eee88ff00398ff7f715fab053374d808c90dSteve Block operands_type_(operands_type), 1653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch result_type_(result_type) { } 16644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 16744f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 16844f0eee88ff00398ff7f715fab053374d808c90dSteve Block enum SmiCodeGenerateHeapNumberResults { 16944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ALLOW_HEAPNUMBER_RESULTS, 17044f0eee88ff00398ff7f715fab053374d808c90dSteve Block NO_HEAPNUMBER_RESULTS 17144f0eee88ff00398ff7f715fab053374d808c90dSteve Block }; 17244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 17344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Token::Value op_; 17444f0eee88ff00398ff7f715fab053374d808c90dSteve Block OverwriteMode mode_; 17544f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool use_fpu_; 17644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 17744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Operand type information determined at runtime. 178257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpIC::TypeInfo operands_type_; 179257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpIC::TypeInfo result_type_; 18044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual void PrintName(StringStream* stream); 18244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 18344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Minor key encoding in 16 bits RRRTTTVOOOOOOOMM. 18444f0eee88ff00398ff7f715fab053374d808c90dSteve Block class ModeBits: public BitField<OverwriteMode, 0, 2> {}; 18544f0eee88ff00398ff7f715fab053374d808c90dSteve Block class OpBits: public BitField<Token::Value, 2, 7> {}; 18644f0eee88ff00398ff7f715fab053374d808c90dSteve Block class FPUBits: public BitField<bool, 9, 1> {}; 187257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class OperandTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {}; 188257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class ResultTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {}; 18944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 190257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Major MajorKey() { return BinaryOp; } 19144f0eee88ff00398ff7f715fab053374d808c90dSteve Block int MinorKey() { 19244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return OpBits::encode(op_) 19344f0eee88ff00398ff7f715fab053374d808c90dSteve Block | ModeBits::encode(mode_) 19444f0eee88ff00398ff7f715fab053374d808c90dSteve Block | FPUBits::encode(use_fpu_) 19544f0eee88ff00398ff7f715fab053374d808c90dSteve Block | OperandTypeInfoBits::encode(operands_type_) 19644f0eee88ff00398ff7f715fab053374d808c90dSteve Block | ResultTypeInfoBits::encode(result_type_); 19744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 19844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 19944f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Generate(MacroAssembler* masm); 20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateGeneric(MacroAssembler* masm); 20144f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateSmiSmiOperation(MacroAssembler* masm); 20244f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateFPOperation(MacroAssembler* masm, 20344f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool smi_operands, 20444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Label* not_numbers, 20544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Label* gc_required); 20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateSmiCode(MacroAssembler* masm, 207257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* use_runtime, 20844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Label* gc_required, 20944f0eee88ff00398ff7f715fab053374d808c90dSteve Block SmiCodeGenerateHeapNumberResults heapnumber_results); 21044f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateLoadArguments(MacroAssembler* masm); 21144f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateReturn(MacroAssembler* masm); 21244f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateUninitializedStub(MacroAssembler* masm); 21344f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateSmiStub(MacroAssembler* masm); 21444f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateInt32Stub(MacroAssembler* masm); 21544f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateHeapNumberStub(MacroAssembler* masm); 216257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateOddballStub(MacroAssembler* masm); 21744f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateStringStub(MacroAssembler* masm); 218257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateBothStringStub(MacroAssembler* masm); 21944f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateGenericStub(MacroAssembler* masm); 22044f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateAddStrings(MacroAssembler* masm); 22144f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateCallRuntime(MacroAssembler* masm); 22244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 22344f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateHeapResultAllocation(MacroAssembler* masm, 22444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register result, 22544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register heap_number_map, 22644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch1, 22744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch2, 22844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Label* gc_required); 22944f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateRegisterArgsPush(MacroAssembler* masm); 23044f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateTypeTransition(MacroAssembler* masm); 23144f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm); 23244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 233257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual int GetCodeKind() { return Code::BINARY_OP_IC; } 23444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 23544f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual InlineCacheState GetICState() { 236257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return BinaryOpIC::ToState(operands_type_); 23744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 23844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void FinishCode(Handle<Code> code) { 240257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch code->set_binary_op_type(operands_type_); 241257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch code->set_binary_op_result_type(result_type_); 24244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 24344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 24444f0eee88ff00398ff7f715fab053374d808c90dSteve Block friend class CodeGenerator; 24544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 24644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 24744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass StringHelper : public AllStatic { 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Generate code for copying characters using a simple loop. This should only 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // be used in places where the number of characters is small and the 2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // additional setup and checking in GenerateCopyCharactersLong adds too much 2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // overhead. Copying of overlapping regions is not supported. 2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Dest register ends at the position after the last character written. 2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateCopyCharacters(MacroAssembler* masm, 2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register dest, 2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register src, 2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register count, 2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch, 2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool ascii); 2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Generate code for copying a large number of characters. This function 2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // is allowed to spend extra time setting up conditions to make copying 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // faster. Copying of overlapping regions is not supported. 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Dest register ends at the position after the last character written. 2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateCopyCharactersLong(MacroAssembler* masm, 2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register dest, 2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register src, 2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register count, 2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch1, 2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch2, 2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch3, 2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch4, 2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch5, 2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int flags); 2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Probe the symbol table for a two character string. If the string is 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // not found by probing a jump to the label not_found is performed. This jump 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // does not guarantee that the string is not in the symbol table. If the 2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // string is found the code falls through with the string in register r0. 2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Contents of both c1 and c2 registers are modified. At the exit c1 is 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // guaranteed to contain halfword with low and high bytes equal to 2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // initial contents of c1 and c2 respectively. 2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, 2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register c1, 2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register c2, 2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch1, 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch2, 2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch3, 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch4, 2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch5, 2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* not_found); 2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Generate string hash. 2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateHashInit(MacroAssembler* masm, 2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register hash, 2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register character); 2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateHashAddCharacter(MacroAssembler* masm, 3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register hash, 3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register character); 3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateHashGetHash(MacroAssembler* masm, 3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register hash); 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper); 3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Flag that indicates how to generate code for the stub StringAddStub. 31344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockenum StringAddFlags { 31444f0eee88ff00398ff7f715fab053374d808c90dSteve Block NO_STRING_ADD_FLAGS = 0, 315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Omit left string check in stub (left is definitely a string). 316257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch NO_STRING_CHECK_LEFT_IN_STUB = 1 << 0, 317257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Omit right string check in stub (right is definitely a string). 318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch NO_STRING_CHECK_RIGHT_IN_STUB = 1 << 1, 319257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Omit both string checks in stub. 320257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch NO_STRING_CHECK_IN_STUB = 321257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch NO_STRING_CHECK_LEFT_IN_STUB | NO_STRING_CHECK_RIGHT_IN_STUB 32244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 32344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 32444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 32544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass StringAddStub: public CodeStub { 32644f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 327257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch explicit StringAddStub(StringAddFlags flags) : flags_(flags) {} 32844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 32944f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 33044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Major MajorKey() { return StringAdd; } 331257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int MinorKey() { return flags_; } 33244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 33344f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Generate(MacroAssembler* masm); 33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 335257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateConvertArgument(MacroAssembler* masm, 336257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int stack_offset, 337257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register arg, 338257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch1, 339257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch2, 340257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch3, 341257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch4, 342257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* slow); 343257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 344257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const StringAddFlags flags_; 34544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 34644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 34744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 34844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass SubStringStub: public CodeStub { 34944f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 35044f0eee88ff00398ff7f715fab053374d808c90dSteve Block SubStringStub() {} 35144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 35244f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 35344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Major MajorKey() { return SubString; } 35444f0eee88ff00398ff7f715fab053374d808c90dSteve Block int MinorKey() { return 0; } 35544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 35644f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Generate(MacroAssembler* masm); 35744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 35844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 35944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 36044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass StringCompareStub: public CodeStub { 36144f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 36244f0eee88ff00398ff7f715fab053374d808c90dSteve Block StringCompareStub() { } 36344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 36444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Compare two flat ASCII strings and returns result in v0. 36544f0eee88ff00398ff7f715fab053374d808c90dSteve Block static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm, 36644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register left, 36744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register right, 36844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch1, 36944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch2, 37044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch3, 37144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch4); 37244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Compares two flat ASCII strings for equality and returns result 374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // in v0. 375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateFlatAsciiStringEquals(MacroAssembler* masm, 376257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register left, 377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register right, 378257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch1, 379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch2, 380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch3); 38144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 382257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual Major MajorKey() { return StringCompare; } 384257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual int MinorKey() { return 0; } 385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual void Generate(MacroAssembler* masm); 386257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 387257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateAsciiCharsCompareLoop(MacroAssembler* masm, 388257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register left, 389257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register right, 390257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register length, 391257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch1, 392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch2, 393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch3, 394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* chars_not_equal); 39544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 39644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 39744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 39844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// This stub can convert a signed int32 to a heap number (double). It does 39944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// not work for int32s that are in Smi range! No GC occurs during this stub 40044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// so you don't have to set up the frame. 40144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass WriteInt32ToHeapNumberStub : public CodeStub { 40244f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 40344f0eee88ff00398ff7f715fab053374d808c90dSteve Block WriteInt32ToHeapNumberStub(Register the_int, 40444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register the_heap_number, 40544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch, 40644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch2) 40744f0eee88ff00398ff7f715fab053374d808c90dSteve Block : the_int_(the_int), 40844f0eee88ff00398ff7f715fab053374d808c90dSteve Block the_heap_number_(the_heap_number), 40944f0eee88ff00398ff7f715fab053374d808c90dSteve Block scratch_(scratch), 4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch sign_(scratch2) { 4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IntRegisterBits::is_valid(the_int_.code())); 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(HeapNumberRegisterBits::is_valid(the_heap_number_.code())); 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ScratchRegisterBits::is_valid(scratch_.code())); 4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(SignRegisterBits::is_valid(sign_.code())); 4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool IsPregenerated(); 4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateFixedRegStubsAheadOfTime(); 41944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 42044f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 42144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register the_int_; 42244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register the_heap_number_; 42344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch_; 42444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register sign_; 42544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 42644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Minor key encoding in 16 bits. 42744f0eee88ff00398ff7f715fab053374d808c90dSteve Block class IntRegisterBits: public BitField<int, 0, 4> {}; 42844f0eee88ff00398ff7f715fab053374d808c90dSteve Block class HeapNumberRegisterBits: public BitField<int, 4, 4> {}; 42944f0eee88ff00398ff7f715fab053374d808c90dSteve Block class ScratchRegisterBits: public BitField<int, 8, 4> {}; 4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class SignRegisterBits: public BitField<int, 12, 4> {}; 43144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 43244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Major MajorKey() { return WriteInt32ToHeapNumber; } 43344f0eee88ff00398ff7f715fab053374d808c90dSteve Block int MinorKey() { 43444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Encode the parameters in a unique 16 bit value. 43544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return IntRegisterBits::encode(the_int_.code()) 43644f0eee88ff00398ff7f715fab053374d808c90dSteve Block | HeapNumberRegisterBits::encode(the_heap_number_.code()) 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch | ScratchRegisterBits::encode(scratch_.code()) 4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch | SignRegisterBits::encode(sign_.code()); 43944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 44044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 44144f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Generate(MacroAssembler* masm); 44244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 44344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 44444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 44544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass NumberToStringStub: public CodeStub { 44644f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 44744f0eee88ff00398ff7f715fab053374d808c90dSteve Block NumberToStringStub() { } 44844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 44944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Generate code to do a lookup in the number string cache. If the number in 45044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // the register object is found in the cache the generated code falls through 45144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // with the result in the result register. The object and the result register 45244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // can be the same. If the number is not found in the cache the code jumps to 45344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // the label not_found with only the content of register object unchanged. 45444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static void GenerateLookupNumberStringCache(MacroAssembler* masm, 45544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register object, 45644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register result, 45744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch1, 45844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch2, 45944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch3, 46044f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool object_is_smi, 46144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Label* not_found); 46244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 46344f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 46444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Major MajorKey() { return NumberToString; } 46544f0eee88ff00398ff7f715fab053374d808c90dSteve Block int MinorKey() { return 0; } 46644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 46744f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Generate(MacroAssembler* masm); 46844f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 46944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 47044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass RecordWriteStub: public CodeStub { 4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordWriteStub(Register object, 4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value, 4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register address, 4763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RememberedSetAction remembered_set_action, 4773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode fp_mode) 4783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : object_(object), 4793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value_(value), 4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch address_(address), 4813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch remembered_set_action_(remembered_set_action), 4823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch save_fp_regs_mode_(fp_mode), 4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch regs_(object, // An input reg. 4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch address, // An input reg. 4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value) { // One scratch reg. 4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch enum Mode { 4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_BUFFER_ONLY, 4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch INCREMENTAL, 4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch INCREMENTAL_COMPACTION 4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool IsPregenerated(); 4953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateFixedRegStubsAheadOfTime(); 4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool SometimesSetsUpAFrame() { return false; } 4973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void PatchBranchIntoNop(MacroAssembler* masm, int pos) { 4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const unsigned offset = masm->instr_at(pos) & kImm16Mask; 5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->instr_at_put(pos, BNE | (zero_reg.code() << kRsShift) | 5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (zero_reg.code() << kRtShift) | (offset & kImm16Mask)); 5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Assembler::IsBne(masm->instr_at(pos))); 5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void PatchNopIntoBranch(MacroAssembler* masm, int pos) { 5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const unsigned offset = masm->instr_at(pos) & kImm16Mask; 5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->instr_at_put(pos, BEQ | (zero_reg.code() << kRsShift) | 5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (zero_reg.code() << kRtShift) | (offset & kImm16Mask)); 5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Assembler::IsBeq(masm->instr_at(pos))); 5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static Mode GetMode(Code* stub) { 5133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Instr first_instruction = Assembler::instr_at(stub->instruction_start()); 5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Instr second_instruction = Assembler::instr_at(stub->instruction_start() + 5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2 * Assembler::kInstrSize); 5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (Assembler::IsBeq(first_instruction)) { 5183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return INCREMENTAL; 5193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Assembler::IsBne(first_instruction)); 5223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (Assembler::IsBeq(second_instruction)) { 5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return INCREMENTAL_COMPACTION; 5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Assembler::IsBne(second_instruction)); 5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return STORE_BUFFER_ONLY; 5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void Patch(Code* stub, Mode mode) { 5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MacroAssembler masm(NULL, 5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stub->instruction_start(), 5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stub->instruction_size()); 5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (mode) { 5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case STORE_BUFFER_ONLY: 5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(GetMode(stub) == INCREMENTAL || 5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetMode(stub) == INCREMENTAL_COMPACTION); 5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PatchBranchIntoNop(&masm, 0); 5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PatchBranchIntoNop(&masm, 2 * Assembler::kInstrSize); 5423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case INCREMENTAL: 5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); 5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PatchNopIntoBranch(&masm, 0); 5463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case INCREMENTAL_COMPACTION: 5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); 5493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PatchNopIntoBranch(&masm, 2 * Assembler::kInstrSize); 5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(GetMode(stub) == mode); 5533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CPU::FlushICache(stub->instruction_start(), 4 * Assembler::kInstrSize); 5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 5573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // This is a helper class for freeing up 3 scratch registers. The input is 5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // two registers that must be preserved and one scratch register provided by 5593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the caller. 5603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class RegisterAllocation { 5613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 5623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegisterAllocation(Register object, 5633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register address, 5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch0) 5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : object_(object), 5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch address_(address), 5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch0_(scratch0) { 5683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!AreAliased(scratch0, object, address, no_reg)); 5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch1_ = GetRegThatIsNotOneOf(object_, address_, scratch0_); 5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Save(MacroAssembler* masm) { 5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!AreAliased(object_, address_, scratch1_, scratch0_)); 5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We don't have to save scratch0_ because it was given to us as 5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // a scratch register. 5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->push(scratch1_); 5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Restore(MacroAssembler* masm) { 5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->pop(scratch1_); 5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If we have to call into C then we need to save and restore all caller- 5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // saved registers that were not already preserved. The scratch registers 5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // will be restored by other means so we don't bother pushing them here. 5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { 5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->MultiPush((kJSCallerSaved | ra.bit()) & ~scratch1_.bit()); 5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mode == kSaveFPRegs) { 5893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CpuFeatures::Scope scope(FPU); 5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->MultiPushFPU(kCallerSavedFPU); 5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline void RestoreCallerSaveRegisters(MacroAssembler*masm, 5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode mode) { 5963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mode == kSaveFPRegs) { 5973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CpuFeatures::Scope scope(FPU); 5983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->MultiPopFPU(kCallerSavedFPU); 5993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->MultiPop((kJSCallerSaved | ra.bit()) & ~scratch1_.bit()); 6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Register object() { return object_; } 6043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Register address() { return address_; } 6053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Register scratch0() { return scratch0_; } 6063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Register scratch1() { return scratch1_; } 6073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object_; 6103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register address_; 6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch0_; 6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch1_; 6133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register GetRegThatIsNotOneOf(Register r1, 6153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register r2, 6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register r3) { 6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < Register::kNumAllocatableRegisters; i++) { 6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register candidate = Register::FromAllocationIndex(i); 6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (candidate.is(r1)) continue; 6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (candidate.is(r2)) continue; 6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (candidate.is(r3)) continue; 6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return candidate; 6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return no_reg; 6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch friend class RecordWriteStub; 6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 6293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch enum OnNoNeedToInformIncrementalMarker { 6313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kReturnOnNoNeedToInformIncrementalMarker, 6323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kUpdateRememberedSetOnNoNeedToInformIncrementalMarker 6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 6343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Generate(MacroAssembler* masm); 6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void GenerateIncremental(MacroAssembler* masm, Mode mode); 6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void CheckNeedsToInformIncrementalMarker( 6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MacroAssembler* masm, 6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch OnNoNeedToInformIncrementalMarker on_no_need, 6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Mode mode); 6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void InformIncrementalMarker(MacroAssembler* masm, Mode mode); 6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Major MajorKey() { return RecordWrite; } 6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int MinorKey() { 6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ObjectBits::encode(object_.code()) | 6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ValueBits::encode(value_.code()) | 6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AddressBits::encode(address_.code()) | 6493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RememberedSetActionBits::encode(remembered_set_action_) | 6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsModeBits::encode(save_fp_regs_mode_); 6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Activate(Code* code) { 6543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code); 6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class ObjectBits: public BitField<int, 0, 5> {}; 6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class ValueBits: public BitField<int, 5, 5> {}; 6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class AddressBits: public BitField<int, 10, 5> {}; 6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class RememberedSetActionBits: public BitField<RememberedSetAction, 15, 1> {}; 6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 16, 1> {}; 6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object_; 6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value_; 6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register address_; 6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RememberedSetAction remembered_set_action_; 6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode save_fp_regs_mode_; 6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label slow_; 6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegisterAllocation regs_; 6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 67344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Enter C code from generated RegExp code in a way that allows 67444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// the C code to fix the return address in case of a GC. 67544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Currently only needed on ARM and MIPS. 67644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass RegExpCEntryStub: public CodeStub { 67744f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 67844f0eee88ff00398ff7f715fab053374d808c90dSteve Block RegExpCEntryStub() {} 67944f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual ~RegExpCEntryStub() {} 68044f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Generate(MacroAssembler* masm); 68144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 68244f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 68344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Major MajorKey() { return RegExpCEntry; } 68444f0eee88ff00398ff7f715fab053374d808c90dSteve Block int MinorKey() { return 0; } 68544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 68644f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool NeedsImmovableCode() { return true; } 68744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 68844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 689257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Trampoline stub to call into native code. To call safely into native code 690257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// in the presence of compacting GC (which can move code objects) we need to 691257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// keep the code which called into native pinned in the memory. Currently the 692257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// simplest approach is to generate such stub early enough so it can never be 693257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// moved by GC 694257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass DirectCEntryStub: public CodeStub { 695257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 696257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch DirectCEntryStub() {} 697257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void Generate(MacroAssembler* masm); 698257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateCall(MacroAssembler* masm, 699257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ExternalReference function); 700257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateCall(MacroAssembler* masm, Register target); 701257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 702257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 703257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Major MajorKey() { return DirectCEntry; } 704257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int MinorKey() { return 0; } 705257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 706257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool NeedsImmovableCode() { return true; } 707257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 708257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 709257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass FloatingPointHelper : public AllStatic { 710257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 711257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch enum Destination { 712257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kFPURegisters, 713257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kCoreRegisters 714257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch }; 71544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 716257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 717257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Loads smis from a0 and a1 (right and left in binary operations) into 718257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // floating point registers. Depending on the destination the values ends up 719257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // either f14 and f12 or in a2/a3 and a0/a1 respectively. If the destination 720257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // is floating point registers FPU must be supported. If core registers are 721257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // requested when FPU is supported f12 and f14 will be scratched. 722257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void LoadSmis(MacroAssembler* masm, 723257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Destination destination, 724257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch1, 725257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch2); 726257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 727257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Loads objects from a0 and a1 (right and left in binary operations) into 728257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // floating point registers. Depending on the destination the values ends up 729257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // either f14 and f12 or in a2/a3 and a0/a1 respectively. If the destination 730257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // is floating point registers FPU must be supported. If core registers are 731257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // requested when FPU is supported f12 and f14 will still be scratched. If 732257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // either a0 or a1 is not a number (not smi and not heap number object) the 733257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // not_number label is jumped to with a0 and a1 intact. 734257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void LoadOperands(MacroAssembler* masm, 735257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FloatingPointHelper::Destination destination, 736257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register heap_number_map, 737257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch1, 738257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch2, 739257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* not_number); 740257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 741257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Convert the smi or heap number in object to an int32 using the rules 742257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // for ToInt32 as described in ECMAScript 9.5.: the value is truncated 743257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // and brought into the range -2^31 .. +2^31 - 1. 744257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void ConvertNumberToInt32(MacroAssembler* masm, 745257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register object, 746257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst, 747257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register heap_number_map, 748257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch1, 749257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch2, 750257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch3, 751257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FPURegister double_scratch, 752257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* not_int32); 753257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 754257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Converts the integer (untagged smi) in |int_scratch| to a double, storing 755257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // the result either in |double_dst| or |dst2:dst1|, depending on 756257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // |destination|. 757257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Warning: The value in |int_scratch| will be changed in the process! 758257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void ConvertIntToDouble(MacroAssembler* masm, 759257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register int_scratch, 760257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Destination destination, 761257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FPURegister double_dst, 762257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst1, 763257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst2, 764257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch2, 765257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FPURegister single_scratch); 766257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 767257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Load the number from object into double_dst in the double format. 768257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Control will jump to not_int32 if the value cannot be exactly represented 769257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // by a 32-bit integer. 770257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Floating point value in the 32-bit integer range that are not exact integer 771257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // won't be loaded. 772257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void LoadNumberAsInt32Double(MacroAssembler* masm, 773257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register object, 774257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Destination destination, 775257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FPURegister double_dst, 776257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst1, 777257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst2, 778257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register heap_number_map, 779257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch1, 780257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch2, 781257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FPURegister single_scratch, 782257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* not_int32); 783257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 784257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Loads the number from object into dst as a 32-bit integer. 785257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Control will jump to not_int32 if the object cannot be exactly represented 786257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // by a 32-bit integer. 787257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Floating point value in the 32-bit integer range that are not exact integer 788257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // won't be converted. 789257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // scratch3 is not used when FPU is supported. 790257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void LoadNumberAsInt32(MacroAssembler* masm, 791257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register object, 792257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst, 793257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register heap_number_map, 79444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch1, 79544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch2, 796257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch3, 797257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FPURegister double_scratch, 798257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* not_int32); 799257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 800257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Generate non FPU code to check if a double can be exactly represented by a 801257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // 32-bit integer. This does not check for 0 or -0, which need 802257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // to be checked for separately. 803257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Control jumps to not_int32 if the value is not a 32-bit integer, and falls 804257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // through otherwise. 805257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // src1 and src2 will be cloberred. 806257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // 807257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Expected input: 808257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // - src1: higher (exponent) part of the double value. 809257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // - src2: lower (mantissa) part of the double value. 810257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Output status: 811257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // - dst: 32 higher bits of the mantissa. (mantissa[51:20]) 812257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // - src2: contains 1. 813257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // - other registers are clobbered. 814257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void DoubleIs32BitInteger(MacroAssembler* masm, 815257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 816257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 817257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst, 818257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch, 819257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* not_int32); 820257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 821257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Generates code to call a C function to do a double operation using core 822257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // registers. (Used when FPU is not supported.) 823257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // This code never falls through, but returns with a heap number containing 824257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // the result in v0. 825257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Register heapnumber_result must be a heap number in which the 826257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // result of the operation will be stored. 827257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Requires the following layout on entry: 828257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // a0: Left value (least significant part of mantissa). 829257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // a1: Left value (sign, exponent, top of mantissa). 830257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // a2: Right value (least significant part of mantissa). 831257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // a3: Right value (sign, exponent, top of mantissa). 832257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void CallCCodeForDoubleOperation(MacroAssembler* masm, 833257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Token::Value op, 834257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register heap_number_result, 835257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch); 836257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 837257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 838257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void LoadNumber(MacroAssembler* masm, 839257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FloatingPointHelper::Destination destination, 840257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register object, 841257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FPURegister dst, 842257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst1, 843257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst2, 844257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register heap_number_map, 845257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch1, 846257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch2, 847257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* not_number); 848257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 849257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 850257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 851257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass StringDictionaryLookupStub: public CodeStub { 852257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 853257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; 854257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 855257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch explicit StringDictionaryLookupStub(LookupMode mode) : mode_(mode) { } 856257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 857257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void Generate(MacroAssembler* masm); 858257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 8593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateNegativeLookup(MacroAssembler* masm, 8603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* miss, 8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* done, 8623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register receiver, 8633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register properties, 8643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name, 8653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch0); 866257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 867257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GeneratePositiveLookup(MacroAssembler* masm, 868257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* miss, 869257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* done, 870257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register elements, 871257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register name, 872257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register r0, 873257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register r1); 874257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 8753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool SometimesSetsUpAFrame() { return false; } 8763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 877257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 878257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const int kInlinedProbes = 4; 879257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const int kTotalProbes = 20; 880257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 881257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const int kCapacityOffset = 882257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StringDictionary::kHeaderSize + 883257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StringDictionary::kCapacityIndex * kPointerSize; 884257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 885257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const int kElementsStartOffset = 886257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StringDictionary::kHeaderSize + 887257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StringDictionary::kElementsStartIndex * kPointerSize; 888257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 8893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Major MajorKey() { return StringDictionaryLookup; } 890257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 891257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int MinorKey() { 892257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return LookupModeBits::encode(mode_); 893257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 894257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 895257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class LookupModeBits: public BitField<LookupMode, 0, 1> {}; 896257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 897257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LookupMode mode_; 898257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 89944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 90044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 90144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} } // namespace v8::internal 90244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 90344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif // V8_MIPS_CODE_STUBS_ARM_H_ 904