1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Redistribution and use in source and binary forms, with or without 380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// modification, are permitted provided that the following conditions are 480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// met: 580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// 680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// * Redistributions of source code must retain the above copyright 780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// notice, this list of conditions and the following disclaimer. 880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// * Redistributions in binary form must reproduce the above 980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// copyright notice, this list of conditions and the following 1080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// disclaimer in the documentation and/or other materials provided 1180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// with the distribution. 1280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// * Neither the name of Google Inc. nor the names of its 1380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// contributors may be used to endorse or promote products derived 1480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// from this software without specific prior written permission. 1580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// 1680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 2880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#ifndef V8_ARM_CODE_STUBS_ARM_H_ 2980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#define V8_ARM_CODE_STUBS_ARM_H_ 3080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 3180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#include "ic-inl.h" 3280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 3380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsennamespace v8 { 3480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsennamespace internal { 3580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 3680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 3780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Compute a transcendental math function natively, or call the 3880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// TranscendentalCache runtime function. 3980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass TranscendentalCacheStub: public CodeStub { 4080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 41e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch enum ArgumentType { 42e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch TAGGED = 0 << TranscendentalCache::kTranscendentalTypeBits, 43e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits 44e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch }; 45e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 46e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch TranscendentalCacheStub(TranscendentalCache::Type type, 47e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ArgumentType argument_type) 48e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch : type_(type), argument_type_(argument_type) { } 4980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 5080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 5180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen TranscendentalCache::Type type_; 52e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ArgumentType argument_type_; 53e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void GenerateCallCFunction(MacroAssembler* masm, Register scratch); 54e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 5580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return TranscendentalCache; } 56e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int MinorKey() { return type_ | argument_type_; } 5780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Runtime::FunctionId RuntimeFunction(); 5880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 5980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 6080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass StoreBufferOverflowStub: public CodeStub { 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp) 643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : save_doubles_(save_fp) { } 653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Generate(MacroAssembler* masm); 673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool IsPregenerated(); 693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateFixedRegStubsAheadOfTime(); 703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool SometimesSetsUpAFrame() { return false; } 713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode save_doubles_; 743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Major MajorKey() { return StoreBufferOverflow; } 763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; } 773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 80257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass UnaryOpStub: public CodeStub { 811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public: 823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch UnaryOpStub(Token::Value op, 833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch UnaryOverwriteMode mode, 843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED) 851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block : op_(op), 861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block mode_(mode), 873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch operand_type_(operand_type) { 88257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 89257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 90257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 91257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Token::Value op_; 92257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UnaryOverwriteMode mode_; 93257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 94257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Operand type information determined at runtime. 95257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UnaryOpIC::TypeInfo operand_type_; 96257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual void PrintName(StringStream* stream); 98257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 99257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {}; 100257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class OpBits: public BitField<Token::Value, 1, 7> {}; 101257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class OperandTypeInfoBits: public BitField<UnaryOpIC::TypeInfo, 8, 3> {}; 102257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 103257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Major MajorKey() { return UnaryOp; } 104257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int MinorKey() { 105257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return ModeBits::encode(mode_) 106257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch | OpBits::encode(op_) 107257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch | OperandTypeInfoBits::encode(operand_type_); 108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 109257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 110257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Note: A lot of the helper functions below will vanish when we use virtual 111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // function instead of switch more often. 112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void Generate(MacroAssembler* masm); 113257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 114257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateTypeTransition(MacroAssembler* masm); 115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 116257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateSmiStub(MacroAssembler* masm); 117257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateSmiStubSub(MacroAssembler* masm); 118257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateSmiStubBitNot(MacroAssembler* masm); 119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateSmiCodeSub(MacroAssembler* masm, Label* non_smi, Label* slow); 120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateSmiCodeBitNot(MacroAssembler* masm, Label* slow); 121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 122257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateHeapNumberStub(MacroAssembler* masm); 123257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateHeapNumberStubSub(MacroAssembler* masm); 124257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateHeapNumberStubBitNot(MacroAssembler* masm); 125257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateHeapNumberCodeSub(MacroAssembler* masm, Label* slow); 126257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateHeapNumberCodeBitNot(MacroAssembler* masm, Label* slow); 127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateGenericStub(MacroAssembler* masm); 129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateGenericStubSub(MacroAssembler* masm); 130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateGenericStubBitNot(MacroAssembler* masm); 131257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateGenericCodeFallback(MacroAssembler* masm); 132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 133257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual int GetCodeKind() { return Code::UNARY_OP_IC; } 134257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 135257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual InlineCacheState GetICState() { 136257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return UnaryOpIC::ToState(operand_type_); 137257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void FinishCode(Handle<Code> code) { 140257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch code->set_unary_op_type(operand_type_); 141257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 142257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 143257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 144257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 145257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass BinaryOpStub: public CodeStub { 146257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 147257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpStub(Token::Value op, OverwriteMode mode) 148257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch : op_(op), 149257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch mode_(mode), 150257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch operands_type_(BinaryOpIC::UNINITIALIZED), 1513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch result_type_(BinaryOpIC::UNINITIALIZED) { 1528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch use_vfp3_ = CpuFeatures::IsSupported(VFP3); 1531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); 1541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 1551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 156257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpStub( 1571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int key, 158257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpIC::TypeInfo operands_type, 159257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED) 1601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block : op_(OpBits::decode(key)), 1611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block mode_(ModeBits::decode(key)), 1621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block use_vfp3_(VFP3Bits::decode(key)), 1631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block operands_type_(operands_type), 1643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch result_type_(result_type) { } 1651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private: 1671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block enum SmiCodeGenerateHeapNumberResults { 1681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ALLOW_HEAPNUMBER_RESULTS, 1691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block NO_HEAPNUMBER_RESULTS 1701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block }; 1711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Token::Value op_; 1731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block OverwriteMode mode_; 1741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool use_vfp3_; 1751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Operand type information determined at runtime. 177257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpIC::TypeInfo operands_type_; 178257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpIC::TypeInfo result_type_; 1791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual void PrintName(StringStream* stream); 1811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Minor key encoding in 16 bits RRRTTTVOOOOOOOMM. 1831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block class ModeBits: public BitField<OverwriteMode, 0, 2> {}; 1841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block class OpBits: public BitField<Token::Value, 2, 7> {}; 1851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block class VFP3Bits: public BitField<bool, 9, 1> {}; 186257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class OperandTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {}; 187257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class ResultTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {}; 1881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 189257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Major MajorKey() { return BinaryOp; } 1901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int MinorKey() { 1911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return OpBits::encode(op_) 1921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block | ModeBits::encode(mode_) 1931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block | VFP3Bits::encode(use_vfp3_) 1941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block | OperandTypeInfoBits::encode(operands_type_) 1951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block | ResultTypeInfoBits::encode(result_type_); 1961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 1971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void Generate(MacroAssembler* masm); 1991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateGeneric(MacroAssembler* masm); 2001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateSmiSmiOperation(MacroAssembler* masm); 2011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateFPOperation(MacroAssembler* masm, 2021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool smi_operands, 2031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Label* not_numbers, 2041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Label* gc_required); 2051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateSmiCode(MacroAssembler* masm, 2068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Label* use_runtime, 2071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Label* gc_required, 2081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block SmiCodeGenerateHeapNumberResults heapnumber_results); 2091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateLoadArguments(MacroAssembler* masm); 2101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateReturn(MacroAssembler* masm); 2111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateUninitializedStub(MacroAssembler* masm); 2121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateSmiStub(MacroAssembler* masm); 2131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateInt32Stub(MacroAssembler* masm); 2141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateHeapNumberStub(MacroAssembler* masm); 21544f0eee88ff00398ff7f715fab053374d808c90dSteve Block void GenerateOddballStub(MacroAssembler* masm); 2161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateStringStub(MacroAssembler* masm); 217257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateBothStringStub(MacroAssembler* masm); 2181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateGenericStub(MacroAssembler* masm); 2191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateAddStrings(MacroAssembler* masm); 2201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateCallRuntime(MacroAssembler* masm); 2211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateHeapResultAllocation(MacroAssembler* masm, 2231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Register result, 2241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Register heap_number_map, 2251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Register scratch1, 2261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Register scratch2, 2271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Label* gc_required); 2281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateRegisterArgsPush(MacroAssembler* masm); 2291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateTypeTransition(MacroAssembler* masm); 2301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm); 2311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 232257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual int GetCodeKind() { return Code::BINARY_OP_IC; } 2331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block virtual InlineCacheState GetICState() { 235257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return BinaryOpIC::ToState(operands_type_); 2361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void FinishCode(Handle<Code> code) { 239257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch code->set_binary_op_type(operands_type_); 240257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch code->set_binary_op_result_type(result_type_); 2411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block friend class CodeGenerator; 2441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 2451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 247692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdochclass StringHelper : public AllStatic { 248692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch public: 249692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // Generate code for copying characters using a simple loop. This should only 250692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // be used in places where the number of characters is small and the 251692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // additional setup and checking in GenerateCopyCharactersLong adds too much 252692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // overhead. Copying of overlapping regions is not supported. 253692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // Dest register ends at the position after the last character written. 254692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch static void GenerateCopyCharacters(MacroAssembler* masm, 255692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register dest, 256692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register src, 257692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register count, 258692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register scratch, 259692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch bool ascii); 260692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 261692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // Generate code for copying a large number of characters. This function 262692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // is allowed to spend extra time setting up conditions to make copying 263692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // faster. Copying of overlapping regions is not supported. 264692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // Dest register ends at the position after the last character written. 265692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch static void GenerateCopyCharactersLong(MacroAssembler* masm, 266692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register dest, 267692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register src, 268692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register count, 269692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register scratch1, 270692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register scratch2, 271692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register scratch3, 272692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register scratch4, 273692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register scratch5, 274692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch int flags); 275692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 276692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 277692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // Probe the symbol table for a two character string. If the string is 278692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // not found by probing a jump to the label not_found is performed. This jump 279692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // does not guarantee that the string is not in the symbol table. If the 280692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // string is found the code falls through with the string in register r0. 281692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // Contents of both c1 and c2 registers are modified. At the exit c1 is 282692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // guaranteed to contain halfword with low and high bytes equal to 283692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // initial contents of c1 and c2 respectively. 284692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, 285692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register c1, 286692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register c2, 287692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register scratch1, 288692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register scratch2, 289692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register scratch3, 290692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register scratch4, 291692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register scratch5, 292692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Label* not_found); 293692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 294692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // Generate string hash. 295692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch static void GenerateHashInit(MacroAssembler* masm, 296692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register hash, 297692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register character); 298692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 299692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch static void GenerateHashAddCharacter(MacroAssembler* masm, 300692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register hash, 301692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register character); 302692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 303692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch static void GenerateHashGetHash(MacroAssembler* masm, 304692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Register hash); 305692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 306692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch private: 307692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper); 308692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch}; 309692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 310692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 31180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Flag that indicates how to generate code for the stub StringAddStub. 31280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenenum StringAddFlags { 31380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen NO_STRING_ADD_FLAGS = 0, 314e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Omit left string check in stub (left is definitely a string). 315e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NO_STRING_CHECK_LEFT_IN_STUB = 1 << 0, 316e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Omit right string check in stub (right is definitely a string). 317e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NO_STRING_CHECK_RIGHT_IN_STUB = 1 << 1, 318e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Omit both string checks in stub. 319e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NO_STRING_CHECK_IN_STUB = 320e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NO_STRING_CHECK_LEFT_IN_STUB | NO_STRING_CHECK_RIGHT_IN_STUB 32180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 32280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 32380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 32480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass StringAddStub: public CodeStub { 32580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 326e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch explicit StringAddStub(StringAddFlags flags) : flags_(flags) {} 32780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 32880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 32980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return StringAdd; } 330e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int MinorKey() { return flags_; } 33180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 33280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 33380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 334e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void GenerateConvertArgument(MacroAssembler* masm, 335e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int stack_offset, 336e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Register arg, 337e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Register scratch1, 338e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Register scratch2, 339e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Register scratch3, 340e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Register scratch4, 341e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Label* slow); 342e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 343e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const StringAddFlags flags_; 34480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 34580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 34680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 34780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass SubStringStub: public CodeStub { 34880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 34980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen SubStringStub() {} 35080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 35180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 35280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return SubString; } 35380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return 0; } 35480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 35580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 35680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 35780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 35880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 35980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 36080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass StringCompareStub: public CodeStub { 36180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 36280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringCompareStub() { } 36380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 364257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Compares two flat ASCII strings and returns result in r0. 36580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm, 36680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register left, 36780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register right, 36880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch1, 36980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch2, 37080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch3, 37180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch4); 37280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Compares two flat ASCII strings for equality and returns result 374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // in r0. 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); 38180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 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 Label* chars_not_equal); 39480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 39580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 39680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 39780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// This stub can convert a signed int32 to a heap number (double). It does 39880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// not work for int32s that are in Smi range! No GC occurs during this stub 39980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// so you don't have to set up the frame. 40080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass WriteInt32ToHeapNumberStub : public CodeStub { 40180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 40280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen WriteInt32ToHeapNumberStub(Register the_int, 40380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register the_heap_number, 40480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch) 40580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : the_int_(the_int), 40680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen the_heap_number_(the_heap_number), 40780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen scratch_(scratch) { } 40880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool IsPregenerated(); 4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateFixedRegStubsAheadOfTime(); 4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 41380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register the_int_; 41480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register the_heap_number_; 41580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch_; 41680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 41780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Minor key encoding in 16 bits. 41880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class IntRegisterBits: public BitField<int, 0, 4> {}; 41980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class HeapNumberRegisterBits: public BitField<int, 4, 4> {}; 42080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class ScratchRegisterBits: public BitField<int, 8, 4> {}; 42180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 42280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return WriteInt32ToHeapNumber; } 42380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { 42480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Encode the parameters in a unique 16 bit value. 42580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return IntRegisterBits::encode(the_int_.code()) 42680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen | HeapNumberRegisterBits::encode(the_heap_number_.code()) 42780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen | ScratchRegisterBits::encode(scratch_.code()); 42880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 42980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 43080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 43180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 43280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 43380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 43480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass NumberToStringStub: public CodeStub { 43580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 43680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen NumberToStringStub() { } 43780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 43880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Generate code to do a lookup in the number string cache. If the number in 43980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // the register object is found in the cache the generated code falls through 44080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // with the result in the result register. The object and the result register 44180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // can be the same. If the number is not found in the cache the code jumps to 44280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // the label not_found with only the content of register object unchanged. 44380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static void GenerateLookupNumberStringCache(MacroAssembler* masm, 44480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register object, 44580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register result, 44680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch1, 44780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch2, 44880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch3, 44980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool object_is_smi, 45080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* not_found); 45180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 45280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 45380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return NumberToString; } 45480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return 0; } 45580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 45680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 45780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 45880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 45980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass RecordWriteStub: public CodeStub { 4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordWriteStub(Register object, 4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value, 4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register address, 4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RememberedSetAction remembered_set_action, 4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode fp_mode) 4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : object_(object), 4683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value_(value), 4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch address_(address), 4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch remembered_set_action_(remembered_set_action), 4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch save_fp_regs_mode_(fp_mode), 4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch regs_(object, // An input reg. 4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch address, // An input reg. 4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value) { // One scratch reg. 4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch enum Mode { 4783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_BUFFER_ONLY, 4793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch INCREMENTAL, 4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch INCREMENTAL_COMPACTION 4813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 4823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool IsPregenerated(); 4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateFixedRegStubsAheadOfTime(); 4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool SometimesSetsUpAFrame() { return false; } 4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void PatchBranchIntoNop(MacroAssembler* masm, int pos) { 4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->instr_at_put(pos, (masm->instr_at(pos) & ~B27) | (B24 | B20)); 4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Assembler::IsTstImmediate(masm->instr_at(pos))); 4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void PatchNopIntoBranch(MacroAssembler* masm, int pos) { 4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->instr_at_put(pos, (masm->instr_at(pos) & ~(B24 | B20)) | B27); 4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Assembler::IsBranch(masm->instr_at(pos))); 4953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static Mode GetMode(Code* stub) { 4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Instr first_instruction = Assembler::instr_at(stub->instruction_start()); 4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Instr second_instruction = Assembler::instr_at(stub->instruction_start() + 5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Assembler::kInstrSize); 5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (Assembler::IsBranch(first_instruction)) { 5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return INCREMENTAL; 5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Assembler::IsTstImmediate(first_instruction)); 5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (Assembler::IsBranch(second_instruction)) { 5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return INCREMENTAL_COMPACTION; 5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Assembler::IsTstImmediate(second_instruction)); 5133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return STORE_BUFFER_ONLY; 5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void Patch(Code* stub, Mode mode) { 5183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MacroAssembler masm(NULL, 5193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stub->instruction_start(), 5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stub->instruction_size()); 5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (mode) { 5223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case STORE_BUFFER_ONLY: 5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(GetMode(stub) == INCREMENTAL || 5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetMode(stub) == INCREMENTAL_COMPACTION); 5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PatchBranchIntoNop(&masm, 0); 5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PatchBranchIntoNop(&masm, Assembler::kInstrSize); 5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case INCREMENTAL: 5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); 5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PatchNopIntoBranch(&masm, 0); 5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case INCREMENTAL_COMPACTION: 5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); 5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PatchNopIntoBranch(&masm, Assembler::kInstrSize); 5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(GetMode(stub) == mode); 5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CPU::FlushICache(stub->instruction_start(), 2 * Assembler::kInstrSize); 5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 5423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // This is a helper class for freeing up 3 scratch registers. The input is 5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // two registers that must be preserved and one scratch register provided by 5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the caller. 5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class RegisterAllocation { 5463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegisterAllocation(Register object, 5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register address, 5493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch0) 5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : object_(object), 5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch address_(address), 5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch0_(scratch0) { 5533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!AreAliased(scratch0, object, address, no_reg)); 5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch1_ = GetRegThatIsNotOneOf(object_, address_, scratch0_); 5553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Save(MacroAssembler* masm) { 5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!AreAliased(object_, address_, scratch1_, scratch0_)); 5593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We don't have to save scratch0_ because it was given to us as 5603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // a scratch register. 5613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->push(scratch1_); 5623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Restore(MacroAssembler* masm) { 5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->pop(scratch1_); 5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If we have to call into C then we need to save and restore all caller- 5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // saved registers that were not already preserved. The scratch registers 5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // will be restored by other means so we don't bother pushing them here. 5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { 5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->stm(db_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit()); 5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mode == kSaveFPRegs) { 5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CpuFeatures::Scope scope(VFP3); 5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->sub(sp, 5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch sp, 5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1))); 5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Save all VFP registers except d0. 5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) { 5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DwVfpRegister reg = DwVfpRegister::from_code(i); 5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->vstr(reg, MemOperand(sp, (i - 1) * kDoubleSize)); 5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline void RestoreCallerSaveRegisters(MacroAssembler*masm, 5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode mode) { 5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mode == kSaveFPRegs) { 5893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CpuFeatures::Scope scope(VFP3); 5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Restore all VFP registers except d0. 5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) { 5923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DwVfpRegister reg = DwVfpRegister::from_code(i); 5933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->vldr(reg, MemOperand(sp, (i - 1) * kDoubleSize)); 5943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->add(sp, 5963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch sp, 5973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1))); 5983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->ldm(ia_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit()); 6003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Register object() { return object_; } 6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Register address() { return address_; } 6043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Register scratch0() { return scratch0_; } 6053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Register scratch1() { return scratch1_; } 6063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 6083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object_; 6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register address_; 6103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch0_; 6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch1_; 6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register GetRegThatIsNotOneOf(Register r1, 6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register r2, 6153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register r3) { 6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < Register::kNumAllocatableRegisters; i++) { 6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register candidate = Register::FromAllocationIndex(i); 6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (candidate.is(r1)) continue; 6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (candidate.is(r2)) continue; 6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (candidate.is(r3)) continue; 6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return candidate; 6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return no_reg; 6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch friend class RecordWriteStub; 6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch enum OnNoNeedToInformIncrementalMarker { 6303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kReturnOnNoNeedToInformIncrementalMarker, 6313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kUpdateRememberedSetOnNoNeedToInformIncrementalMarker 6323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Generate(MacroAssembler* masm); 6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void GenerateIncremental(MacroAssembler* masm, Mode mode); 6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void CheckNeedsToInformIncrementalMarker( 6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MacroAssembler* masm, 6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch OnNoNeedToInformIncrementalMarker on_no_need, 6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Mode mode); 6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void InformIncrementalMarker(MacroAssembler* masm, Mode mode); 6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Major MajorKey() { return RecordWrite; } 6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int MinorKey() { 6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ObjectBits::encode(object_.code()) | 6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ValueBits::encode(value_.code()) | 6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AddressBits::encode(address_.code()) | 6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RememberedSetActionBits::encode(remembered_set_action_) | 6493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsModeBits::encode(save_fp_regs_mode_); 6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Activate(Code* code) { 6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code); 6543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class ObjectBits: public BitField<int, 0, 4> {}; 6573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class ValueBits: public BitField<int, 4, 4> {}; 6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class AddressBits: public BitField<int, 8, 4> {}; 6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class RememberedSetActionBits: public BitField<RememberedSetAction, 12, 1> {}; 6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 13, 1> {}; 6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object_; 6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value_; 6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register address_; 6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RememberedSetAction remembered_set_action_; 6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode save_fp_regs_mode_; 6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label slow_; 6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegisterAllocation regs_; 6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 67280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Enter C code from generated RegExp code in a way that allows 67380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// the C code to fix the return address in case of a GC. 67480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Currently only needed on ARM. 67580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass RegExpCEntryStub: public CodeStub { 67680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 67780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen RegExpCEntryStub() {} 67880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual ~RegExpCEntryStub() {} 67980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 68080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 68180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 68280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return RegExpCEntry; } 68380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return 0; } 68444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 68544f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool NeedsImmovableCode() { return true; } 68680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 68780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 68880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 6891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Trampoline stub to call into native code. To call safely into native code 6901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// in the presence of compacting GC (which can move code objects) we need to 6911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// keep the code which called into native pinned in the memory. Currently the 6921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// simplest approach is to generate such stub early enough so it can never be 6931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// moved by GC 6941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockclass DirectCEntryStub: public CodeStub { 6951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public: 6961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DirectCEntryStub() {} 6971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void Generate(MacroAssembler* masm); 698e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void GenerateCall(MacroAssembler* masm, ExternalReference function); 699e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void GenerateCall(MacroAssembler* masm, Register target); 7001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 7011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private: 7021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Major MajorKey() { return DirectCEntry; } 7031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int MinorKey() { return 0; } 70444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 70544f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool NeedsImmovableCode() { return true; } 7061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 7071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 7081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 709257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass FloatingPointHelper : public AllStatic { 710257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 711257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch enum Destination { 712257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kVFPRegisters, 713257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kCoreRegisters 714257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch }; 715257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 716257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 717257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Loads smis from r0 and r1 (right and left in binary operations) into 718257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // floating point registers. Depending on the destination the values ends up 719257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // either d7 and d6 or in r2/r3 and r0/r1 respectively. If the destination is 720257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // floating point registers VFP3 must be supported. If core registers are 721257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // requested when VFP3 is supported d6 and d7 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 r0 and r1 (right and left in binary operations) into 728257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // floating point registers. Depending on the destination the values ends up 729257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // either d7 and d6 or in r2/r3 and r0/r1 respectively. If the destination is 730257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // floating point registers VFP3 must be supported. If core registers are 731257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // requested when VFP3 is supported d6 and d7 will still be scratched. If 732257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // either r0 or r1 is not a number (not smi and not heap number object) the 733257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // not_number label is jumped to with r0 and r1 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 DwVfpRegister 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 DwVfpRegister double_dst, 762257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst1, 763257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst2, 764257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch2, 765257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SwVfpRegister 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 DwVfpRegister 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 SwVfpRegister 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 VFP3 is supported. 790257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void LoadNumberAsInt32(MacroAssembler* masm, 791257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register object, 792257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst, 793257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register heap_number_map, 794257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch1, 795257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch2, 796257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch3, 797257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch DwVfpRegister double_scratch, 798257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* not_int32); 799257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 800257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Generate non VFP3 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 VFP3 is not supported.) 823257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // This code never falls through, but returns with a heap number containing 824257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // the result in r0. 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 // r0: Left value (least significant part of mantissa). 829257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // r1: Left value (sign, exponent, top of mantissa). 830257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // r2: Right value (least significant part of mantissa). 831257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // r3: 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 DwVfpRegister 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}; 899257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 900257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 90180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} } // namespace v8::internal 90280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 90380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#endif // V8_ARM_CODE_STUBS_ARM_H_ 904