1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved. 2a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Redistribution and use in source and binary forms, with or without 3a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// modification, are permitted provided that the following conditions are 4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// met: 5a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// 6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// * Redistributions of source code must retain the above copyright 7a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// notice, this list of conditions and the following disclaimer. 8a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// * Redistributions in binary form must reproduce the above 9a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// copyright notice, this list of conditions and the following 10a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// disclaimer in the documentation and/or other materials provided 11a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// with the distribution. 12a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// * Neither the name of Google Inc. nor the names of its 13a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// contributors may be used to endorse or promote products derived 14a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// from this software without specific prior written permission. 15a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// 16a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 28c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#include "v8.h" 29c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 31c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 32a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "ia32/lithium-codegen-ia32.h" 33a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#include "ic.h" 34a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "code-stubs.h" 357979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org#include "deoptimizer.h" 36a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "stub-cache.h" 370ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry#include "codegen.h" 38a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 39a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace v8 { 40a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace internal { 41a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 42a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 43750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgstatic SaveFPRegsMode GetSaveFPRegsMode() { 44750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // We don't need to save floating point regs when generating the snapshot 45750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return CpuFeatures::IsSafeForSnapshot(SSE2) ? kSaveFPRegs : kDontSaveFPRegs; 46750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 47750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 48750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 4931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org// When invoking builtins, we need to record the safepoint in the middle of 5031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org// the invoke instruction sequence generated by the macro assembler. 51fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.orgclass SafepointGenerator : public CallWrapper { 52a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public: 53a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SafepointGenerator(LCodeGen* codegen, 54a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LPointerMap* pointers, 5527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode mode) 56a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org : codegen_(codegen), 57a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org pointers_(pointers), 5827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org deopt_mode_(mode) {} 59a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org virtual ~SafepointGenerator() { } 60a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 61fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org virtual void BeforeCall(int call_size) const {} 62fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org 63fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org virtual void AfterCall() const { 6427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org codegen_->RecordSafepoint(pointers_, deopt_mode_); 65a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 66a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 67a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private: 68a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LCodeGen* codegen_; 69a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LPointerMap* pointers_; 7027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode deopt_mode_; 71a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}; 72a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 73a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 74a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define __ masm()-> 75a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 76a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgbool LCodeGen::GenerateCode() { 771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org LPhase phase("Z_Code generation", chunk()); 78a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(is_unused()); 79a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org status_ = GENERATING; 80c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 81c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Open a frame scope to indicate that there is a frame on the stack. The 82c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // MANUAL indicates that the scope shouldn't actually generate code to set up 83c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the frame (that is done in GeneratePrologue). 84c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope frame_scope(masm_, StackFrame::MANUAL); 85c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 8694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org support_aligned_spilled_doubles_ = info()->IsOptimizing(); 8794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 88a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org dynamic_frame_alignment_ = info()->IsOptimizing() && 89a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ((chunk()->num_double_slots() > 2 && 90a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org !chunk()->graph()->is_recursive()) || 91a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org !info()->osr_ast_id().IsNone()); 927028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 93a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return GeneratePrologue() && 94a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org GenerateBody() && 95a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org GenerateDeferredCode() && 96a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org GenerateJumpTable() && 97a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org GenerateSafepointTable(); 98a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 99a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::FinishCode(Handle<Code> code) { 102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(is_done()); 103160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org code->set_stack_slots(GetStackSlotCount()); 10483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); 1056ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org if (FLAG_weak_embedded_maps_in_optimized_code) { 1066ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org RegisterDependentCodeForEmbeddedMaps(code); 1076ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org } 108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PopulateDeoptimizationData(code); 109a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (!info()->IsStub()) { 110a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); 111a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 1121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org info()->CommitDependencies(code); 113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 116594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::Abort(BailoutReason reason) { 11746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org info()->set_bailout_reason(reason); 118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org status_ = ABORTED; 119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 122a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::Comment(const char* format, ...) { 123a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (!FLAG_code_comments) return; 124a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org char buffer[4 * KB]; 125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org StringBuilder builder(buffer, ARRAY_SIZE(buffer)); 126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org va_list arguments; 127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org va_start(arguments, format); 128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org builder.AddFormattedList(format, arguments); 129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org va_end(arguments); 130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 131a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Copy the string before recording it in the assembler to avoid 132a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // issues when the stack allocated buffer goes out of scope. 133a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org size_t length = builder.position(); 134a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Vector<char> copy = Vector<char>::New(length + 1); 135e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::MemCopy(copy.start(), builder.Finalize(), copy.length()); 136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org masm()->RecordComment(copy.start()); 137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 140d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#ifdef _MSC_VER 141d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid LCodeGen::MakeSureStackPagesMapped(int offset) { 142d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org const int kPageSize = 4 * KB; 143d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org for (offset -= kPageSize; offset > 0; offset -= kPageSize) { 144d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ mov(Operand(esp, offset), eax); 145d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 146d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 147d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#endif 148d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 149d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 150a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgbool LCodeGen::GeneratePrologue() { 151a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(is_generating()); 152a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 153a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (info()->IsOptimizing()) { 154a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ProfileEntryHookStub::MaybeCallEntryHook(masm_); 155753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org 156a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG 157a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (strlen(FLAG_stop_at) > 0 && 15859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 159a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ int3(); 160a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 161a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif 162a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 163a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Strict mode functions and builtins need to replace the receiver 164a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // with undefined when called as functions (without an explicit 165a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // receiver object). ecx is zero for method calls and non-zero for 166a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // function calls. 167a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (!info_->is_classic_mode() || info_->is_native()) { 168a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Label ok; 169a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ test(ecx, Operand(ecx)); 170a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ j(zero, &ok, Label::kNear); 171a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // +1 for return address. 172a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize; 173a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ mov(Operand(esp, receiver_offset), 174a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Immediate(isolate()->factory()->undefined_value())); 175a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ bind(&ok); 176a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 1775323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org 17894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) { 179a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Move state of dynamic frame alignment into edx. 180a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ mov(edx, Immediate(kNoAlignmentPadding)); 181a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 182a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Label do_not_pad, align_loop; 183a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org STATIC_ASSERT(kDoubleSize == 2 * kPointerSize); 184a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Align esp + 4 to a multiple of 2 * kPointerSize. 185a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ test(esp, Immediate(kPointerSize)); 186a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ j(not_zero, &do_not_pad, Label::kNear); 187a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ push(Immediate(0)); 188a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ mov(ebx, esp); 189a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ mov(edx, Immediate(kAlignmentPaddingPushed)); 190a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Copy arguments, receiver, and return address. 191a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ mov(ecx, Immediate(scope()->num_parameters() + 2)); 192a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 193a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ bind(&align_loop); 194a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ mov(eax, Operand(ebx, 1 * kPointerSize)); 195a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ mov(Operand(ebx, 0), eax); 196a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ add(Operand(ebx), Immediate(kPointerSize)); 197a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ dec(ecx); 198a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ j(not_zero, &align_loop, Label::kNear); 199a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue)); 200a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ bind(&do_not_pad); 201a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 2027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 2037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 20483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org info()->set_prologue_offset(masm_->pc_offset()); 205a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (NeedsEagerFrame()) { 206a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(!frame_is_built_); 207a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org frame_is_built_ = true; 208a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ push(ebp); // Caller's frame pointer. 209a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ mov(ebp, esp); 2104e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org info()->AddNoFrameRange(0, masm_->pc_offset()); 211a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ push(esi); // Callee's context. 212a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (info()->IsStub()) { 213a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ push(Immediate(Smi::FromInt(StackFrame::STUB))); 214a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 215a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ push(edi); // Callee's JS function. 216a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 217a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 219a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (info()->IsOptimizing() && 220a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org dynamic_frame_alignment_ && 221a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org FLAG_debug_code) { 2227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ test(esp, Immediate(kPointerSize)); 223594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(zero, kFrameIsExpectedToBeAligned); 2247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 2257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Reserve space for the stack slots needed by the code. 227160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org int slots = GetStackSlotCount(); 228a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(slots != 0 || !info()->IsOptimizing()); 229a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (slots > 0) { 230a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (slots == 1) { 231a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (dynamic_frame_alignment_) { 232a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ push(edx); 233a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 234a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ push(Immediate(kNoAlignmentPadding)); 235a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 2365323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org } else { 237a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (FLAG_debug_code) { 23894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ sub(Operand(esp), Immediate(slots * kPointerSize)); 239d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#ifdef _MSC_VER 240d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org MakeSureStackPagesMapped(slots * kPointerSize); 241d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#endif 24294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ push(eax); 243a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ mov(Operand(eax), Immediate(slots)); 244a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Label loop; 245a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ bind(&loop); 24694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ mov(MemOperand(esp, eax, times_4, 0), 24794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Immediate(kSlotsZapValue)); 248a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ dec(eax); 249a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ j(not_zero, &loop); 25094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ pop(eax); 251a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 252a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ sub(Operand(esp), Immediate(slots * kPointerSize)); 253a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#ifdef _MSC_VER 254d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org MakeSureStackPagesMapped(slots * kPointerSize); 255a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#endif 256c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 2577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 25894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (support_aligned_spilled_doubles_) { 25994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Comment(";;; Store dynamic frame alignment tag for spilled doubles"); 26094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // Store dynamic frame alignment state in the first local. 26194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org int offset = JavaScriptFrameConstants::kDynamicAlignmentStateOffset; 26294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (dynamic_frame_alignment_) { 26394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ mov(Operand(ebp, offset), edx); 26494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } else { 26594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ mov(Operand(ebp, offset), Immediate(kNoAlignmentPadding)); 26694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 26794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 26894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 26994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 27094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { 27194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Comment(";;; Save clobbered callee double registers"); 272750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 27394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org int count = 0; 27494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org BitVector* doubles = chunk()->allocated_double_registers(); 27594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org BitVector::Iterator save_iterator(doubles); 27694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org while (!save_iterator.Done()) { 27794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ movdbl(MemOperand(esp, count * kDoubleSize), 27894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org XMMRegister::FromAllocationIndex(save_iterator.Current())); 27994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org save_iterator.Advance(); 28094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org count++; 281a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Possibly allocate a local context. 286a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 2873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (heap_slots > 0) { 2883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Comment(";;; Allocate local context"); 2893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Argument to NewContext is the function, which is still in edi. 2903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ push(edi); 2913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (heap_slots <= FastNewContextStub::kMaximumSlots) { 2923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org FastNewContextStub stub(heap_slots); 2933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ CallStub(&stub); 2943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 2956d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org __ CallRuntime(Runtime::kNewFunctionContext, 1); 2963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 29727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(Safepoint::kNoLazyDeopt); 2983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Context is returned in both eax and esi. It replaces the context 2993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // passed to us. It's saved in the stack and kept live in esi. 3003a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); 3013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 3023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Copy parameters into context if necessary. 3033a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int num_parameters = scope()->num_parameters(); 3043a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org for (int i = 0; i < num_parameters; i++) { 305486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Variable* var = scope()->parameter(i); 306486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (var->IsContextSlot()) { 3073a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int parameter_offset = StandardFrameConstants::kCallerSPOffset + 3083a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org (num_parameters - 1 - i) * kPointerSize; 3093a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Load parameter from stack. 3103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ mov(eax, Operand(ebp, parameter_offset)); 3113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Store it in the context. 312486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org int context_offset = Context::SlotOffset(var->index()); 3133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ mov(Operand(esi, context_offset), eax); 314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Update the write barrier. This clobbers eax and ebx. 315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ RecordWriteContextSlot(esi, 316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com context_offset, 317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com eax, 318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ebx, 319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kDontSaveFPRegs); 3203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 3213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 3223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Comment(";;; End allocate local context"); 3233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 3243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 325a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Trace the call. 326a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (FLAG_trace && info()->IsOptimizing()) { 327496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // We have not executed any compiled code yet, so esi still holds the 328496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // incoming context. 329a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ CallRuntime(Runtime::kTraceEnter, 0); 330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return !is_aborted(); 332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 333a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 334a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 335a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgbool LCodeGen::GenerateBody() { 336a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(is_generating()); 337a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org bool emit_instructions = true; 338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (current_instruction_ = 0; 339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org !is_aborted() && current_instruction_ < instructions_->length(); 340a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org current_instruction_++) { 341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LInstruction* instr = instructions_->at(current_instruction_); 34232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org 34332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org // Don't emit code for basic blocks with a replacement. 344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (instr->IsLabel()) { 34532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org emit_instructions = !LLabel::cast(instr)->HasReplacement(); 346a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 34732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (!emit_instructions) continue; 348a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 34932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (FLAG_code_comments && instr->HasInterestingComment(this)) { 35032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; <@%d,#%d> %s", 35132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org current_instruction_, 35232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->hydrogen_value()->id(), 35332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->Mnemonic()); 35432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org } 355e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 35632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr); 357e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 358594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org RecordAndUpdatePosition(instr->position()); 359594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 36032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->CompileToNative(this); 361e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 36232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (!CpuFeatures::IsSupported(SSE2)) { 36332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (FLAG_debug_code && FLAG_enable_slow_asserts) { 36432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ VerifyX87StackDepth(x87_stack_depth_); 365e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 366a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 367a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 36827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org EnsureSpaceForLazyDeopt(); 369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return !is_aborted(); 370a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 373a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool LCodeGen::GenerateJumpTable() { 374169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Label needs_frame; 37532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (jump_table_.length() > 0) { 37632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; -------------------- Jump table --------------------"); 37732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org } 378a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int i = 0; i < jump_table_.length(); i++) { 379a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ bind(&jump_table_[i].label); 380a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Address entry = jump_table_[i].address; 381aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org Deoptimizer::BailoutType type = jump_table_[i].bailout_type; 382876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); 383068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org if (id == Deoptimizer::kNotDeoptimizationEntry) { 384068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org Comment(";;; jump table entry %d.", i); 385068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } else { 386068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); 387068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } 388a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (jump_table_[i].needs_frame) { 389a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ push(Immediate(ExternalReference::ForDeoptEntry(entry))); 390169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (needs_frame.is_bound()) { 391169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ jmp(&needs_frame); 392a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 393169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ bind(&needs_frame); 394169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ push(MemOperand(ebp, StandardFrameConstants::kContextOffset)); 395169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // This variant of deopt can only be used with stubs. Since we don't 396169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // have a function pointer to install in the stack frame that we're 397169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // building, install a special marker there instead. 398169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(info()->IsStub()); 399169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ push(Immediate(Smi::FromInt(StackFrame::STUB))); 400169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Push a PC inside the function so that the deopt code can find where 401169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // the deopt comes from. It doesn't have to be the precise return 402169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // address of a "calling" LAZY deopt, it only has to be somewhere 403169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // inside the code body. 404169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Label push_approx_pc; 405169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ call(&push_approx_pc); 406169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ bind(&push_approx_pc); 407169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Push the continuation which was stashed were the ebp should 408169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // be. Replace it with the saved ebp. 409169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ push(MemOperand(esp, 3 * kPointerSize)); 410169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ mov(MemOperand(esp, 4 * kPointerSize), ebp); 411169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ lea(ebp, MemOperand(esp, 4 * kPointerSize)); 412169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ ret(0); // Call the continuation without clobbering registers. 413a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 414a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 415169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ call(entry, RelocInfo::RUNTIME_ENTRY); 416a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 417a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 418a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return !is_aborted(); 419a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 420a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 421a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 422a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgbool LCodeGen::GenerateDeferredCode() { 423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(is_generating()); 424ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org if (deferred_.length() > 0) { 425ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 426ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org LDeferredCode* code = deferred_[i]; 427594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 428594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int pos = instructions_->at(code->instruction_index())->position(); 429594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org RecordAndUpdatePosition(pos); 430594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 43132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; <@%d,#%d> " 43232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org "-------------------- Deferred %s --------------------", 43332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org code->instruction_index(), 43432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org code->instr()->hydrogen_value()->id(), 43532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org code->instr()->Mnemonic()); 436ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org __ bind(code->entry()); 437a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (NeedsDeferredFrame()) { 43832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; Build frame"); 439a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(!frame_is_built_); 440a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(info()->IsStub()); 441a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org frame_is_built_ = true; 442a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Build the frame in such a way that esi isn't trashed. 443a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ push(ebp); // Caller's frame pointer. 444a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ push(Operand(ebp, StandardFrameConstants::kContextOffset)); 445a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ push(Immediate(Smi::FromInt(StackFrame::STUB))); 446a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ lea(ebp, Operand(esp, 2 * kPointerSize)); 44732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; Deferred code"); 448a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 449ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org code->Generate(); 450a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (NeedsDeferredFrame()) { 45132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; Destroy frame"); 452a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(frame_is_built_); 453a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org frame_is_built_ = false; 454a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ mov(esp, ebp); 455a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ pop(ebp); 456a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 457ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org __ jmp(code->exit()); 458ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org } 459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Deferred code is the last part of the instruction sequence. Mark 462a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // the generated code as done unless we bailed out. 463a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (!is_aborted()) status_ = DONE; 464a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return !is_aborted(); 465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 467a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 468a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgbool LCodeGen::GenerateSafepointTable() { 469a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(is_done()); 470a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (!info()->IsStub()) { 471a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // For lazy deoptimization we need space to patch a call after every call. 472a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Ensure there is always space for such patching, even if the code ends 473a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // in a call. 474a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int target_offset = masm()->pc_offset() + Deoptimizer::patch_size(); 475a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org while (masm()->pc_offset() < target_offset) { 476a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org masm()->nop(); 477a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 478a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 479160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org safepoints_.Emit(masm(), GetStackSlotCount()); 480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return !is_aborted(); 481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgRegister LCodeGen::ToRegister(int index) const { 485a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return Register::FromAllocationIndex(index); 486a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 489169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgX87Register LCodeGen::ToX87Register(int index) const { 490169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org return X87Register::FromAllocationIndex(index); 491169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org} 492169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 493169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgXMMRegister LCodeGen::ToDoubleRegister(int index) const { 495a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return XMMRegister::FromAllocationIndex(index); 496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 499169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87LoadForUsage(X87Register reg) { 500169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(X87StackContains(reg)); 501169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Fxch(reg); 502169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org x87_stack_depth_--; 503a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 504a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 505a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 506169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87Fxch(X87Register reg, int other_slot) { 507169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(X87StackContains(reg) && x87_stack_depth_ > other_slot); 508169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org int i = X87ArrayIndex(reg); 509169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org int st = x87_st2idx(i); 510169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (st != other_slot) { 511169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org int other_i = x87_st2idx(other_slot); 512169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Register other = x87_stack_[other_i]; 513169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org x87_stack_[other_i] = reg; 514169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org x87_stack_[i] = other; 515169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (st == 0) { 516169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fxch(other_slot); 517169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } else if (other_slot == 0) { 518169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fxch(st); 519169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } else { 520169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fxch(st); 521169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fxch(other_slot); 522169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fxch(st); 523169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 524169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 525e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 526e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 527e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 528169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgint LCodeGen::x87_st2idx(int pos) { 529169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org return x87_stack_depth_ - pos - 1; 530e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 531e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 532e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 533169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgint LCodeGen::X87ArrayIndex(X87Register reg) { 534169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org for (int i = 0; i < x87_stack_depth_; i++) { 535169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (x87_stack_[i].is(reg)) return i; 536169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 537169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org UNREACHABLE(); 538169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org return -1; 539169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org} 540169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 541169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 542169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgbool LCodeGen::X87StackContains(X87Register reg) { 543169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org for (int i = 0; i < x87_stack_depth_; i++) { 544169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (x87_stack_[i].is(reg)) return true; 545169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 546169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org return false; 547e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 548e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 549e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 550169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87Free(X87Register reg) { 551169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(X87StackContains(reg)); 552169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org int i = X87ArrayIndex(reg); 553169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org int st = x87_st2idx(i); 554169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (st > 0) { 555169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // keep track of how fstp(i) changes the order of elements 556169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org int tos_i = x87_st2idx(0); 557169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org x87_stack_[i] = x87_stack_[tos_i]; 558169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 559e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org x87_stack_depth_--; 560169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fstp(st); 561169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org} 562169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 563169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 564169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87Mov(X87Register dst, Operand src, X87OperandType opts) { 565169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (X87StackContains(dst)) { 566169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Fxch(dst); 567169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fstp(0); 568169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } else { 569169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(x87_stack_depth_ < X87Register::kNumAllocatableRegisters); 570169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org x87_stack_[x87_stack_depth_] = dst; 571169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org x87_stack_depth_++; 572169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 573169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Fld(src, opts); 574e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 575e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 576e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 577169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87Fld(Operand src, X87OperandType opts) { 578169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (opts == kX87DoubleOperand) { 579169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fld_d(src); 580169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } else if (opts == kX87FloatOperand) { 581169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fld_s(src); 582169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } else if (opts == kX87IntOperand) { 583169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fild_s(src); 584169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } else { 585169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org UNREACHABLE(); 586e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 587e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 588e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 589e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 590169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87Mov(Operand dst, X87Register src) { 591169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Fxch(src); 592169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fst_d(dst); 593169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org} 594169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 595169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 596169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87PrepareToWrite(X87Register reg) { 597169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (X87StackContains(reg)) { 598169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Free(reg); 599169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 600169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Mark this register as the next register to write to 601169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org x87_stack_[x87_stack_depth_] = reg; 602169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org} 603169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 604169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 605169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87CommitWrite(X87Register reg) { 606169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Assert the reg is prepared to write, but not on the virtual stack yet 607169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(!X87StackContains(reg) && x87_stack_[x87_stack_depth_].is(reg) && 608169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org x87_stack_depth_ < X87Register::kNumAllocatableRegisters); 609169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org x87_stack_depth_++; 610169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org} 611169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 612169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 613169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87PrepareBinaryOp( 614169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Register left, X87Register right, X87Register result) { 615169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // You need to use DefineSameAsFirst for x87 instructions 616169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(result.is(left)); 617169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Fxch(right, 1); 618169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Fxch(left); 619169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org} 620169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 621169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 622e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::FlushX87StackIfNecessary(LInstruction* instr) { 623169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (x87_stack_depth_ > 0 && instr->ClobbersDoubleRegisters()) { 624169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org bool double_inputs = instr->HasDoubleRegisterInput(); 625169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 626169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Flush stack from tos down, since FreeX87() will mess with tos 627169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org for (int i = x87_stack_depth_-1; i >= 0; i--) { 628169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Register reg = x87_stack_[i]; 629169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Skip registers which contain the inputs for the next instruction 630169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // when flushing the stack 631169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (double_inputs && instr->IsDoubleInput(reg, this)) { 632169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org continue; 633169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 634169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Free(reg); 635169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (i < x87_stack_depth_-1) i++; 636e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 637e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 638169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (instr->IsReturn()) { 639169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org while (x87_stack_depth_ > 0) { 640169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fstp(0); 641169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org x87_stack_depth_--; 642169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 643169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 644169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org} 645169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 646169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 647169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::EmitFlushX87ForDeopt() { 648169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org for (int i = 0; i < x87_stack_depth_; i++) __ fstp(0); 649e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 650e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 651e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 652a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgRegister LCodeGen::ToRegister(LOperand* op) const { 653a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(op->IsRegister()); 654a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return ToRegister(op->index()); 655a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 656a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 657a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 658169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgX87Register LCodeGen::ToX87Register(LOperand* op) const { 659169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(op->IsDoubleRegister()); 660169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org return ToX87Register(op->index()); 661169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org} 662169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 663169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 664a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgXMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const { 665a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(op->IsDoubleRegister()); 666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return ToDoubleRegister(op->index()); 667a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 668a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 669a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 670fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgint32_t LCodeGen::ToInteger32(LConstantOperand* op) const { 671fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org return ToRepresentation(op, Representation::Integer32()); 672fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org} 673fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 674fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 675fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgint32_t LCodeGen::ToRepresentation(LConstantOperand* op, 676fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org const Representation& r) const { 677657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org HConstant* constant = chunk_->LookupConstant(op); 678fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org int32_t value = constant->Integer32Value(); 679fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (r.IsInteger32()) return value; 680fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ASSERT(r.IsSmiOrTagged()); 681fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org return reinterpret_cast<int32_t>(Smi::FromInt(value)); 682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 683a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 684a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 68564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgHandle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { 686657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org HConstant* constant = chunk_->LookupConstant(op); 687a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); 688657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org return constant->handle(); 68964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 69064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 69164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 692394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comdouble LCodeGen::ToDouble(LConstantOperand* op) const { 693657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org HConstant* constant = chunk_->LookupConstant(op); 694657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org ASSERT(constant->HasDoubleValue()); 695657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org return constant->DoubleValue(); 696394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 697394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 698394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 699d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgExternalReference LCodeGen::ToExternalReference(LConstantOperand* op) const { 700d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HConstant* constant = chunk_->LookupConstant(op); 701d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(constant->HasExternalReferenceValue()); 702d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return constant->ExternalReferenceValue(); 703d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 704d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 705d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 706bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.orgbool LCodeGen::IsInteger32(LConstantOperand* op) const { 70753ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); 708a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 710a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 711a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgbool LCodeGen::IsSmi(LConstantOperand* op) const { 712a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org return chunk_->LookupLiteralRepresentation(op).IsSmi(); 713a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org} 714a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 715a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 716a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgOperand LCodeGen::ToOperand(LOperand* op) const { 717a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (op->IsRegister()) return Operand(ToRegister(op)); 718a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (op->IsDoubleRegister()) return Operand(ToDoubleRegister(op)); 719a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); 720ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org return Operand(ebp, StackSlotOffset(op->index())); 721a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 722a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 723a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comOperand LCodeGen::HighOperand(LOperand* op) { 7250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ASSERT(op->IsDoubleStackSlot()); 726ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org return Operand(ebp, StackSlotOffset(op->index()) + kPointerSize); 7270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 7280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 730c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::WriteTranslation(LEnvironment* environment, 731b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Translation* translation) { 732c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (environment == NULL) return; 733c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 734c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // The translation includes one command per value in the environment. 735b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org int translation_size = environment->translation_size(); 736c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // The output frame height does not include the parameters. 737c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int height = translation_size - environment->parameter_count(); 738c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 739b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org WriteTranslation(environment->outer(), translation); 740a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool has_closure_id = !info()->closure().is_null() && 74132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org !info()->closure().is_identical_to(environment->closure()); 742a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int closure_id = has_closure_id 7435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ? DefineDeoptimizationLiteral(environment->closure()) 7445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org : Translation::kSelfLiteralId; 745967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org switch (environment->frame_type()) { 746967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org case JS_FUNCTION: 747967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org translation->BeginJSFrame(environment->ast_id(), closure_id, height); 748967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org break; 749967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org case JS_CONSTRUCT: 750967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org translation->BeginConstructStubFrame(closure_id, translation_size); 751967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org break; 752de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org case JS_GETTER: 753de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org ASSERT(translation_size == 1); 754de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org ASSERT(height == 0); 755de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org translation->BeginGetterStubFrame(closure_id); 756de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org break; 757471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org case JS_SETTER: 75846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ASSERT(translation_size == 2); 75946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ASSERT(height == 0); 76046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org translation->BeginSetterStubFrame(closure_id); 761471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org break; 762967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org case ARGUMENTS_ADAPTOR: 763967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); 764967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org break; 765a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case STUB: 766a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org translation->BeginCompiledStubFrame(); 767a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org break; 768a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org default: 769a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org UNREACHABLE(); 770659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 77156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 772594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int object_index = 0; 773594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int dematerialized_index = 0; 774c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = 0; i < translation_size; ++i) { 775c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LOperand* value = environment->values()->at(i); 776594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org AddToTranslation(environment, 777594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation, 77846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org value, 77946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org environment->HasTaggedValueAt(i), 780594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org environment->HasUint32ValueAt(i), 781594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org &object_index, 782594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org &dematerialized_index); 783c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 784c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 785c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 786c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 787594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::AddToTranslation(LEnvironment* environment, 788594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Translation* translation, 789a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LOperand* op, 79046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org bool is_tagged, 791594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org bool is_uint32, 792594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int* object_index_pointer, 793594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int* dematerialized_index_pointer) { 794594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (op == LEnvironment::materialization_marker()) { 795594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int object_index = (*object_index_pointer)++; 796594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (environment->ObjectIsDuplicateAt(object_index)) { 797594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int dupe_of = environment->ObjectDuplicateOfAt(object_index); 798594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation->DuplicateObject(dupe_of); 799594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return; 800594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 801594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int object_length = environment->ObjectLengthAt(object_index); 802594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (environment->ObjectIsArgumentsAt(object_index)) { 803594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation->BeginArgumentsObject(object_length); 804594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 805594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation->BeginCapturedObject(object_length); 806594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 807594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int dematerialized_index = *dematerialized_index_pointer; 808594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int env_offset = environment->translation_size() + dematerialized_index; 809594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org *dematerialized_index_pointer += object_length; 810594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org for (int i = 0; i < object_length; ++i) { 811594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org LOperand* value = environment->values()->at(env_offset + i); 812594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org AddToTranslation(environment, 813594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation, 814594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org value, 815594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org environment->HasTaggedValueAt(env_offset + i), 816594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org environment->HasUint32ValueAt(env_offset + i), 817594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org object_index_pointer, 818594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org dematerialized_index_pointer); 819594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 820594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return; 821594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 822594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 823b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (op->IsStackSlot()) { 824a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (is_tagged) { 825a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org translation->StoreStackSlot(op->index()); 82646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } else if (is_uint32) { 82746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org translation->StoreUint32StackSlot(op->index()); 828a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org translation->StoreInt32StackSlot(op->index()); 830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (op->IsDoubleStackSlot()) { 832a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org translation->StoreDoubleStackSlot(op->index()); 833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (op->IsArgument()) { 834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(is_tagged); 835160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org int src_index = GetStackSlotCount() + op->index(); 836a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org translation->StoreStackSlot(src_index); 837a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (op->IsRegister()) { 838a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register reg = ToRegister(op); 839a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (is_tagged) { 840a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org translation->StoreRegister(reg); 84146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } else if (is_uint32) { 84246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org translation->StoreUint32Register(reg); 843a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 844a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org translation->StoreInt32Register(reg); 845a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 846a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (op->IsDoubleRegister()) { 847a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org XMMRegister reg = ToDoubleRegister(op); 848a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org translation->StoreDoubleRegister(reg); 849a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (op->IsConstantOperand()) { 850657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op)); 851657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org int src_index = DefineDeoptimizationLiteral(constant->handle()); 852a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org translation->StoreLiteral(src_index); 853a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 854a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org UNREACHABLE(); 855a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 856a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 857a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 858a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 85944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid LCodeGen::CallCodeGeneric(Handle<Code> code, 86044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org RelocInfo::Mode mode, 86144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org LInstruction* instr, 86244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org SafepointMode safepoint_mode) { 86331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org ASSERT(instr != NULL); 86431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org LPointerMap* pointers = instr->pointer_map(); 86531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org RecordPosition(pointers->position()); 86631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org __ call(code, mode); 86727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepointWithLazyDeopt(instr, safepoint_mode); 8685f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 8695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Signal that we don't inline smi code before these stubs in the 8705f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // optimizing code generator. 87140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org if (code->kind() == Code::BINARY_OP_IC || 8725f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org code->kind() == Code::COMPARE_IC) { 8735f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org __ nop(); 8745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 875a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 876a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 877a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 87844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid LCodeGen::CallCode(Handle<Code> code, 87944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org RelocInfo::Mode mode, 880ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org LInstruction* instr) { 881ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT); 88244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org} 88344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 88444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 885ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid LCodeGen::CallRuntime(const Runtime::Function* fun, 886496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org int argc, 887ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org LInstruction* instr) { 888a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(instr != NULL); 88931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org ASSERT(instr->HasPointerMap()); 890a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LPointerMap* pointers = instr->pointer_map(); 891a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org RecordPosition(pointers->position()); 892a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 893496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ CallRuntime(fun, argc); 8947979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 89527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 896a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 897a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(info()->is_calling()); 898a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 899a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 900a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 90194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::LoadContextFromDeferred(LOperand* context) { 902ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org if (context->IsRegister()) { 903ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org if (!ToRegister(context).is(esi)) { 904ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org __ mov(esi, ToRegister(context)); 905ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org } 906c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else if (context->IsStackSlot()) { 907ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org __ mov(esi, ToOperand(context)); 908c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else if (context->IsConstantOperand()) { 909657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org HConstant* constant = 910657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org chunk_->LookupConstant(LConstantOperand::cast(context)); 911594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ LoadObject(esi, Handle<Object>::cast(constant->handle())); 912c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 913c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com UNREACHABLE(); 914ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org } 91594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 91694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 91794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 91894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org int argc, 91994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org LInstruction* instr, 92094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org LOperand* context) { 92194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org LoadContextFromDeferred(context); 922ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org 92344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org __ CallRuntimeSaveDoubles(id); 92444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org RecordSafepointWithRegisters( 92527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org instr->pointer_map(), argc, Safepoint::kNoLazyDeopt); 926a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 927a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(info()->is_calling()); 92844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org} 92944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 93044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 93127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::RegisterEnvironmentForDeoptimization( 93227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org LEnvironment* environment, Safepoint::DeoptMode mode) { 933a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (!environment->HasBeenRegistered()) { 934a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Physical stack frame layout: 935a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // -x ............. -4 0 ..................................... y 936a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // [incoming arguments] [spill slots] [pushed outgoing arguments] 937a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 938a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Layout of the environment: 939a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // 0 ..................................................... size-1 940a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // [parameters] [locals] [expression stack including arguments] 941a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 942a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Layout of the translation: 943a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // 0 ........................................................ size - 1 + 4 944a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // [expression stack including arguments] [locals] [4 words] [parameters] 945a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // |>------------ translation_size ------------<| 946a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 947a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int frame_count = 0; 948659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org int jsframe_count = 0; 949a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (LEnvironment* e = environment; e != NULL; e = e->outer()) { 950a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ++frame_count; 951967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org if (e->frame_type() == JS_FUNCTION) { 952659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org ++jsframe_count; 953659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 954a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 95556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Translation translation(&translations_, frame_count, jsframe_count, zone()); 956b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org WriteTranslation(environment, &translation); 957a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int deoptimization_index = deoptimizations_.length(); 95827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org int pc_offset = masm()->pc_offset(); 95927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org environment->Register(deoptimization_index, 96027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org translation.index(), 96127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 9627028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org deoptimizations_.Add(environment, zone()); 963a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 964a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 965a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 966a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 967aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.orgvoid LCodeGen::DeoptimizeIf(Condition cc, 968aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org LEnvironment* environment, 969aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org Deoptimizer::BailoutType bailout_type) { 97027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 971a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(environment->HasBeenRegistered()); 972a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int id = environment->deoptimization_index(); 973a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(info()->IsOptimizing() || info()->IsStub()); 9748432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Address entry = 9758432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); 976a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (entry == NULL) { 977594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kBailoutWasNotPrepared); 978a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return; 979a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 980a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 981e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (FLAG_deopt_every_n_times != 0 && !info()->IsStub()) { 982ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ExternalReference count = ExternalReference::stress_deopt_count(isolate()); 983a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Label no_deopt; 984a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ pushfd(); 985a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(eax); 986ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ mov(eax, Operand::StaticVariable(count)); 987ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ sub(eax, Immediate(1)); 98883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_zero, &no_deopt, Label::kNear); 989a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (FLAG_trap_on_deopt) __ int3(); 990ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ mov(eax, Immediate(FLAG_deopt_every_n_times)); 991ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ mov(Operand::StaticVariable(count), eax); 992a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ pop(eax); 993a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ popfd(); 99410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org ASSERT(frame_is_built_); 99510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org __ call(entry, RelocInfo::RUNTIME_ENTRY); 996a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&no_deopt); 997ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ mov(Operand::StaticVariable(count), eax); 998a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ pop(eax); 999a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ popfd(); 1000a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1001a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1002169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Before Instructions which can deopt, we normally flush the x87 stack. But 1003169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // we can have inputs or outputs of the current instruction on the stack, 1004169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // thus we need to flush them here from the physical stack to leave it in a 1005169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // consistent state. 1006169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (x87_stack_depth_ > 0) { 1007169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Label done; 1008169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear); 1009169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org EmitFlushX87ForDeopt(); 1010169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ bind(&done); 1011169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 1012169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 1013594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (info()->ShouldTrapOnDeopt()) { 10147c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Label done; 1015169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear); 10167c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ int3(); 10177c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ bind(&done); 10187c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 10197c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 1020a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(info()->IsStub() || frame_is_built_); 10217c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (cc == no_condition && frame_is_built_) { 1022169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ call(entry, RelocInfo::RUNTIME_ENTRY); 1023a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 10247c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // We often have several deopts to the same entry, reuse the last 10257c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // jump entry if this is the case. 10267c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (jump_table_.is_empty() || 10277c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org jump_table_.last().address != entry || 10287c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org jump_table_.last().needs_frame != !frame_is_built_ || 1029aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org jump_table_.last().bailout_type != bailout_type) { 1030aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org Deoptimizer::JumpTableEntry table_entry(entry, 1031aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org bailout_type, 1032aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org !frame_is_built_); 10337c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org jump_table_.Add(table_entry, zone()); 1034a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 10357c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (cc == no_condition) { 10367c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ jmp(&jump_table_.last().label); 1037a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 10387c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ j(cc, &jump_table_.last().label); 1039a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1040a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1041a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1042a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1043a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1044aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.orgvoid LCodeGen::DeoptimizeIf(Condition cc, 1045aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org LEnvironment* environment) { 1046aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org Deoptimizer::BailoutType bailout_type = info()->IsStub() 1047aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org ? Deoptimizer::LAZY 1048aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org : Deoptimizer::EAGER; 1049aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org DeoptimizeIf(cc, environment, bailout_type); 1050aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org} 1051aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org 1052aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org 10536ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.orgvoid LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) { 10546ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org ZoneList<Handle<Map> > maps(1, zone()); 10556ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 10566ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { 10576ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org RelocInfo::Mode mode = it.rinfo()->rmode(); 10586ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org if (mode == RelocInfo::EMBEDDED_OBJECT && 10596ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org it.rinfo()->target_object()->IsMap()) { 10606ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org Handle<Map> map(Map::cast(it.rinfo()->target_object())); 10616ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org if (map->CanTransition()) { 10626ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org maps.Add(map, zone()); 10636ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org } 10646ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org } 10656ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org } 10666ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org#ifdef VERIFY_HEAP 10676ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org // This disables verification of weak embedded maps after full GC. 10686ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org // AddDependentCode can cause a GC, which would observe the state where 10696ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org // this code is not yet in the depended code lists of the embedded maps. 10706ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org NoWeakEmbeddedMapsVerificationScope disable_verification_of_embedded_maps; 10716ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org#endif 10726ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org for (int i = 0; i < maps.length(); i++) { 10732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code); 10746ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org } 10756ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org} 10766ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org 10776ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org 1078a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 1079a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int length = deoptimizations_.length(); 1080a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (length == 0) return; 1081a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Handle<DeoptimizationInputData> data = 1082ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org factory()->NewDeoptimizationInputData(length, TENURED); 1083a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1084876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org Handle<ByteArray> translations = 1085876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org translations_.CreateByteArray(isolate()->factory()); 10869ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org data->SetTranslationByteArray(*translations); 1087a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); 1088a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1089a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Handle<FixedArray> literals = 1090ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); 109179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org { AllowDeferredHandleDereference copy_handles; 109232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org for (int i = 0; i < deoptimization_literals_.length(); i++) { 109332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org literals->set(i, *deoptimization_literals_[i]); 109432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org } 109532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org data->SetLiteralArray(*literals); 1096a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1097a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1098471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); 1099a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); 1100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Populate the deoptimization entries. 1102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < length; i++) { 1103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LEnvironment* env = deoptimizations_[i]; 1104471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org data->SetAstId(i, env->ast_id()); 1105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); 1106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->SetArgumentsStackHeight(i, 1107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Smi::FromInt(env->arguments_stack_height())); 110827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org data->SetPc(i, Smi::FromInt(env->pc_offset())); 1109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org code->set_deoptimization_data(*data); 1111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgint LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) { 1115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int result = deoptimization_literals_.length(); 1116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < deoptimization_literals_.length(); ++i) { 1117a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (deoptimization_literals_[i].is_identical_to(literal)) return i; 1118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 11197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org deoptimization_literals_.Add(literal, zone()); 1120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return result; 1121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1122a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1123a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1124a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() { 1125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(deoptimization_literals_.length() == 0); 1126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const ZoneList<Handle<JSFunction> >* inlined_closures = 1128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org chunk()->inlined_closures(); 1129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0, length = inlined_closures->length(); 1131a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org i < length; 1132a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org i++) { 1133a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DefineDeoptimizationLiteral(inlined_closures->at(i)); 1134a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org inlined_function_count_ = deoptimization_literals_.length(); 1137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 114027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::RecordSafepointWithLazyDeopt( 114127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org LInstruction* instr, SafepointMode safepoint_mode) { 114227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { 114327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt); 114427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } else { 114527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 114627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepointWithRegisters( 114727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org instr->pointer_map(), 0, Safepoint::kLazyDeopt); 114827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } 114927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org} 115027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org 115127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org 1152378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid LCodeGen::RecordSafepoint( 1153378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org LPointerMap* pointers, 1154378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Safepoint::Kind kind, 1155378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org int arguments, 115627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode deopt_mode) { 115744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ASSERT(kind == expected_safepoint_kind_); 1158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com const ZoneList<LOperand*>* operands = pointers->GetNormalizedOperands(); 115927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint safepoint = 116027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org safepoints_.DefineSafepoint(masm(), kind, arguments, deopt_mode); 1161a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < operands->length(); i++) { 1162a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LOperand* pointer = operands->at(i); 1163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (pointer->IsStackSlot()) { 1164400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org safepoint.DefinePointerSlot(pointer->index(), zone()); 1165378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { 11667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org safepoint.DefinePointerRegister(ToRegister(pointer), zone()); 1167a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1168a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1169378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org} 1170378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 1171378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 1172378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid LCodeGen::RecordSafepoint(LPointerMap* pointers, 117327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode mode) { 117427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(pointers, Safepoint::kSimple, 0, mode); 1175a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1176a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1177a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 117827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::RecordSafepoint(Safepoint::DeoptMode mode) { 11797028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org LPointerMap empty_pointers(RelocInfo::kNoPosition, zone()); 118027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(&empty_pointers, mode); 11813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 11823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 11833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, 1185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int arguments, 118627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode mode) { 118727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, mode); 1188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::RecordPosition(int position) { 11926d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org if (position == RelocInfo::kNoPosition) return; 1193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org masm()->positions_recorder()->RecordPosition(position); 1194a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1195a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1196a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1197594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::RecordAndUpdatePosition(int position) { 1198594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (position >= 0 && position != old_position_) { 1199594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org masm()->positions_recorder()->RecordPosition(position); 1200594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org old_position_ = position; 1201594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 1202594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 1203594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 1204594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 120532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.orgstatic const char* LabelType(LLabel* label) { 120632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (label->is_loop_header()) return " (loop header)"; 120732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (label->is_osr_entry()) return " (OSR entry)"; 120832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org return ""; 120932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org} 121032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org 121132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org 1212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoLabel(LLabel* label) { 121332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", 121432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org current_instruction_, 121532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org label->hydrogen_value()->id(), 1216b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org label->block_id(), 121732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org LabelType(label)); 1218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(label->label()); 1219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org current_block_ = label->block_id(); 12208e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org DoGap(label); 1221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoParallelMove(LParallelMove* move) { 12250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com resolver_.Resolve(move); 1226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoGap(LGap* gap) { 1230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = LGap::FIRST_INNER_POSITION; 1231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org i <= LGap::LAST_INNER_POSITION; 1232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org i++) { 1233a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LGap::InnerPosition inner_pos = static_cast<LGap::InnerPosition>(i); 1234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LParallelMove* move = gap->GetParallelMove(inner_pos); 1235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (move != NULL) DoParallelMove(move); 1236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12408e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid LCodeGen::DoInstructionGap(LInstructionGap* instr) { 12418e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org DoGap(instr); 12428e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org} 12438e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org 12448e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org 1245a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoParameter(LParameter* instr) { 1246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Nothing to do. 1247a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1248a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1249a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1250a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallStub(LCallStub* instr) { 1251496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 1252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 1253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org switch (instr->hydrogen()->major_key()) { 1254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case CodeStub::RegExpConstructResult: { 1255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org RegExpConstructResultStub stub; 12568432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1257a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1258a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1259a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case CodeStub::RegExpExec: { 1260a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org RegExpExecStub stub; 12618432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1264a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case CodeStub::SubString: { 1265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SubStringStub stub; 12668432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case CodeStub::NumberToString: { 1270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org NumberToStringStub stub; 12718432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1273a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case CodeStub::StringCompare: { 1275a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org StringCompareStub stub; 12768432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case CodeStub::TranscendentalCache: { 1280023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org TranscendentalCacheStub stub(instr->transcendental_type(), 1281023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org TranscendentalCacheStub::TAGGED); 12828432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org default: 1286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org UNREACHABLE(); 1287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 12921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Record the address of the first unknown OSR value as the place to enter. 12931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (osr_pc_offset_ == -1) osr_pc_offset_ = masm()->pc_offset(); 1294a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1295a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoModI(LModI* instr) { 12988a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org HMod* hmod = instr->hydrogen(); 12998a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org HValue* left = hmod->left(); 13008a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org HValue* right = hmod->right(); 13018a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (hmod->HasPowerOf2Divisor()) { 13028a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // TODO(svenpanne) We should really do the strength reduction on the 13038a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // Hydrogen level. 13048a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org Register left_reg = ToRegister(instr->left()); 13058a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org ASSERT(left_reg.is(ToRegister(instr->result()))); 1306b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 13078a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // Note: The code below even works when right contains kMinInt. 13088a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org int32_t divisor = Abs(right->GetInteger32Constant()); 1309b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 13108a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org Label left_is_not_negative, done; 13118a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (left->CanBeNegative()) { 13128a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ test(left_reg, Operand(left_reg)); 13138a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ j(not_sign, &left_is_not_negative, Label::kNear); 13148a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ neg(left_reg); 13158a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ and_(left_reg, divisor - 1); 13168a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ neg(left_reg); 13178a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 13188a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org DeoptimizeIf(zero, instr->environment()); 13198a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org } 13207b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org __ jmp(&done, Label::kNear); 1321b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org } 13228a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org 13238a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ bind(&left_is_not_negative); 13248a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ and_(left_reg, divisor - 1); 1325b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ bind(&done); 13268a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org 13271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (hmod->fixed_right_arg().has_value) { 132856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register left_reg = ToRegister(instr->left()); 13298a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org ASSERT(left_reg.is(ToRegister(instr->result()))); 133056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register right_reg = ToRegister(instr->right()); 1331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 13321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org int32_t divisor = hmod->fixed_right_arg().value; 13338a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org ASSERT(IsPowerOf2(divisor)); 13348a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org 13358a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // Check if our assumption of a fixed right operand still holds. 13368a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ cmp(right_reg, Immediate(divisor)); 13378a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org DeoptimizeIf(not_equal, instr->environment()); 13388a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org 13398a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org Label left_is_not_negative, done; 13408a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (left->CanBeNegative()) { 13418a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ test(left_reg, Operand(left_reg)); 13428a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ j(not_sign, &left_is_not_negative, Label::kNear); 13438a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ neg(left_reg); 13448a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ and_(left_reg, divisor - 1); 13458a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ neg(left_reg); 13468a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 13478a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org DeoptimizeIf(zero, instr->environment()); 13488a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org } 13498a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ jmp(&done, Label::kNear); 13508a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org } 13518a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org 13528a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ bind(&left_is_not_negative); 13538a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ and_(left_reg, divisor - 1); 13548a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ bind(&done); 13558a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org 13568a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org } else { 13578a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org Register left_reg = ToRegister(instr->left()); 13588e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org ASSERT(left_reg.is(eax)); 13598a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org Register right_reg = ToRegister(instr->right()); 1360b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org ASSERT(!right_reg.is(eax)); 1361b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org ASSERT(!right_reg.is(edx)); 13628a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org Register result_reg = ToRegister(instr->result()); 13638a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org ASSERT(result_reg.is(edx)); 1364a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 13658a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org Label done; 13668a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // Check for x % 0, idiv would signal a divide error. We have to 13678a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // deopt in this case because we can't return a NaN. 13688a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (right->CanBeZero()) { 13698e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org __ test(right_reg, Operand(right_reg)); 1370b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org DeoptimizeIf(zero, instr->environment()); 1371b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org } 1372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 13738a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // Check for kMinInt % -1, idiv would signal a divide error. We 13748a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // have to deopt if we care about -0, because we can't return that. 13758a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) { 13768a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org Label no_overflow_possible; 1377a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ cmp(left_reg, kMinInt); 13788a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ j(not_equal, &no_overflow_possible, Label::kNear); 1379a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ cmp(right_reg, -1); 13808a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 13818a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org DeoptimizeIf(equal, instr->environment()); 13828a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org } else { 13838a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ j(not_equal, &no_overflow_possible, Label::kNear); 13848a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Set(result_reg, Immediate(0)); 13858a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ jmp(&done, Label::kNear); 13868a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org } 13878a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ bind(&no_overflow_possible); 1388a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 1389a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 13908a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // Sign extend dividend in eax into edx:eax. 1391b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ cdq(); 1392a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 13938a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // If we care about -0, test if the dividend is <0 and the result is 0. 13948a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (left->CanBeNegative() && 13958a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org hmod->CanBeZero() && 13968a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 139783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label positive_left; 13988e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org __ test(left_reg, Operand(left_reg)); 139983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_sign, &positive_left, Label::kNear); 1400b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ idiv(right_reg); 14018e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org __ test(result_reg, Operand(result_reg)); 14028a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org DeoptimizeIf(zero, instr->environment()); 14038a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ jmp(&done, Label::kNear); 1404b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ bind(&positive_left); 1405b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org } 14068a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ idiv(right_reg); 14078e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org __ bind(&done); 1408a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1409a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1410a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1411a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1412a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoDivI(LDivI* instr) { 14134cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (!instr->is_flooring() && instr->hydrogen()->HasPowerOf2Divisor()) { 14145323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org Register dividend = ToRegister(instr->left()); 1415837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org int32_t divisor = instr->hydrogen()->right()->GetInteger32Constant(); 14165323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org int32_t test_value = 0; 14175323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org int32_t power = 0; 14185323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org 14195323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org if (divisor > 0) { 14205323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org test_value = divisor - 1; 14215323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org power = WhichPowerOf2(divisor); 14225323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org } else { 14235323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org // Check for (0 / -x) that will produce negative zero. 14245323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 14255323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org __ test(dividend, Operand(dividend)); 14265323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org DeoptimizeIf(zero, instr->environment()); 14275323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org } 14285323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org // Check for (kMinInt / -1). 14295323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 14305323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org __ cmp(dividend, kMinInt); 14315323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org DeoptimizeIf(zero, instr->environment()); 14325323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org } 14335323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org test_value = - divisor - 1; 14345323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org power = WhichPowerOf2(-divisor); 14355323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org } 14365323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org 14375323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org if (test_value != 0) { 1438837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org if (instr->hydrogen()->CheckFlag( 1439837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org HInstruction::kAllUsesTruncatingToInt32)) { 1440837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org Label done, negative; 1441837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org __ cmp(dividend, 0); 1442837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org __ j(less, &negative, Label::kNear); 1443837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org __ sar(dividend, power); 144421af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org if (divisor < 0) __ neg(dividend); 1445837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org __ jmp(&done, Label::kNear); 1446837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org 1447837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org __ bind(&negative); 1448837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org __ neg(dividend); 1449837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org __ sar(dividend, power); 1450837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org if (divisor > 0) __ neg(dividend); 1451837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org __ bind(&done); 1452837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org return; // Don't fall through to "__ neg" below. 1453837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org } else { 1454837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org // Deoptimize if remainder is not 0. 1455837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org __ test(dividend, Immediate(test_value)); 1456837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org DeoptimizeIf(not_zero, instr->environment()); 1457837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org __ sar(dividend, power); 1458837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org } 14595323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org } 14605323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org 14615323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org if (divisor < 0) __ neg(dividend); 14625323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org 14635323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org return; 14645323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org } 14655323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org 146656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 1467a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 146856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(ToRegister(instr->left()).is(eax)); 146956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(!ToRegister(instr->right()).is(eax)); 147056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(!ToRegister(instr->right()).is(edx)); 1471a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1472a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register left_reg = eax; 1473a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1474a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Check for x / 0. 1475a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register right_reg = ToRegister(right); 14764cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) { 1477a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(right_reg, ToOperand(right)); 1478a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(zero, instr->environment()); 1479a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Check for (0 / -x) that will produce negative zero. 14824cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (instr->hydrogen_value()->CheckFlag(HValue::kBailoutOnMinusZero)) { 148383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label left_not_zero; 1484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(left_reg, Operand(left_reg)); 148583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_zero, &left_not_zero, Label::kNear); 1486a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(right_reg, ToOperand(right)); 1487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(sign, instr->environment()); 1488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&left_not_zero); 1489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 14915323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org // Check for (kMinInt / -1). 14924cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)) { 149383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label left_not_min_int; 1494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(left_reg, kMinInt); 149583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_zero, &left_not_min_int, Label::kNear); 1496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(right_reg, -1); 1497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(zero, instr->environment()); 1498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&left_not_min_int); 1499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Sign extend to edx. 1502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cdq(); 1503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ idiv(right_reg); 1504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1505837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org if (instr->is_flooring()) { 15064cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Label done; 15074cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org __ test(edx, edx); 15084cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org __ j(zero, &done, Label::kNear); 15094cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org __ xor_(edx, right_reg); 15104cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org __ sar(edx, 31); 15114cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org __ add(eax, edx); 15124cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org __ bind(&done); 1513837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org } else if (!instr->hydrogen()->CheckFlag( 1514837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org HInstruction::kAllUsesTruncatingToInt32)) { 1515837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org // Deoptimize if remainder is not 0. 1516837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org __ test(edx, Operand(edx)); 1517837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org DeoptimizeIf(not_zero, instr->environment()); 15184cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 1519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1521a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1522d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.orgvoid LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { 152356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(instr->right()->IsConstantOperand()); 1524d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 152556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register dividend = ToRegister(instr->left()); 152656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right())); 1527d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org Register result = ToRegister(instr->result()); 1528d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1529d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org switch (divisor) { 1530d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org case 0: 1531d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org DeoptimizeIf(no_condition, instr->environment()); 1532d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org return; 1533d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1534d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org case 1: 1535d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ Move(result, dividend); 1536d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org return; 1537d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1538d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org case -1: 1539d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ Move(result, dividend); 1540d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ neg(result); 1541d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1542d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org DeoptimizeIf(zero, instr->environment()); 1543d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1544d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1545d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org DeoptimizeIf(overflow, instr->environment()); 1546d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1547d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org return; 1548d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1549d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1550d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org uint32_t divisor_abs = abs(divisor); 1551d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org if (IsPowerOf2(divisor_abs)) { 1552d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org int32_t power = WhichPowerOf2(divisor_abs); 1553d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org if (divisor < 0) { 1554d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org // Input[dividend] is clobbered. 1555d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org // The sequence is tedious because neg(dividend) might overflow. 1556d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ mov(result, dividend); 1557d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ sar(dividend, 31); 1558d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ neg(result); 1559d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1560d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org DeoptimizeIf(zero, instr->environment()); 1561d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1562d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ shl(dividend, 32 - power); 1563d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ sar(result, power); 1564d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ not_(dividend); 1565d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org // Clear result.sign if dividend.sign is set. 1566d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ and_(result, dividend); 1567d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } else { 1568d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ Move(result, dividend); 1569d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ sar(result, power); 1570d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1571d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } else { 157256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(ToRegister(instr->left()).is(eax)); 1573d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org ASSERT(ToRegister(instr->result()).is(edx)); 157456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register scratch = ToRegister(instr->temp()); 1575d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1576d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org // Find b which: 2^b < divisor_abs < 2^(b+1). 1577d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs); 1578d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org unsigned shift = 32 + b; // Precision +1bit (effectively). 1579d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org double multiplier_f = 1580d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs; 1581d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org int64_t multiplier; 1582d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org if (multiplier_f - floor(multiplier_f) < 0.5) { 1583d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org multiplier = static_cast<int64_t>(floor(multiplier_f)); 1584d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } else { 1585d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org multiplier = static_cast<int64_t>(floor(multiplier_f)) + 1; 1586d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1587d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org // The multiplier is a uint32. 1588d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org ASSERT(multiplier > 0 && 1589d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org multiplier < (static_cast<int64_t>(1) << 32)); 1590d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ mov(scratch, dividend); 1591d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org if (divisor < 0 && 1592d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1593d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ test(dividend, dividend); 1594d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org DeoptimizeIf(zero, instr->environment()); 1595d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1596d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ mov(edx, static_cast<int32_t>(multiplier)); 1597d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ imul(edx); 1598d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org if (static_cast<int32_t>(multiplier) < 0) { 1599d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ add(edx, scratch); 1600d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1601d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org Register reg_lo = eax; 1602d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org Register reg_byte_scratch = scratch; 1603d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org if (!reg_byte_scratch.is_byte_register()) { 1604d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ xchg(reg_lo, reg_byte_scratch); 1605d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org reg_lo = scratch; 1606d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org reg_byte_scratch = eax; 1607d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1608d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org if (divisor < 0) { 1609d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ xor_(reg_byte_scratch, reg_byte_scratch); 1610d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ cmp(reg_lo, 0x40000000); 1611d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ setcc(above, reg_byte_scratch); 1612d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ neg(edx); 1613d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ sub(edx, reg_byte_scratch); 1614d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } else { 1615d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ xor_(reg_byte_scratch, reg_byte_scratch); 1616d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ cmp(reg_lo, 0xC0000000); 1617d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ setcc(above_equal, reg_byte_scratch); 1618d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ add(edx, reg_byte_scratch); 1619d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1620d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org __ sar(edx, shift - 32); 1621d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1622d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org} 1623d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1624d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1625a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoMulI(LMulI* instr) { 162656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register left = ToRegister(instr->left()); 162756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 1628a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1629a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 163056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org __ mov(ToRegister(instr->temp()), left); 1631a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1632a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1633a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (right->IsConstantOperand()) { 1634badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // Try strength reductions on the multiplication. 1635badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // All replacement instructions are at most as long as the imul 1636badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // and have better latency. 1637badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org int constant = ToInteger32(LConstantOperand::cast(right)); 1638badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (constant == -1) { 1639badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ neg(left); 1640badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } else if (constant == 0) { 1641badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ xor_(left, Operand(left)); 1642badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } else if (constant == 2) { 1643badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ add(left, Operand(left)); 1644badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } else if (!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1645badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // If we know that the multiplication can't overflow, it's safe to 1646badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // use instructions that don't set the overflow flag for the 1647badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // multiplication. 1648badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org switch (constant) { 1649badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org case 1: 1650badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // Do nothing. 1651badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org break; 1652badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org case 3: 1653badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ lea(left, Operand(left, left, times_2, 0)); 1654badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org break; 1655badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org case 4: 1656badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ shl(left, 2); 1657badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org break; 1658badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org case 5: 1659badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ lea(left, Operand(left, left, times_4, 0)); 1660badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org break; 1661badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org case 8: 1662badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ shl(left, 3); 1663badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org break; 1664badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org case 9: 1665badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ lea(left, Operand(left, left, times_8, 0)); 1666badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org break; 1667badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org case 16: 1668badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ shl(left, 4); 1669badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org break; 1670badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org default: 1671badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ imul(left, left, constant); 1672badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org break; 1673badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } 1674badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } else { 1675badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ imul(left, left, constant); 1676badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } 1677a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 1678fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen()->representation().IsSmi()) { 1679fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ SmiUntag(left); 1680fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 1681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ imul(left, ToOperand(right)); 1682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1683a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1684a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1685a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(overflow, instr->environment()); 1686a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1687a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1688a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1689a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Bail out if the result is supposed to be negative zero. 169083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 1691a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(left, Operand(left)); 169283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_zero, &done, Label::kNear); 1693a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (right->IsConstantOperand()) { 169433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (ToInteger32(LConstantOperand::cast(right)) < 0) { 1695a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(no_condition, instr->environment()); 169633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } else if (ToInteger32(LConstantOperand::cast(right)) == 0) { 169733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org __ cmp(ToRegister(instr->temp()), Immediate(0)); 169833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org DeoptimizeIf(less, instr->environment()); 1699a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1700a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 1701a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Test the non-zero operand for negative sign. 170256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org __ or_(ToRegister(instr->temp()), ToOperand(right)); 1703a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(sign, instr->environment()); 1704a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1705a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&done); 1706a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1707a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1708a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1710a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoBitI(LBitI* instr) { 171156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 171256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 1713a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(left->Equals(instr->result())); 1714a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(left->IsRegister()); 1715a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1716a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (right->IsConstantOperand()) { 1717594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int32_t right_operand = 1718594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ToRepresentation(LConstantOperand::cast(right), 1719594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org instr->hydrogen()->representation()); 1720a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org switch (instr->op()) { 1721a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::BIT_AND: 1722a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ and_(ToRegister(left), right_operand); 1723a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1724a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::BIT_OR: 1725a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ or_(ToRegister(left), right_operand); 1726a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1727a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::BIT_XOR: 1728594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (right_operand == int32_t(~0)) { 1729594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ not_(ToRegister(left)); 1730594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 1731594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ xor_(ToRegister(left), right_operand); 1732594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 1733a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1734a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org default: 1735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org UNREACHABLE(); 1736a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1737a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1738a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 1739a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org switch (instr->op()) { 1740a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::BIT_AND: 1741a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ and_(ToRegister(left), ToOperand(right)); 1742a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1743a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::BIT_OR: 1744a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ or_(ToRegister(left), ToOperand(right)); 1745a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1746a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::BIT_XOR: 1747a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ xor_(ToRegister(left), ToOperand(right)); 1748a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1749a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org default: 1750a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org UNREACHABLE(); 1751a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1752a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1753a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1754a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1755a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1756a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1757a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoShiftI(LShiftI* instr) { 175856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 175956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 1760a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(left->Equals(instr->result())); 1761a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(left->IsRegister()); 1762a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (right->IsRegister()) { 1763a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(right).is(ecx)); 1764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org switch (instr->op()) { 1766e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case Token::ROR: 1767e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ ror_cl(ToRegister(left)); 1768e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (instr->can_deopt()) { 1769e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ test(ToRegister(left), Immediate(0x80000000)); 1770e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DeoptimizeIf(not_zero, instr->environment()); 1771e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 1772e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 1773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::SAR: 1774a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ sar_cl(ToRegister(left)); 1775a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1776a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::SHR: 1777a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ shr_cl(ToRegister(left)); 1778a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (instr->can_deopt()) { 1779a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(ToRegister(left), Immediate(0x80000000)); 1780a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(not_zero, instr->environment()); 1781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1782a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1783a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::SHL: 1784a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ shl_cl(ToRegister(left)); 1785a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1786a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org default: 1787a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org UNREACHABLE(); 1788a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1789a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1790a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 1791a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int value = ToInteger32(LConstantOperand::cast(right)); 1792a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); 1793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org switch (instr->op()) { 1794e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case Token::ROR: 1795e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (shift_count == 0 && instr->can_deopt()) { 1796e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ test(ToRegister(left), Immediate(0x80000000)); 1797e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DeoptimizeIf(not_zero, instr->environment()); 1798e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 1799e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ ror(ToRegister(left), shift_count); 1800e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 1801e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 1802a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::SAR: 1803a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (shift_count != 0) { 1804a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ sar(ToRegister(left), shift_count); 1805a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1806a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1807a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::SHR: 1808a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (shift_count == 0 && instr->can_deopt()) { 1809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(ToRegister(left), Immediate(0x80000000)); 1810a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(not_zero, instr->environment()); 1811a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 1812a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ shr(ToRegister(left), shift_count); 1813a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1814a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1815a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::SHL: 1816a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (shift_count != 0) { 1817d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen_value()->representation().IsSmi() && 1818d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org instr->can_deopt()) { 1819d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (shift_count != 1) { 1820d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ shl(ToRegister(left), shift_count - 1); 1821d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 1822d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ SmiTag(ToRegister(left)); 1823d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org DeoptimizeIf(overflow, instr->environment()); 1824d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 1825d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ shl(ToRegister(left), shift_count); 1826d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 1827a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1828a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org default: 1830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org UNREACHABLE(); 1831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 1832a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1835a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1836a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1837a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoSubI(LSubI* instr) { 183856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 183956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 1840a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(left->Equals(instr->result())); 1841a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1842a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (right->IsConstantOperand()) { 1843fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ sub(ToOperand(left), 1844fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ToImmediate(right, instr->hydrogen()->representation())); 1845a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 1846a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ sub(ToRegister(left), ToOperand(right)); 1847a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1848a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1849a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(overflow, instr->environment()); 1850a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1851a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1852a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1853a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1854a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoConstantI(LConstantI* instr) { 1855b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ Set(ToRegister(instr->result()), Immediate(instr->value())); 1856b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org} 1857b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org 1858b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org 1859b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgvoid LCodeGen::DoConstantS(LConstantS* instr) { 18609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org __ Set(ToRegister(instr->result()), Immediate(instr->value())); 1861a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1862a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1863a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1864a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoConstantD(LConstantD* instr) { 1865a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org double v = instr->value(); 1866e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint64_t int_val = BitCast<uint64_t, double>(v); 1867e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int32_t lower = static_cast<int32_t>(int_val); 1868e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); 1869e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1870e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (!CpuFeatures::IsSafeForSnapshot(SSE2)) { 1871e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ push(Immediate(upper)); 1872169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ push(Immediate(lower)); 1873169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Mov(ToX87Register(instr->result()), Operand(esp, 0)); 1874e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ add(Operand(esp), Immediate(kDoubleSize)); 1875a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 1876e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CpuFeatureScope scope1(masm(), SSE2); 1877e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(instr->result()->IsDoubleRegister()); 1878e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org XMMRegister res = ToDoubleRegister(instr->result()); 1879e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (int_val == 0) { 1880e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ xorps(res, res); 1881e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 1882e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register temp = ToRegister(instr->temp()); 1883e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (CpuFeatures::IsSupported(SSE4_1)) { 1884e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CpuFeatureScope scope2(masm(), SSE4_1); 1885e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (lower != 0) { 1886e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Set(temp, Immediate(lower)); 1887e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movd(res, Operand(temp)); 1888e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Set(temp, Immediate(upper)); 1889e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ pinsrd(res, Operand(temp), 1); 1890e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 1891e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ xorps(res, res); 1892e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Set(temp, Immediate(upper)); 1893e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ pinsrd(res, Operand(temp), 1); 1894e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 1895d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else { 1896d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ Set(temp, Immediate(upper)); 1897e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movd(res, Operand(temp)); 1898e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ psllq(res, 32); 1899e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (lower != 0) { 1900e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Set(temp, Immediate(lower)); 1901e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movd(xmm0, Operand(temp)); 1902e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ por(res, xmm0); 1903e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 1904d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1905a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1906a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1907a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1908a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1909a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1910d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid LCodeGen::DoConstantE(LConstantE* instr) { 1911d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value())); 1912d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 1913d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 1914d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 1915a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoConstantT(LConstantT* instr) { 1916c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register reg = ToRegister(instr->result()); 1917c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Handle<Object> handle = instr->value(); 191879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 1919fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ LoadObject(reg, handle); 1920a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1921a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1922a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1923355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgvoid LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1924355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Register result = ToRegister(instr->result()); 192556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register map = ToRegister(instr->value()); 1926355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ EnumLength(result, map); 1927355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org} 1928355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 1929355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 19307b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgvoid LCodeGen::DoElementsKind(LElementsKind* instr) { 19317b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org Register result = ToRegister(instr->result()); 193256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 19337b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 19347b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // Load map into |result|. 19357b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org __ mov(result, FieldOperand(input, HeapObject::kMapOffset)); 19367b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // Load the map's "bit field 2" into |result|. We only need the first byte, 19377b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // but the following masking takes care of that anyway. 19387b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org __ mov(result, FieldOperand(result, Map::kBitField2Offset)); 19397b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // Retrieve elements_kind from bit field 2. 19407b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org __ and_(result, Map::kElementsKindMask); 19417b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org __ shr(result, Map::kElementsKindShift); 19427b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org} 19437b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 19447b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 1945a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoValueOf(LValueOf* instr) { 194656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 1947a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register result = ToRegister(instr->result()); 194856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register map = ToRegister(instr->temp()); 1949a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(input.is(result)); 19504efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 195183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 19521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 19531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!instr->hydrogen()->value()->IsHeapObject()) { 19541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // If the object is a smi return the object. 19551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(input, &done, Label::kNear); 19561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 1957a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1958a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // If the object is not a value type, return the object. 1959a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ CmpObjectType(input, JS_VALUE_TYPE, map); 196083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_equal, &done, Label::kNear); 1961a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(result, FieldOperand(input, JSValue::kValueOffset)); 1962a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1963a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&done); 1964a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 1965a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1966a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 19674efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.orgvoid LCodeGen::DoDateField(LDateField* instr) { 196856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register object = ToRegister(instr->date()); 19694efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org Register result = ToRegister(instr->result()); 197056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register scratch = ToRegister(instr->temp()); 19714efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org Smi* index = instr->index(); 19724efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org Label runtime, done; 19734efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org ASSERT(object.is(result)); 19744efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org ASSERT(object.is(eax)); 19754efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 1976de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ test(object, Immediate(kSmiTagMask)); 1977de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org DeoptimizeIf(zero, instr->environment()); 19784efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ CmpObjectType(object, JS_DATE_TYPE, scratch); 1979de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org DeoptimizeIf(not_equal, instr->environment()); 19804efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 19814efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org if (index->value() == 0) { 19824efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ mov(result, FieldOperand(object, JSDate::kValueOffset)); 19834efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } else { 19844efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org if (index->value() < JSDate::kFirstUncachedField) { 19854efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); 19864efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ mov(scratch, Operand::StaticVariable(stamp)); 19874efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ cmp(scratch, FieldOperand(object, JSDate::kCacheStampOffset)); 19884efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ j(not_equal, &runtime, Label::kNear); 19894efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ mov(result, FieldOperand(object, JSDate::kValueOffset + 19904efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org kPointerSize * index->value())); 19914efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ jmp(&done); 19924efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 19934efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ bind(&runtime); 19944efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ PrepareCallCFunction(2, scratch); 19954efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ mov(Operand(esp, 0), object); 19964efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ mov(Operand(esp, 1 * kPointerSize), Immediate(index)); 19974efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 19984efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ bind(&done); 19994efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 20004efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org} 20014efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 20024efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 200332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.orgvoid LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { 2004a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register string = ToRegister(instr->string()); 2005a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register index = ToRegister(instr->index()); 2006a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register value = ToRegister(instr->value()); 2007a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org String::Encoding encoding = instr->encoding(); 2008a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 2009a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (FLAG_debug_code) { 2010a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ push(value); 2011a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ mov(value, FieldOperand(string, HeapObject::kMapOffset)); 2012a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ movzx_b(value, FieldOperand(value, Map::kInstanceTypeOffset)); 2013a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 2014a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ and_(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); 2015a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 2016a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 2017a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ cmp(value, Immediate(encoding == String::ONE_BYTE_ENCODING 2018a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ? one_byte_seq_type : two_byte_seq_type)); 2019594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Check(equal, kUnexpectedStringType); 2020a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ pop(value); 2021a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 2022a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 2023a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (encoding == String::ONE_BYTE_ENCODING) { 2024a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ mov_b(FieldOperand(string, index, times_1, SeqString::kHeaderSize), 2025a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org value); 2026a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } else { 2027a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ mov_w(FieldOperand(string, index, times_2, SeqString::kHeaderSize), 2028a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org value); 2029a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 203032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org} 203132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 203232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 2033a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoThrow(LThrow* instr) { 2034ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org __ push(ToOperand(instr->value())); 2035ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 2036ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallRuntime(Runtime::kThrow, 1, instr); 2037a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2038a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (FLAG_debug_code) { 2039a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Comment("Unreachable code."); 2040a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ int3(); 2041a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2042a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2043a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2044a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2045a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoAddI(LAddI* instr) { 204656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 204756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 2048a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2049906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { 2050906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (right->IsConstantOperand()) { 2051fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org int32_t offset = ToRepresentation(LConstantOperand::cast(right), 2052fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org instr->hydrogen()->representation()); 2053906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset)); 2054906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else { 2055906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org Operand address(ToRegister(left), ToRegister(right), times_1, 0); 2056906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org __ lea(ToRegister(instr->result()), address); 2057906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 2058a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 2059906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (right->IsConstantOperand()) { 2060fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ add(ToOperand(left), 2061fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ToImmediate(right, instr->hydrogen()->representation())); 2062906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else { 2063906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org __ add(ToRegister(left), ToOperand(right)); 2064906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 2065906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 2066906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org DeoptimizeIf(overflow, instr->environment()); 2067906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 2068a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2069a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2070a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2071a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2072471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid LCodeGen::DoMathMinMax(LMathMinMax* instr) { 2073750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 207456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 207556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 2076471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ASSERT(left->Equals(instr->result())); 2077471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org HMathMinMax::Operation operation = instr->hydrogen()->operation(); 2078fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen()->representation().IsSmiOrInteger32()) { 2079471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Label return_left; 2080471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Condition condition = (operation == HMathMinMax::kMathMin) 2081471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ? less_equal 2082471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org : greater_equal; 2083471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (right->IsConstantOperand()) { 2084471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Operand left_op = ToOperand(left); 2085fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Immediate immediate = ToImmediate(LConstantOperand::cast(instr->right()), 2086fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org instr->hydrogen()->representation()); 2087fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ cmp(left_op, immediate); 2088471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(condition, &return_left, Label::kNear); 2089fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ mov(left_op, immediate); 2090471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 2091471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Register left_reg = ToRegister(left); 2092471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Operand right_op = ToOperand(right); 2093471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ cmp(left_reg, right_op); 2094471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(condition, &return_left, Label::kNear); 2095471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ mov(left_reg, right_op); 2096471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 2097471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&return_left); 2098471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 2099471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ASSERT(instr->hydrogen()->representation().IsDouble()); 2100471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Label check_nan_left, check_zero, return_left, return_right; 2101471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; 2102471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org XMMRegister left_reg = ToDoubleRegister(left); 2103471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org XMMRegister right_reg = ToDoubleRegister(right); 2104471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ ucomisd(left_reg, right_reg); 2105471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN. 2106471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(equal, &check_zero, Label::kNear); // left == right. 2107471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(condition, &return_left, Label::kNear); 2108471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ jmp(&return_right, Label::kNear); 2109471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 2110471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&check_zero); 2111471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org XMMRegister xmm_scratch = xmm0; 2112471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ xorps(xmm_scratch, xmm_scratch); 2113471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ ucomisd(left_reg, xmm_scratch); 2114471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(not_equal, &return_left, Label::kNear); // left == right != 0. 2115471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // At this point, both left and right are either 0 or -0. 2116471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (operation == HMathMinMax::kMathMin) { 2117471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ orpd(left_reg, right_reg); 2118471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 2119471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // Since we operate on +0 and/or -0, addsd and andsd have the same effect. 2120471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ addsd(left_reg, right_reg); 2121471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 2122471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ jmp(&return_left, Label::kNear); 2123471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 2124471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&check_nan_left); 2125471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ ucomisd(left_reg, left_reg); // NaN check. 2126471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(parity_even, &return_left, Label::kNear); // left == NaN. 2127471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&return_right); 2128471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ movsd(left_reg, right_reg); 2129471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 2130471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&return_left); 2131471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 2132471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org} 2133471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 2134471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 2135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoArithmeticD(LArithmeticD* instr) { 2136169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 2137169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org CpuFeatureScope scope(masm(), SSE2); 2138169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org XMMRegister left = ToDoubleRegister(instr->left()); 2139169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org XMMRegister right = ToDoubleRegister(instr->right()); 2140169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org XMMRegister result = ToDoubleRegister(instr->result()); 2141169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Modulo uses a fixed result register. 2142169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(instr->op() == Token::MOD || left.is(result)); 2143169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org switch (instr->op()) { 2144169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org case Token::ADD: 2145169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ addsd(left, right); 2146169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org break; 2147169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org case Token::SUB: 2148169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ subsd(left, right); 2149169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org break; 2150169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org case Token::MUL: 2151169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ mulsd(left, right); 2152169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org break; 2153169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org case Token::DIV: 2154169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ divsd(left, right); 2155169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Don't delete this mov. It may improve performance on some CPUs, 2156169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // when there is a mulsd depending on the result 2157169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ movaps(left, left); 2158169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org break; 2159169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org case Token::MOD: { 2160169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Pass two doubles as arguments on the stack. 2161169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ PrepareCallCFunction(4, eax); 2162169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ movdbl(Operand(esp, 0 * kDoubleSize), left); 2163169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ movdbl(Operand(esp, 1 * kDoubleSize), right); 2164169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ CallCFunction( 2165169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ExternalReference::double_fp_operation(Token::MOD, isolate()), 2166169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 4); 2167169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 2168169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Return value is in st(0) on ia32. 2169169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Store it into the (fixed) result register. 2170169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ sub(Operand(esp), Immediate(kDoubleSize)); 2171169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fstp_d(Operand(esp, 0)); 2172169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ movdbl(result, Operand(esp, 0)); 2173169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ add(Operand(esp), Immediate(kDoubleSize)); 2174169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org break; 2175169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 2176169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org default: 2177169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org UNREACHABLE(); 2178169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org break; 2179169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 2180169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } else { 2181169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Register left = ToX87Register(instr->left()); 2182169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Register right = ToX87Register(instr->right()); 2183169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Register result = ToX87Register(instr->result()); 2184169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87PrepareBinaryOp(left, right, result); 2185169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org switch (instr->op()) { 2186169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org case Token::MUL: 2187169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fmul_i(1); 2188169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org break; 2189169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org default: 2190169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org UNREACHABLE(); 2191169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org break; 2192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2194a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2195a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2196a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2197a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoArithmeticT(LArithmeticT* instr) { 2198ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 2199ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org ASSERT(ToRegister(instr->left()).is(edx)); 2200ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org ASSERT(ToRegister(instr->right()).is(eax)); 2201a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 2202a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 220340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org BinaryOpStub stub(instr->op(), NO_OVERWRITE); 22048432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 2205030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org __ nop(); // Signals no inlined code. 2206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2208a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 220932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.orgint LCodeGen::GetNextEmittedBlock() const { 221077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { 221177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (!chunk_->GetLabel(i)->HasReplacement()) return i; 2212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return -1; 2214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 22171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<class InstrType> 22181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid LCodeGen::EmitBranch(InstrType instr, Condition cc) { 22191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org int left_block = instr->TrueDestination(chunk_); 2220e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org int right_block = instr->FalseDestination(chunk_); 22211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 222277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org int next_block = GetNextEmittedBlock(); 2223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2224e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (right_block == left_block || cc == no_condition) { 2225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org EmitGoto(left_block); 2226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (left_block == next_block) { 2227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ j(NegateCondition(cc), chunk_->GetAssemblyLabel(right_block)); 2228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (right_block == next_block) { 2229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ j(cc, chunk_->GetAssemblyLabel(left_block)); 2230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 2231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ j(cc, chunk_->GetAssemblyLabel(left_block)); 2232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ jmp(chunk_->GetAssemblyLabel(right_block)); 2233a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2237c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.orgtemplate<class InstrType> 2238c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.orgvoid LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) { 2239c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org int false_block = instr->FalseDestination(chunk_); 2240c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (cc == no_condition) { 2241c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ jmp(chunk_->GetAssemblyLabel(false_block)); 2242c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } else { 2243c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ j(cc, chunk_->GetAssemblyLabel(false_block)); 2244c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } 2245c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org} 2246c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 2247c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 2248e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgvoid LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) { 2249e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Representation r = instr->hydrogen()->value()->representation(); 2250e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (r.IsSmiOrInteger32() || r.IsDouble()) { 2251e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org EmitBranch(instr, no_condition); 2252e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } else { 2253e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org ASSERT(r.IsTagged()); 2254e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Register reg = ToRegister(instr->value()); 2255e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org HType type = instr->hydrogen()->value()->type(); 2256e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (type.IsTaggedNumber()) { 2257e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org EmitBranch(instr, no_condition); 2258e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } 2259e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); 2260e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 2261e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org factory()->heap_number_map()); 2262e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org EmitBranch(instr, equal); 2263e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } 2264e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org} 2265e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 2266e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 2267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoBranch(LBranch* instr) { 22684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Representation r = instr->hydrogen()->value()->representation(); 226953ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (r.IsSmiOrInteger32()) { 2270b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(!info()->IsStub()); 227156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register reg = ToRegister(instr->value()); 2272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(reg, Operand(reg)); 22731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_zero); 2274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (r.IsDouble()) { 2275b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(!info()->IsStub()); 2276b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org CpuFeatureScope scope(masm(), SSE2); 227756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister reg = ToDoubleRegister(instr->value()); 2278fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org __ xorps(xmm0, xmm0); 2279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ucomisd(reg, xmm0); 22801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_equal); 2281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 2282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(r.IsTagged()); 228356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register reg = ToRegister(instr->value()); 2284d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org HType type = instr->hydrogen()->value()->type(); 2285d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (type.IsBoolean()) { 2286b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(!info()->IsStub()); 2287ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmp(reg, factory()->true_value()); 22881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 2289d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } else if (type.IsSmi()) { 2290b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(!info()->IsStub()); 2291d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ test(reg, Operand(reg)); 22921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_equal); 22931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (type.IsJSArray()) { 22941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(!info()->IsStub()); 22951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, no_condition); 22961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (type.IsHeapNumber()) { 22971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(!info()->IsStub()); 22981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org CpuFeatureScope scope(masm(), SSE2); 22991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ xorps(xmm0, xmm0); 23001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); 23011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_equal); 23021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (type.IsString()) { 23031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(!info()->IsStub()); 23041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); 23051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_equal); 2306a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 23077943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 23081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); 23097943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org 23107943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org if (expected.Contains(ToBooleanStub::UNDEFINED)) { 23117943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org // undefined -> false. 23127943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ cmp(reg, factory()->undefined_value()); 23131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(equal, instr->FalseLabel(chunk_)); 23147943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org } 23157943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org if (expected.Contains(ToBooleanStub::BOOLEAN)) { 23167943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org // true -> true. 23177943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ cmp(reg, factory()->true_value()); 23181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(equal, instr->TrueLabel(chunk_)); 23197943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org // false -> false. 23207943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ cmp(reg, factory()->false_value()); 23211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(equal, instr->FalseLabel(chunk_)); 23227943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org } 23237943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org if (expected.Contains(ToBooleanStub::NULL_TYPE)) { 23247943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org // 'null' -> false. 23257943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ cmp(reg, factory()->null_value()); 23261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(equal, instr->FalseLabel(chunk_)); 23277943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org } 23287943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org 23297943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org if (expected.Contains(ToBooleanStub::SMI)) { 23307943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org // Smis: 0 -> false, all other -> true. 23317943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ test(reg, Operand(reg)); 23321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(equal, instr->FalseLabel(chunk_)); 23331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); 23347943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org } else if (expected.NeedsMap()) { 23357943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org // If we need a map later and have a Smi -> deopt. 23367943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ test(reg, Immediate(kSmiTagMask)); 23377943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org DeoptimizeIf(zero, instr->environment()); 23387943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org } 23397943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org 23404acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Register map = no_reg; // Keep the compiler happy. 23417943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org if (expected.NeedsMap()) { 234256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org map = ToRegister(instr->temp()); 23437943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org ASSERT(!map.is(reg)); 23447943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ mov(map, FieldOperand(reg, HeapObject::kMapOffset)); 23454acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 23464acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (expected.CanBeUndetectable()) { 23474acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Undetectable -> false. 23484acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ test_b(FieldOperand(map, Map::kBitFieldOffset), 23494acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 1 << Map::kIsUndetectable); 23501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(not_zero, instr->FalseLabel(chunk_)); 23514acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 23527943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org } 23537943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org 23547943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { 23557943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org // spec object -> true. 23567943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 23571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(above_equal, instr->TrueLabel(chunk_)); 23587943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org } 23597943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org 23607943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org if (expected.Contains(ToBooleanStub::STRING)) { 23617943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org // String value -> false iff empty. 23627943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org Label not_string; 23637943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); 23647943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ j(above_equal, ¬_string, Label::kNear); 23657943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); 23661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(not_zero, instr->TrueLabel(chunk_)); 23671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ jmp(instr->FalseLabel(chunk_)); 23687943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ bind(¬_string); 23697943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org } 23707943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org 2371f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org if (expected.Contains(ToBooleanStub::SYMBOL)) { 2372f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Symbol value -> true. 2373f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ CmpInstanceType(map, SYMBOL_TYPE); 23741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(equal, instr->TrueLabel(chunk_)); 2375f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } 2376f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 23777943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 23787943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org // heap number -> false iff +0, -0, or NaN. 23797943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org Label not_heap_number; 23807943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 23817943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org factory()->heap_number_map()); 23827943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ j(not_equal, ¬_heap_number, Label::kNear); 2383b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 2384b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org CpuFeatureScope scope(masm(), SSE2); 2385b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ xorps(xmm0, xmm0); 2386b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); 2387b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org } else { 2388b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ fldz(); 2389b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); 2390b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ FCmp(); 2391b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org } 23921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(zero, instr->FalseLabel(chunk_)); 23931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ jmp(instr->TrueLabel(chunk_)); 23947943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org __ bind(¬_heap_number); 23957943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org } 23967943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org 23971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!expected.IsGeneric()) { 23981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // We've seen something for the first time -> deopt. 23991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // This can only happen if we are not generic already. 24001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org DeoptimizeIf(no_condition, instr->environment()); 24011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 2402a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2403a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2404a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2405a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2406a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 240704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgvoid LCodeGen::EmitGoto(int block) { 240832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (!IsNextEmittedBlock(block)) { 24091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block))); 2410a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2411a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2412a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2413a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2414a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoGoto(LGoto* instr) { 241504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org EmitGoto(instr->block_id()); 2416a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2417a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2418a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2419a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgCondition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { 2420a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Condition cond = no_condition; 2421a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org switch (op) { 2422a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::EQ: 2423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::EQ_STRICT: 2424a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org cond = equal; 2425a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 2426a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::LT: 2427a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org cond = is_unsigned ? below : less; 2428a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 2429a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::GT: 2430a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org cond = is_unsigned ? above : greater; 2431a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 2432a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::LTE: 2433a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org cond = is_unsigned ? below_equal : less_equal; 2434a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 2435a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::GTE: 2436a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org cond = is_unsigned ? above_equal : greater_equal; 2437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 2438a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::IN: 2439a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case Token::INSTANCEOF: 2440a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org default: 2441a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org UNREACHABLE(); 2442a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return cond; 2444a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2445a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2446a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2447e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgvoid LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { 244856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 244956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 2450394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Condition cc = TokenToCondition(instr->op(), instr->is_double()); 2451a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2452394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (left->IsConstantOperand() && right->IsConstantOperand()) { 2453394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // We can statically evaluate the comparison. 2454394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com double left_val = ToDouble(LConstantOperand::cast(left)); 2455394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com double right_val = ToDouble(LConstantOperand::cast(right)); 24561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org int next_block = EvalComparison(instr->op(), left_val, right_val) ? 24571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_); 2458394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EmitGoto(next_block); 2459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 2460394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (instr->is_double()) { 2461750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 2462394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Don't base result on EFLAGS when a NaN is involved. Instead 2463394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // jump to the false block. 2464394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); 24651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(parity_even, instr->FalseLabel(chunk_)); 2466394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 2467394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (right->IsConstantOperand()) { 2468fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ cmp(ToOperand(left), 2469fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ToImmediate(right, instr->hydrogen()->representation())); 2470394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else if (left->IsConstantOperand()) { 2471fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ cmp(ToOperand(right), 2472fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ToImmediate(left, instr->hydrogen()->representation())); 2473394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // We transposed the operands. Reverse the condition. 2474394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com cc = ReverseCondition(cc); 2475394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 2476394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ cmp(ToRegister(left), ToOperand(right)); 2477394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 2478394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 24791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, cc); 2480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2484ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.orgvoid LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 248556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register left = ToRegister(instr->left()); 24867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2487b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (instr->right()->IsConstantOperand()) { 2488a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); 2489a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ CmpObject(left, right); 2490b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } else { 2491b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org Operand right = ToOperand(instr->right()); 2492a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ cmp(left, right); 2493b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 24941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 24957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 24967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 24977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2498c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.orgvoid LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) { 2499c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (instr->hydrogen()->representation().IsTagged()) { 2500c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org Register input_reg = ToRegister(instr->object()); 2501c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ cmp(input_reg, factory()->the_hole_value()); 2502c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org EmitBranch(instr, equal); 2503c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org return; 2504c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } 2505c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 2506c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org bool use_sse2 = CpuFeatures::IsSupported(SSE2); 2507c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (use_sse2) { 2508c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org CpuFeatureScope scope(masm(), SSE2); 2509c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->object()); 2510c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ ucomisd(input_reg, input_reg); 2511c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org EmitFalseBranch(instr, parity_odd); 2512c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } else { 2513c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org // Put the value to the top of stack 2514c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org X87Register src = ToX87Register(instr->object()); 2515c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org X87LoadForUsage(src); 2516c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ fld(0); 2517c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ fld(0); 2518c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ FCmp(); 2519c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org Label ok; 2520c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ j(parity_even, &ok); 2521c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ fstp(0); 2522c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org EmitFalseBranch(instr, no_condition); 2523c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ bind(&ok); 2524c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } 2525c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 2526c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 2527c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ sub(esp, Immediate(kDoubleSize)); 2528c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (use_sse2) { 2529c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org CpuFeatureScope scope(masm(), SSE2); 2530c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->object()); 2531c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ movdbl(MemOperand(esp, 0), input_reg); 2532c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } else { 2533c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ fstp_d(MemOperand(esp, 0)); 2534c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } 2535c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 2536c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ add(esp, Immediate(kDoubleSize)); 2537c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org int offset = sizeof(kHoleNanUpper32); 2538c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ cmp(MemOperand(esp, -offset), Immediate(kHoleNanUpper32)); 2539c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org EmitBranch(instr, equal); 2540c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org} 2541c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 2542c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 25435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgCondition LCodeGen::EmitIsObject(Register input, 25445f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Register temp1, 25455f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Label* is_not_object, 25465f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Label* is_object) { 25477b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org __ JumpIfSmi(input, is_not_object); 25485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 2549ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmp(input, isolate()->factory()->null_value()); 25505f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org __ j(equal, is_object); 25515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 25525f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org __ mov(temp1, FieldOperand(input, HeapObject::kMapOffset)); 25535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Undetectable objects behave like undefined. 25543cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org __ test_b(FieldOperand(temp1, Map::kBitFieldOffset), 25553cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 1 << Map::kIsUndetectable); 25565f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org __ j(not_zero, is_not_object); 25575f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 25583cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org __ movzx_b(temp1, FieldOperand(temp1, Map::kInstanceTypeOffset)); 25593cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org __ cmp(temp1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); 25605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org __ j(below, is_not_object); 25613cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org __ cmp(temp1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 25625f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org return below_equal; 25635f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 25645f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 25655f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 25665f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 256756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register reg = ToRegister(instr->value()); 256856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 25695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 25701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Condition true_cond = EmitIsObject( 25711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org reg, temp, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_)); 25725f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 25731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, true_cond); 25745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 25755f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 25765f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 25770ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryCondition LCodeGen::EmitIsString(Register input, 25780ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Register temp1, 25791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label* is_not_string, 25801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org SmiCheck check_needed = INLINE_SMI_CHECK) { 25811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (check_needed == INLINE_SMI_CHECK) { 25821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(input, is_not_string); 25831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 25840ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 25850ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Condition cond = masm_->IsObjectStringType(input, temp1, temp1); 25860ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 25870ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry return cond; 25880ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry} 25890ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 25900ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 25910ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 259256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register reg = ToRegister(instr->value()); 259356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 25940ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 25951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org SmiCheck check_needed = 25961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->hydrogen()->value()->IsHeapObject() 25971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 25980ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 25991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Condition true_cond = EmitIsString( 26001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org reg, temp, instr->FalseLabel(chunk_), check_needed); 26010ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 26021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, true_cond); 26030ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry} 26040ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 26050ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 2606a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 260756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Operand input = ToOperand(instr->value()); 2608a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2609a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(input, Immediate(kSmiTagMask)); 26101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, zero); 2611a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2612a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2613a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 26147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgvoid LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 261556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 261656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 26177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 26181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!instr->hydrogen()->value()->IsHeapObject()) { 26191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org STATIC_ASSERT(kSmiTag == 0); 26201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(input, instr->FalseLabel(chunk_)); 26211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 26227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 26237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ test_b(FieldOperand(temp, Map::kBitFieldOffset), 26247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1 << Map::kIsUndetectable); 26251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_zero); 26267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 26277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 26287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 26290ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorrystatic Condition ComputeCompareCondition(Token::Value op) { 26300ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry switch (op) { 26310ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry case Token::EQ_STRICT: 26320ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry case Token::EQ: 26330ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry return equal; 26340ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry case Token::LT: 26350ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry return less; 26360ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry case Token::GT: 26370ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry return greater; 26380ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry case Token::LTE: 26390ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry return less_equal; 26400ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry case Token::GTE: 26410ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry return greater_equal; 26420ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry default: 26430ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry UNREACHABLE(); 26440ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry return no_condition; 26450ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry } 26460ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry} 26470ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 26480ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 26490ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { 26500ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Token::Value op = instr->op(); 26510ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 26528432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 26530ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry CallCode(ic, RelocInfo::CODE_TARGET, instr); 26540ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 26550ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Condition condition = ComputeCompareCondition(op); 26560ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ test(eax, Operand(eax)); 26570ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 26581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, condition); 26590ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry} 26600ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 26610ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 26624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgstatic InstanceType TestType(HHasInstanceTypeAndBranch* instr) { 26630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com InstanceType from = instr->from(); 26640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com InstanceType to = instr->to(); 2665a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (from == FIRST_TYPE) return to; 2666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(from == to || to == LAST_TYPE); 2667a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return from; 2668a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2669a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2670a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 26714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgstatic Condition BranchCondition(HHasInstanceTypeAndBranch* instr) { 26720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com InstanceType from = instr->from(); 26730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com InstanceType to = instr->to(); 2674a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (from == to) return equal; 2675a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (to == LAST_TYPE) return above_equal; 2676a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (from == FIRST_TYPE) return below_equal; 2677a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org UNREACHABLE(); 2678a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return equal; 2679a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2680a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 268356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 268456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 2685a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 26861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!instr->hydrogen()->value()->IsHeapObject()) { 26871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(input, instr->FalseLabel(chunk_)); 26881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 2689a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 26900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __ CmpObjectType(input, TestType(instr->hydrogen()), temp); 26911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, BranchCondition(instr->hydrogen())); 2692a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2693a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2694a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 26958f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.orgvoid LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 269656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 26978f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org Register result = ToRegister(instr->result()); 26988f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 2699c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ AssertString(input); 27008f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 27018f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ mov(result, FieldOperand(input, String::kHashFieldOffset)); 27028f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ IndexFromHash(result, result); 27038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org} 27048f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 27058f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 2706a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoHasCachedArrayIndexAndBranch( 2707a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LHasCachedArrayIndexAndBranch* instr) { 270856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 2709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2710a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(FieldOperand(input, String::kHashFieldOffset), 2711a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Immediate(String::kContainsCachedArrayIndexMask)); 27121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 2713a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2714a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2715a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2716a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Branches to a label or falls through with the answer in the z flag. Trashes 2717f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// the temp registers, but not the input. 2718a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::EmitClassOfTest(Label* is_true, 2719a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Label* is_false, 2720a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Handle<String>class_name, 2721a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register input, 2722a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register temp, 2723a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register temp2) { 2724a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!input.is(temp)); 2725f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ASSERT(!input.is(temp2)); 2726f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ASSERT(!temp.is(temp2)); 27277b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org __ JumpIfSmi(input, is_false); 2728a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 272959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Function"))) { 2730c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Assuming the following assertions, we can use the same compares to test 2731c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // for both being a function type and being in the object type range. 2732c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 2733c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == 2734c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FIRST_SPEC_OBJECT_TYPE + 1); 2735c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == 2736c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LAST_SPEC_OBJECT_TYPE - 1); 2737c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); 2738c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, temp); 2739c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ j(below, is_false); 2740c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ j(equal, is_true); 2741c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CmpInstanceType(temp, LAST_SPEC_OBJECT_TYPE); 2742c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ j(equal, is_true); 2743a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 2744c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Faster code path to avoid two compares: subtract lower bound from the 2745c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // actual type and do a signed compare with the width of the type range. 2746c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 274756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ movzx_b(temp2, FieldOperand(temp, Map::kInstanceTypeOffset)); 2748c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(Operand(temp2), Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 274956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ cmp(Operand(temp2), Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - 275056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2751c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ j(above, is_false); 2752a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2753a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2754c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range. 2755a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Check if the constructor in the map is a function. 2756a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(temp, FieldOperand(temp, Map::kConstructorOffset)); 2757a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Objects with a non-function constructor have class 'Object'. 2758a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ CmpObjectType(temp, JS_FUNCTION_TYPE, temp2); 275959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Object"))) { 2760a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ j(not_equal, is_true); 2761a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 2762a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ j(not_equal, is_false); 2763a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // temp now contains the constructor function. Grab the 2766a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // instance class name from there. 2767a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(temp, FieldOperand(temp, JSFunction::kSharedFunctionInfoOffset)); 2768a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(temp, FieldOperand(temp, 2769a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SharedFunctionInfo::kInstanceClassNameOffset)); 27704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // The class name we are testing against is internalized since it's a literal. 27714a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // The name in the constructor is internalized because of the way the context 27724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // is booted. This routine isn't expected to work for random API-created 2773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // classes and it doesn't have to because you can't access it with natives 27744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // syntax. Since both sides are internalized it is sufficient to use an 27754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // identity comparison. 2776a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(temp, class_name); 2777a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // End with the answer in the z flag. 2778a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2779a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2780a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 278256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 278356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 278456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp2 = ToRegister(instr->temp2()); 2785f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 2786a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Handle<String> class_name = instr->hydrogen()->class_name(); 2787a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 27881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), 27891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org class_name, input, temp, temp2); 2790a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 27911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 2792a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2794a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2795a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 279656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register reg = ToRegister(instr->value()); 2797a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 27981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 2799a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2800a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2801a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2802a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2803d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Object and function are in fixed registers defined by the stub. 2804496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 28055f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org InstanceofStub stub(InstanceofStub::kArgsInRegisters); 28068432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 2807a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 280883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label true_value, done; 2809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(eax, Operand(eax)); 281083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(zero, &true_value, Label::kNear); 2811ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ mov(ToRegister(instr->result()), factory()->false_value()); 281283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 2813a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&true_value); 2814ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ mov(ToRegister(instr->result()), factory()->true_value()); 2815a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&done); 2816a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2817a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2818a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2819d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.orgvoid LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { 2820d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org class DeferredInstanceOfKnownGlobal: public LDeferredCode { 2821d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org public: 2822d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org DeferredInstanceOfKnownGlobal(LCodeGen* codegen, 2823d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org LInstanceOfKnownGlobal* instr) 2824d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org : LDeferredCode(codegen), instr_(instr) { } 2825d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org virtual void Generate() { 282627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_); 2827d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 2828c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual LInstruction* instr() { return instr_; } 2829d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Label* map_check() { return &map_check_; } 2830d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org private: 2831d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org LInstanceOfKnownGlobal* instr_; 2832d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Label map_check_; 2833d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org }; 2834d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 2835d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org DeferredInstanceOfKnownGlobal* deferred; 28367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); 2837d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 2838d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Label done, false_result; 283956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register object = ToRegister(instr->value()); 284056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 2841d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 284249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // A Smi is not an instance of anything. 28437b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org __ JumpIfSmi(object, &false_result); 2844d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 284549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // This is the inlined call site instanceof cache. The two occurences of the 2846d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // hole value will be patched to the last map/result pair generated by the 2847d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // instanceof stub. 284883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label cache_miss; 284956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register map = ToRegister(instr->temp()); 2850d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); 2851d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ bind(deferred->map_check()); // Label for calculating code patching. 285241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cache_cell = factory()->NewCell(factory()->the_hole_value()); 285341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ cmp(map, Operand::ForCell(cache_cell)); // Patched to cached map. 28547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ j(not_equal, &cache_miss, Label::kNear); 2855ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ mov(eax, factory()->the_hole_value()); // Patched to either true or false. 2856d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ jmp(&done); 2857d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 285849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // The inlined call site cache did not match. Check for null and string 285949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // before calling the deferred code. 2860d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ bind(&cache_miss); 286149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Null is not an instance of anything. 2862ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmp(object, factory()->null_value()); 2863d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ j(equal, &false_result); 2864d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 2865d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // String values are not instances of anything. 2866d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Condition is_string = masm_->IsObjectStringType(object, temp, temp); 2867d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ j(is_string, &false_result); 2868d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 2869d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Go to the deferred code. 2870d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ jmp(deferred->entry()); 2871d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 2872d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ bind(&false_result); 2873ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ mov(ToRegister(instr->result()), factory()->false_value()); 2874d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 2875d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Here result has either true or false. Deferred code also produces true or 2876d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // false object. 2877d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ bind(deferred->exit()); 2878d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ bind(&done); 2879d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org} 2880d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 2881d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 288227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 288327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Label* map_check) { 288444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 2885d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 2886d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org InstanceofStub::Flags flags = InstanceofStub::kNoFlags; 2887d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org flags = static_cast<InstanceofStub::Flags>( 2888d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org flags | InstanceofStub::kArgsInRegisters); 2889d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org flags = static_cast<InstanceofStub::Flags>( 2890d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org flags | InstanceofStub::kCallSiteInlineCheck); 2891d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org flags = static_cast<InstanceofStub::Flags>( 2892d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org flags | InstanceofStub::kReturnTrueFalseObject); 2893d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org InstanceofStub stub(flags); 2894d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 289544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // Get the temp register reserved by the instruction. This needs to be a 289644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // register which is pushed last by PushSafepointRegisters as top of the 289744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // stack is used to pass the offset to the location of the map check to 289844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // the stub. 289956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 290044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0); 290164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ LoadHeapObject(InstanceofStub::right(), instr->function()); 2902ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org static const int kAdditionalDelta = 13; 2903d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 2904d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ mov(temp, Immediate(delta)); 29053a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ StoreToSafepointRegisterSlot(temp, temp); 29068432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCodeGeneric(stub.GetCode(isolate()), 290744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org RelocInfo::CODE_TARGET, 290844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org instr, 290944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 29101044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org // Get the deoptimization index of the LLazyBailout-environment that 29111044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org // corresponds to this instruction. 29121044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); 291327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 291427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org 2915d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Put the result value into the eax slot and restore all registers. 29163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ StoreToSafepointRegisterSlot(eax, eax); 2917d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org} 2918d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 2919d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 292071fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgvoid LCodeGen::DoInstanceSize(LInstanceSize* instr) { 292171fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org Register object = ToRegister(instr->object()); 292271fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org Register result = ToRegister(instr->result()); 292371fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org __ mov(result, FieldOperand(object, HeapObject::kMapOffset)); 292471fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org __ movzx_b(result, FieldOperand(result, Map::kInstanceSizeOffset)); 292571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org} 292671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org 292771fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org 2928a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCmpT(LCmpT* instr) { 2929a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Token::Value op = instr->op(); 2930a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 29318432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 2932ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 2933a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2934a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Condition condition = ComputeCompareCondition(op); 293583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label true_value, done; 2936a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(eax, Operand(eax)); 293783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(condition, &true_value, Label::kNear); 2938ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ mov(ToRegister(instr->result()), factory()->false_value()); 293983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 2940a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&true_value); 2941ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ mov(ToRegister(instr->result()), factory()->true_value()); 2942a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&done); 2943a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2944a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2945a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 29466e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgvoid LCodeGen::EmitReturn(LReturn* instr, bool dynamic_frame_alignment) { 29476e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org int extra_value_count = dynamic_frame_alignment ? 2 : 1; 29486e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 29496e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org if (instr->has_constant_parameter_count()) { 29506e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org int parameter_count = ToInteger32(instr->constant_parameter_count()); 29516e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org if (dynamic_frame_alignment && FLAG_debug_code) { 29526e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ cmp(Operand(esp, 29536e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org (parameter_count + extra_value_count) * kPointerSize), 29546e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Immediate(kAlignmentZapValue)); 2955594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(equal, kExpectedAlignmentMarker); 29566e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } 29576e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ Ret((parameter_count + extra_value_count) * kPointerSize, ecx); 29586e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } else { 29596e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Register reg = ToRegister(instr->parameter_count()); 2960ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // The argument count parameter is a smi 2961ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ SmiUntag(reg); 29626e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Register return_addr_reg = reg.is(ecx) ? ebx : ecx; 29636e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org if (dynamic_frame_alignment && FLAG_debug_code) { 29646e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org ASSERT(extra_value_count == 2); 29656e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ cmp(Operand(esp, reg, times_pointer_size, 29666e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org extra_value_count * kPointerSize), 29676e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Immediate(kAlignmentZapValue)); 2968594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(equal, kExpectedAlignmentMarker); 29696e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } 29706e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 29716e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // emit code to restore stack based on instr->parameter_count() 29726e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ pop(return_addr_reg); // save return address 29736e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org if (dynamic_frame_alignment) { 29746e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ inc(reg); // 1 more for alignment 29756e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } 29766e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ shl(reg, kPointerSizeLog2); 29776e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ add(esp, reg); 29786e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ jmp(return_addr_reg); 29796e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } 29806e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org} 29816e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 29826e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 2983a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoReturn(LReturn* instr) { 2984a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (FLAG_trace && info()->IsOptimizing()) { 2985496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Preserve the return value on the stack and rely on the runtime call 2986496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // to return the value in the same register. We're leaving the code 2987496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // managed by the register allocator and tearing down the frame, it's 2988496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // safe to write to the context register. 2989a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(eax); 2990496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2991a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ CallRuntime(Runtime::kTraceExit, 1); 2992a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 299394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { 299494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ASSERT(NeedsEagerFrame()); 2995750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 299694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org BitVector* doubles = chunk()->allocated_double_registers(); 299794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org BitVector::Iterator save_iterator(doubles); 299894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org int count = 0; 299994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org while (!save_iterator.Done()) { 300094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ movdbl(XMMRegister::FromAllocationIndex(save_iterator.Current()), 300194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org MemOperand(esp, count * kDoubleSize)); 300294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org save_iterator.Advance(); 300394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org count++; 300494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 300594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 30067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (dynamic_frame_alignment_) { 30077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Fetch the state of the dynamic frame alignment. 30087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ mov(edx, Operand(ebp, 30097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org JavaScriptFrameConstants::kDynamicAlignmentStateOffset)); 30107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 30114e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org int no_frame_start = -1; 3012a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (NeedsEagerFrame()) { 3013a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ mov(esp, ebp); 3014a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ pop(ebp); 30154e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org no_frame_start = masm_->pc_offset(); 3016a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 30177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (dynamic_frame_alignment_) { 30187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label no_padding; 30197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ cmp(edx, Immediate(kNoAlignmentPadding)); 30207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ j(equal, &no_padding); 30216e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 30226e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org EmitReturn(instr, true); 30237028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ bind(&no_padding); 30247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 30256e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 30266e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org EmitReturn(instr, false); 30274e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org if (no_frame_start != -1) { 30284e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org info()->AddNoFrameRange(no_frame_start, masm_->pc_offset()); 30294e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 3030a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3031a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3032a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3033c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgvoid LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 3034a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register result = ToRegister(instr->result()); 303541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ mov(result, Operand::ForCell(instr->hydrogen()->cell())); 3036c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (instr->hydrogen()->RequiresHoleCheck()) { 3037ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmp(result, factory()->the_hole_value()); 3038a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(equal, instr->environment()); 3039a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 3040a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3041a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3042a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3043c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgvoid LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { 3044c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 30451044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org ASSERT(ToRegister(instr->global_object()).is(edx)); 3046c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 3047c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 3048c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ mov(ecx, instr->name()); 3049c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET : 3050c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RelocInfo::CODE_TARGET_CONTEXT; 3051c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 3052ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallCode(ic, mode, instr); 3053c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org} 3054c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 3055c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 305674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { 3057e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org Register value = ToRegister(instr->value()); 3058b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<PropertyCell> cell_handle = instr->hydrogen()->cell(); 3059378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3060378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // If the cell we are storing to contains the hole it could have 3061378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // been deleted from the property dictionary. In that case, we need 3062378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // to update the property details in the property dictionary to mark 3063378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // it as no longer deleted. We deoptimize in that case. 3064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (instr->hydrogen()->RequiresHoleCheck()) { 306541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ cmp(Operand::ForCell(cell_handle), factory()->the_hole_value()); 3066378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org DeoptimizeIf(equal, instr->environment()); 3067378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 3068378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3069378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Store the value. 307041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ mov(Operand::ForCell(cell_handle), value); 307164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Cells are always rescanned, so no write barrier here. 3072a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3073a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3074a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 307574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { 307674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 307774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org ASSERT(ToRegister(instr->global_object()).is(edx)); 307874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org ASSERT(ToRegister(instr->value()).is(eax)); 307974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org 308074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ mov(ecx, instr->name()); 30811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 308244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ? isolate()->builtins()->StoreIC_Initialize_Strict() 308344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org : isolate()->builtins()->StoreIC_Initialize(); 3084ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); 308574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org} 308674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org 308774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org 3088c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 308983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Register context = ToRegister(instr->context()); 3090c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Register result = ToRegister(instr->result()); 309183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ mov(result, ContextOperand(context, instr->slot_index())); 30927ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 309364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 309464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ cmp(result, factory()->the_hole_value()); 30957ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org if (instr->hydrogen()->DeoptimizesOnHole()) { 30967ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org DeoptimizeIf(equal, instr->environment()); 30977ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } else { 30987ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org Label is_not_hole; 30997ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ j(not_equal, &is_not_hole, Label::kNear); 31007ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ mov(result, factory()->undefined_value()); 31017ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ bind(&is_not_hole); 31027ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } 310364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 310483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org} 310583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 310683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 310783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgvoid LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { 310883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Register context = ToRegister(instr->context()); 310983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Register value = ToRegister(instr->value()); 31107ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 31117ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org Label skip_assignment; 31127ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 311364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Operand target = ContextOperand(context, instr->slot_index()); 311464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 311564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ cmp(target, factory()->the_hole_value()); 31167ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org if (instr->hydrogen()->DeoptimizesOnHole()) { 31177ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org DeoptimizeIf(equal, instr->environment()); 31187ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } else { 31197ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ j(not_equal, &skip_assignment, Label::kNear); 31207ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } 312164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 31227ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 312364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ mov(target, value); 3124394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (instr->hydrogen()->NeedsWriteBarrier()) { 3125394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com SmiCheck check_needed = 31261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->hydrogen()->value()->IsHeapObject() 31271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 312856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 312983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org int offset = Context::SlotOffset(instr->slot_index()); 3130394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteContextSlot(context, 3131394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com offset, 3132394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com value, 3133394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com temp, 3134750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org GetSaveFPRegsMode(), 3135394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 3136394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com check_needed); 313783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 31387ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 31397ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ bind(&skip_assignment); 3140c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3141c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3142c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3143a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 314453ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org HObjectAccess access = instr->hydrogen()->access(); 314553ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org int offset = access.offset(); 3146d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 3147d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (access.IsExternalMemory()) { 3148d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register result = ToRegister(instr->result()); 3149d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->object()->IsConstantOperand()) { 3150d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ExternalReference external_reference = ToExternalReference( 3151d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org LConstantOperand::cast(instr->object())); 3152d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ mov(result, MemOperand::StaticVariable(external_reference)); 3153d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 3154d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ mov(result, MemOperand(ToRegister(instr->object()), offset)); 3155d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 3156d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return; 3157d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 3158d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 31597979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register object = ToRegister(instr->object()); 316057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (FLAG_track_double_fields && 316157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org instr->hydrogen()->representation().IsDouble()) { 3162f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (CpuFeatures::IsSupported(SSE2)) { 3163f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org CpuFeatureScope scope(masm(), SSE2); 3164f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org XMMRegister result = ToDoubleRegister(instr->result()); 316557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movdbl(result, FieldOperand(object, offset)); 3166f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } else { 3167169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset)); 3168f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 316957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org return; 317057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 317157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 317257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Register result = ToRegister(instr->result()); 317353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (access.IsInobject()) { 317457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ mov(result, FieldOperand(object, offset)); 317557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 317657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); 317757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ mov(result, FieldOperand(result, offset)); 3178a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 3179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3180a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3181a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 318264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid LCodeGen::EmitPushTaggedOperand(LOperand* operand) { 318364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(!operand->IsDoubleRegister()); 318464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (operand->IsConstantOperand()) { 318564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); 318679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 318764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (object->IsSmi()) { 318864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Push(Handle<Smi>::cast(object)); 318964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 319064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ PushHeapObject(Handle<HeapObject>::cast(object)); 319164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 319264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (operand->IsRegister()) { 319364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ push(ToRegister(operand)); 319464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 319564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ push(ToOperand(operand)); 31967979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } 31977979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org} 31987979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 31997979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 3200a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 3201496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 32021044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org ASSERT(ToRegister(instr->object()).is(edx)); 3203a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 3204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(ecx, instr->name()); 32067979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 3207ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 3208a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3209a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 32119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgvoid LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 32129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org Register function = ToRegister(instr->function()); 321356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 32149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org Register result = ToRegister(instr->result()); 32159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org // Check that the function really is a function. 32179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org __ CmpObjectType(function, JS_FUNCTION_TYPE, result); 32189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org DeoptimizeIf(not_equal, instr->environment()); 32199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org // Check whether the function has an instance prototype. 322183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label non_instance; 32229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org __ test_b(FieldOperand(result, Map::kBitFieldOffset), 32239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 1 << Map::kHasNonInstancePrototype); 322483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_zero, &non_instance, Label::kNear); 32259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org // Get the prototype or initial map from the function. 32279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org __ mov(result, 32289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 32299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org // Check that the function has a prototype or an initial map. 3231ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmp(Operand(result), Immediate(factory()->the_hole_value())); 32329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org DeoptimizeIf(equal, instr->environment()); 32339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org // If the function does not have an initial map, we're done. 323583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 32369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org __ CmpObjectType(result, MAP_TYPE, temp); 323783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_equal, &done, Label::kNear); 32389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org // Get the prototype from the initial map. 32409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org __ mov(result, FieldOperand(result, Map::kPrototypeOffset)); 324183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 32429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org // Non-instance prototype: Fetch prototype from constructor field 32449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org // in the function's map. 32459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org __ bind(&non_instance); 32469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org __ mov(result, FieldOperand(result, Map::kConstructorOffset)); 32479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org // All done. 32499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org __ bind(&done); 32509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org} 32519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32534d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.orgvoid LCodeGen::DoLoadExternalArrayPointer( 32544d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org LLoadExternalArrayPointer* instr) { 3255496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org Register result = ToRegister(instr->result()); 325656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->object()); 32574d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org __ mov(result, FieldOperand(input, 32584d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org ExternalArray::kExternalPointerOffset)); 3259496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org} 3260496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3261496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 3263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register arguments = ToRegister(instr->arguments()); 3264a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register result = ToRegister(instr->result()); 326577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (instr->length()->IsConstantOperand() && 326677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org instr->index()->IsConstantOperand()) { 326777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 326877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org int const_length = ToInteger32(LConstantOperand::cast(instr->length())); 326977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org int index = (const_length - const_index) + 1; 327077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ mov(result, Operand(arguments, index * kPointerSize)); 327177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 327277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Register length = ToRegister(instr->length()); 327377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Operand index = ToOperand(instr->index()); 327477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // There are two words between the frame pointer and the last argument. 327577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // Subtracting from length accounts for one of them add one more. 327677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ sub(length, index); 327777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ mov(result, Operand(arguments, length, times_4, kPointerSize)); 327877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 3279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3282e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 3283e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org ElementsKind elements_kind = instr->elements_kind(); 3284eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org LOperand* key = instr->key(); 3285eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org if (!key->IsConstantOperand() && 3286eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), 3287eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org elements_kind)) { 3288eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org __ SmiUntag(ToRegister(key)); 3289e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 3290e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Operand operand(BuildFastArrayOperand( 3291e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->elements(), 3292eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org key, 3293e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->hydrogen()->key()->representation(), 3294e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org elements_kind, 3295e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 0, 3296e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->additional_index())); 3297e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3298a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (CpuFeatures::IsSupported(SSE2)) { 3299750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 3300a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org XMMRegister result(ToDoubleRegister(instr->result())); 3301a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ movss(result, operand); 3302a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ cvtss2sd(result, result); 3303a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 3304169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand); 3305a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 3306e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3307a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (CpuFeatures::IsSupported(SSE2)) { 3308750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 3309a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ movdbl(ToDoubleRegister(instr->result()), operand); 3310a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 3311169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Mov(ToX87Register(instr->result()), operand); 3312a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 3313e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 3314e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Register result(ToRegister(instr->result())); 3315e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org switch (elements_kind) { 3316e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case EXTERNAL_BYTE_ELEMENTS: 3317e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movsx_b(result, operand); 3318e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3319e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case EXTERNAL_PIXEL_ELEMENTS: 3320e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3321e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movzx_b(result, operand); 3322e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3323e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case EXTERNAL_SHORT_ELEMENTS: 3324e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movsx_w(result, operand); 3325e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3326e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3327e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movzx_w(result, operand); 3328e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3329e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case EXTERNAL_INT_ELEMENTS: 3330e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ mov(result, operand); 3331e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3332e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3333e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ mov(result, operand); 3334e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 3335e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ test(result, Operand(result)); 3336e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DeoptimizeIf(negative, instr->environment()); 3337e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 3338e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3339e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case EXTERNAL_FLOAT_ELEMENTS: 3340e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case EXTERNAL_DOUBLE_ELEMENTS: 3341e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_SMI_ELEMENTS: 3342e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_ELEMENTS: 3343e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_DOUBLE_ELEMENTS: 3344e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_SMI_ELEMENTS: 3345e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_ELEMENTS: 3346e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_DOUBLE_ELEMENTS: 3347e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case DICTIONARY_ELEMENTS: 3348e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case NON_STRICT_ARGUMENTS_ELEMENTS: 3349e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org UNREACHABLE(); 3350e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 33517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 335283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 335383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 335483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 335583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 3356a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { 3357830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 3358830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + 3359830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org sizeof(kHoleNanLower32); 3360830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Operand hole_check_operand = BuildFastArrayOperand( 3361830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org instr->elements(), instr->key(), 3362304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org instr->hydrogen()->key()->representation(), 3363830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FAST_DOUBLE_ELEMENTS, 3364830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org offset, 3365830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org instr->additional_index()); 3366830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); 3367830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org DeoptimizeIf(equal, instr->environment()); 3368830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 3369717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 3370717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org Operand double_load_operand = BuildFastArrayOperand( 33710e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org instr->elements(), 33720e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org instr->key(), 3373304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org instr->hydrogen()->key()->representation(), 33740e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org FAST_DOUBLE_ELEMENTS, 33750e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org FixedDoubleArray::kHeaderSize - kHeapObjectTag, 33760e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org instr->additional_index()); 3377a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (CpuFeatures::IsSupported(SSE2)) { 3378750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 3379a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org XMMRegister result = ToDoubleRegister(instr->result()); 3380a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ movdbl(result, double_load_operand); 3381a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 3382169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Mov(ToX87Register(instr->result()), double_load_operand); 3383a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 3384717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org} 3385717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 3386717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 3387e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3388e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Register result = ToRegister(instr->result()); 3389e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3390e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org // Load the result. 3391e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ mov(result, 3392e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org BuildFastArrayOperand(instr->elements(), 3393e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->key(), 3394e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->hydrogen()->key()->representation(), 3395e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org FAST_ELEMENTS, 3396e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org FixedArray::kHeaderSize - kHeapObjectTag, 3397e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->additional_index())); 3398e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3399e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org // Check for the hole value. 3400e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 3401e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { 3402e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ test(result, Immediate(kSmiTagMask)); 3403e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DeoptimizeIf(not_equal, instr->environment()); 3404e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 3405e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ cmp(result, factory()->the_hole_value()); 3406e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DeoptimizeIf(equal, instr->environment()); 3407e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 3408e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 3409e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 3410e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3411e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3412e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { 3413e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (instr->is_external()) { 3414e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoLoadKeyedExternalArray(instr); 3415e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else if (instr->hydrogen()->representation().IsDouble()) { 3416e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoLoadKeyedFixedDoubleArray(instr); 3417e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 3418e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoLoadKeyedFixedArray(instr); 3419e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 3420e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 3421e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3422e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3423717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.orgOperand LCodeGen::BuildFastArrayOperand( 3424b645116853c677aca8a316381b87441ba6004f67danno@chromium.org LOperand* elements_pointer, 34256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org LOperand* key, 3426304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org Representation key_representation, 342783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ElementsKind elements_kind, 34280e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org uint32_t offset, 34290e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org uint32_t additional_index) { 3430b645116853c677aca8a316381b87441ba6004f67danno@chromium.org Register elements_pointer_reg = ToRegister(elements_pointer); 34314e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org int element_shift_size = ElementsKindToShiftSize(elements_kind); 34324e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org int shift_size = element_shift_size; 343383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (key->IsConstantOperand()) { 343483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org int constant_value = ToInteger32(LConstantOperand::cast(key)); 343583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (constant_value & 0xF0000000) { 3436594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kArrayIndexConstantValueTooBig); 343783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 3438b645116853c677aca8a316381b87441ba6004f67danno@chromium.org return Operand(elements_pointer_reg, 34390e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org ((constant_value + additional_index) << shift_size) 34400e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org + offset); 344183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 3442068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org // Take the tag bit into account while computing the shift size. 3443a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (key_representation.IsSmi() && (shift_size >= 1)) { 3444068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org shift_size -= kSmiTagSize; 3445068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } 344683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); 34470e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org return Operand(elements_pointer_reg, 34480e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org ToRegister(key), 34490e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org scale_factor, 34504e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org offset + (additional_index << element_shift_size)); 345183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 3452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3453a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3454a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3455a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 3456496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 3457a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->object()).is(edx)); 34581044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org ASSERT(ToRegister(instr->key()).is(ecx)); 3459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 34607979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 3461ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 3462a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3463a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3464a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 3466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register result = ToRegister(instr->result()); 3467a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 346828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (instr->hydrogen()->from_inlined()) { 346928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ lea(result, Operand(esp, -2 * kPointerSize)); 347028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } else { 347128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Check for arguments adapter frame. 347228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label done, adapted; 347328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 347428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ mov(result, Operand(result, StandardFrameConstants::kContextOffset)); 347528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ cmp(Operand(result), 347628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 347728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ j(equal, &adapted, Label::kNear); 347828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 347928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // No arguments adaptor frame. 348028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ mov(result, Operand(ebp)); 348128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ jmp(&done, Label::kNear); 3482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 348328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Arguments adaptor frame present. 348428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ bind(&adapted); 348528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 3486b2a1c078e6f552a66c1426482a3d007b7ea7af7ddanno@chromium.org 348728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Result is the frame pointer for the frame if not adapted and for the real 348828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // frame below the adaptor frame if adapted. 348928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ bind(&done); 349028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 3491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3493a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 349556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Operand elem = ToOperand(instr->elements()); 3496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register result = ToRegister(instr->result()); 3497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 349883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 3499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3500d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // If no arguments adaptor frame the number of arguments is fixed. 3501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(ebp, elem); 3502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(result, Immediate(scope()->num_parameters())); 350383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &done, Label::kNear); 3504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Arguments adaptor frame present. Get argument length from there. 3506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 3507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(result, Operand(result, 3508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ArgumentsAdaptorFrameConstants::kLengthOffset)); 3509a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ SmiUntag(result); 3510a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3511d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Argument length is in result register. 3512a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&done); 3513a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3514a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3516154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgvoid LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 3517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register receiver = ToRegister(instr->receiver()); 3518496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org Register function = ToRegister(instr->function()); 351956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register scratch = ToRegister(instr->temp()); 3520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3521d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // If the receiver is null or undefined, we have to pass the global 3522d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // object as a receiver to normal functions. Values have to be 3523d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // passed unchanged to builtins and strict-mode functions. 352483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label global_object, receiver_ok; 3525d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 3526d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // Do not transform the receiver to object for strict mode 3527d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // functions. 3528d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ mov(scratch, 3529d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3530d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset), 3531d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 1 << SharedFunctionInfo::kStrictModeBitWithinByte); 3532412fa510dce700c25e3ff85ee85dd32dd6cb6b87danno@chromium.org __ j(not_equal, &receiver_ok); // A near jump is not sufficient here! 3533d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 3534d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // Do not transform the receiver to object for builtins. 3535d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset), 3536d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 1 << SharedFunctionInfo::kNativeBitWithinByte); 3537412fa510dce700c25e3ff85ee85dd32dd6cb6b87danno@chromium.org __ j(not_equal, &receiver_ok); 3538d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 3539d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // Normal function. Replace undefined or null with global receiver. 3540ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmp(receiver, factory()->null_value()); 354183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &global_object, Label::kNear); 3542ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmp(receiver, factory()->undefined_value()); 354383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &global_object, Label::kNear); 3544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3545496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // The receiver should be a JS object. 3546496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ test(receiver, Immediate(kSmiTagMask)); 3547496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org DeoptimizeIf(equal, instr->environment()); 3548d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch); 3549496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org DeoptimizeIf(below, instr->environment()); 355083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&receiver_ok, Label::kNear); 3551496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3552496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ bind(&global_object); 3553496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // TODO(kmillikin): We have a hydrogen value for the global object. See 3554496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // if it's better to use it than to explicitly fetch it from the context 3555496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // here. 3556496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ mov(receiver, Operand(ebp, StandardFrameConstants::kContextOffset)); 355746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ mov(receiver, ContextOperand(receiver, Context::GLOBAL_OBJECT_INDEX)); 3558d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ mov(receiver, 3559d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); 3560496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ bind(&receiver_ok); 3561154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org} 3562154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 3563154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 3564154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgvoid LCodeGen::DoApplyArguments(LApplyArguments* instr) { 3565154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Register receiver = ToRegister(instr->receiver()); 3566154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Register function = ToRegister(instr->function()); 3567154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Register length = ToRegister(instr->length()); 3568154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Register elements = ToRegister(instr->elements()); 3569154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ASSERT(receiver.is(eax)); // Used for parameter count. 3570154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ASSERT(function.is(edi)); // Required by InvokeFunction. 3571154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 3572a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3573a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Copy the arguments to this function possibly from the 3574a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // adaptor frame below it. 3575a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const uint32_t kArgumentsLimit = 1 * KB; 3576a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(length, kArgumentsLimit); 3577a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(above, instr->environment()); 3578a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(receiver); 3580a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(receiver, length); 3581a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3582a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Loop through the arguments pushing them onto the execution 3583a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // stack. 358483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label invoke, loop; 3585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // length is a small non-negative integer, due to the test above. 3586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(length, Operand(length)); 358783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(zero, &invoke, Label::kNear); 3588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&loop); 3589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize)); 3590a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ dec(length); 3591a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ j(not_zero, &loop); 3592a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3593a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Invoke the function. 3594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&invoke); 35951044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org ASSERT(instr->HasPointerMap()); 359631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org LPointerMap* pointers = instr->pointer_map(); 359731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org RecordPosition(pointers->position()); 359827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org SafepointGenerator safepoint_generator( 359927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org this, pointers, Safepoint::kLazyDeopt); 3600160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ParameterCount actual(eax); 3601d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ InvokeFunction(function, actual, CALL_FUNCTION, 3602d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org safepoint_generator, CALL_AS_METHOD); 3603a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3604a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3605a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 36064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid LCodeGen::DoDebugBreak(LDebugBreak* instr) { 36074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ int3(); 36084e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org} 36094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 36104e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 3611a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoPushArgument(LPushArgument* instr) { 361256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* argument = instr->value(); 361364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org EmitPushTaggedOperand(argument); 3614a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3615a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3616a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 361728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.orgvoid LCodeGen::DoDrop(LDrop* instr) { 361828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ Drop(instr->count()); 361928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org} 362028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 362128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 3622d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.orgvoid LCodeGen::DoThisFunction(LThisFunction* instr) { 3623d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org Register result = ToRegister(instr->result()); 36245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org __ mov(result, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 3625d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org} 3626d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 3627d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 362883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgvoid LCodeGen::DoContext(LContext* instr) { 362983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Register result = ToRegister(instr->result()); 36304cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (info()->IsOptimizing()) { 36314cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org __ mov(result, Operand(ebp, StandardFrameConstants::kContextOffset)); 36324cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } else { 36334cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org // If there is no frame, the context must be in esi. 36344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(result.is(esi)); 36354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 363683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org} 363783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 363883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 363983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgvoid LCodeGen::DoOuterContext(LOuterContext* instr) { 364083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Register context = ToRegister(instr->context()); 364183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Register result = ToRegister(instr->result()); 36426d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org __ mov(result, 36436d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); 364483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org} 364583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 364683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 364756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.orgvoid LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 364856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 364956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ push(esi); // The context is the first argument. 365056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ push(Immediate(instr->hydrogen()->pairs())); 365156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags()))); 365256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org CallRuntime(Runtime::kDeclareGlobals, 3, instr); 365356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org} 365456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org 365556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org 3656a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoGlobalObject(LGlobalObject* instr) { 365783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Register context = ToRegister(instr->context()); 3658a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register result = ToRegister(instr->result()); 365946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ mov(result, 366046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Operand(context, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 3661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3663a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3664a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { 366583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Register global = ToRegister(instr->global()); 3666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register result = ToRegister(instr->result()); 366783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ mov(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); 3668a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3669a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3670a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3671a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::CallKnownFunction(Handle<JSFunction> function, 367232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org int formal_parameter_count, 3673a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int arity, 367440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org LInstruction* instr, 3675fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org CallKind call_kind, 3676fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org EDIState edi_state) { 367732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org bool dont_adapt_arguments = 367832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 367932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org bool can_invoke_directly = 368032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org dont_adapt_arguments || formal_parameter_count == arity; 3681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LPointerMap* pointers = instr->pointer_map(); 3683a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org RecordPosition(pointers->position()); 3684a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 36852efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (can_invoke_directly) { 3686fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org if (edi_state == EDI_UNINITIALIZED) { 3687fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org __ LoadHeapObject(edi, function); 3688fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org } 36892efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 3690b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org // Change context. 3691b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 36922efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 36932efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Set eax to arguments count if adaption is not needed. Assumes that eax 36942efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // is available to write to at this point. 369532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (dont_adapt_arguments) { 36962efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ mov(eax, arity); 36972efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 36982efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 36992efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Invoke function directly. 37002efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ SetCallKind(ecx, call_kind); 370132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (function.is_identical_to(info()->closure())) { 37022efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ CallSelf(); 37032efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 37042efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); 37052efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 37062efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 3707a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 37082efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // We need to adapt arguments. 37092efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org SafepointGenerator generator( 37102efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org this, pointers, Safepoint::kLazyDeopt); 37112efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ParameterCount count(arity); 371232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ParameterCount expected(formal_parameter_count); 371332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ InvokeFunction( 371432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org function, expected, count, CALL_FUNCTION, generator, call_kind); 3715a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 3716a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3717a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3718a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3719a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 3720a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 372132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CallKnownFunction(instr->hydrogen()->function(), 372232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->hydrogen()->formal_parameter_count(), 372340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org instr->arity(), 372440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org instr, 3725fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org CALL_AS_METHOD, 3726fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org EDI_UNINITIALIZED); 3727a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3728a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3729a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3730e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 3731ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org Register input_reg = ToRegister(instr->value()); 3732a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 3733ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org factory()->heap_number_map()); 3734a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(not_equal, instr->environment()); 3735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3736fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Label slow, allocated, done; 3737a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register tmp = input_reg.is(eax) ? ecx : eax; 3738a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; 3739a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3740a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Preserve the value of all registers. 374144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 3742a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3743a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 37440a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Check the sign of the argument. If the argument is positive, just 37450a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // return it. We do not need to patch the stack since |input| and 37460a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // |result| are the same register and |input| will be restored 37470a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // unchanged by popping safepoint registers. 3748a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(tmp, Immediate(HeapNumber::kSignMask)); 3749fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ j(zero, &done); 3750a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3751a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ AllocateHeapNumber(tmp, tmp2, no_reg, &slow); 3752fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ jmp(&allocated, Label::kNear); 3753a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3754a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Slow case: Call the runtime system to do the number allocation. 3755a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&slow); 3756ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, 3757ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org instr, instr->context()); 3758a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Set the pointer to the new heap number in tmp. 3759a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (!tmp.is(eax)) __ mov(tmp, eax); 3760a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Restore input_reg after call to runtime. 37613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ LoadFromSafepointRegisterSlot(input_reg, input_reg); 3762a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3763a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&allocated); 3764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 3765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ and_(tmp2, ~HeapNumber::kSignMask); 3766a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(FieldOperand(tmp, HeapNumber::kExponentOffset), tmp2); 3767a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); 3768a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(FieldOperand(tmp, HeapNumber::kMantissaOffset), tmp2); 37693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ StoreToSafepointRegisterSlot(input_reg, tmp); 3770a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 37710a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ bind(&done); 3772a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3774a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3775e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { 3776ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org Register input_reg = ToRegister(instr->value()); 37770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ test(input_reg, Operand(input_reg)); 37780a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Label is_positive; 3779fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ j(not_sign, &is_positive, Label::kNear); 3780fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ neg(input_reg); // Sets flags. 37810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org DeoptimizeIf(negative, instr->environment()); 37820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ bind(&is_positive); 37830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 37840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 37850a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 3786e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathAbs(LMathAbs* instr) { 3787a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Class for deferred case. 3788a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3789a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public: 3790e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) 3791a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org : LDeferredCode(codegen), instr_(instr) { } 3792a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org virtual void Generate() { 3793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3794a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 3795c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual LInstruction* instr() { return instr_; } 3796a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private: 3797e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org LMathAbs* instr_; 3798a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org }; 3799a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3800ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org ASSERT(instr->value()->Equals(instr->result())); 3801a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Representation r = instr->hydrogen()->value()->representation(); 3802a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3803750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 3804a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (r.IsDouble()) { 3805a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org XMMRegister scratch = xmm0; 3806ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 3807fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org __ xorps(scratch, scratch); 3808a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ subsd(scratch, input_reg); 3809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ pand(input_reg, scratch); 3810594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else if (r.IsSmiOrInteger32()) { 38110a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org EmitIntegerMathAbs(instr); 3812a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { // Tagged case. 3813a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeferredMathAbsTaggedHeapNumber* deferred = 38147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); 3815ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org Register input_reg = ToRegister(instr->value()); 3816a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Smi check. 38177b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org __ JumpIfNotSmi(input_reg, deferred->entry()); 38180a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org EmitIntegerMathAbs(instr); 3819a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(deferred->exit()); 3820a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 3821a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3822a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3823a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3824e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathFloor(LMathFloor* instr) { 3825750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 3826a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org XMMRegister xmm_scratch = xmm0; 3827a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register output_reg = ToRegister(instr->result()); 3828ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 3829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 38304acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (CpuFeatures::IsSupported(SSE4_1)) { 3831750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE4_1); 38324acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 38334acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Deoptimize on negative zero. 38344acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Label non_zero; 38354acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ xorps(xmm_scratch, xmm_scratch); // Zero the register. 38364acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ ucomisd(input_reg, xmm_scratch); 38374acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ j(not_equal, &non_zero, Label::kNear); 38384acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ movmskpd(output_reg, input_reg); 38394acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ test(output_reg, Immediate(1)); 38404acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org DeoptimizeIf(not_zero, instr->environment()); 38414acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ bind(&non_zero); 38424acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 38434acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown); 38444acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ cvttsd2si(output_reg, Operand(xmm_scratch)); 38454acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Overflow is signalled with minint. 38464acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ cmp(output_reg, 0x80000000u); 38474acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org DeoptimizeIf(equal, instr->environment()); 3848a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 38497a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org Label negative_sign, done; 3850212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // Deoptimize on unordered. 38514acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ xorps(xmm_scratch, xmm_scratch); // Zero the register. 38524acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ ucomisd(input_reg, xmm_scratch); 3853212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org DeoptimizeIf(parity_even, instr->environment()); 3854212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org __ j(below, &negative_sign, Label::kNear); 3855a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 38564acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 38574acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Check for negative zero. 38584acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Label positive_sign; 38594acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ j(above, &positive_sign, Label::kNear); 38604acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ movmskpd(output_reg, input_reg); 38614acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ test(output_reg, Immediate(1)); 38624acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org DeoptimizeIf(not_zero, instr->environment()); 38634acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ Set(output_reg, Immediate(0)); 38644acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ jmp(&done, Label::kNear); 38654acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ bind(&positive_sign); 38664acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 3867a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 38684acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Use truncating instruction (OK because input is positive). 38694acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ cvttsd2si(output_reg, Operand(input_reg)); 38704acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Overflow is signalled with minint. 38714acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ cmp(output_reg, 0x80000000u); 38724acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org DeoptimizeIf(equal, instr->environment()); 3873212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org __ jmp(&done, Label::kNear); 3874212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 38757a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org // Non-zero negative reaches here. 3876212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org __ bind(&negative_sign); 38777a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org // Truncate, then compare and compensate. 3878212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org __ cvttsd2si(output_reg, Operand(input_reg)); 3879212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org __ cvtsi2sd(xmm_scratch, output_reg); 3880212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org __ ucomisd(input_reg, xmm_scratch); 3881212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org __ j(equal, &done, Label::kNear); 3882212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org __ sub(output_reg, Immediate(1)); 3883212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org DeoptimizeIf(overflow, instr->environment()); 3884212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 38854acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ bind(&done); 38864acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 38874acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org} 3888a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3889e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 38904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid LCodeGen::DoMathRound(LMathRound* instr) { 3891750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 3892a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register output_reg = ToRegister(instr->result()); 3893ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 38948432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org XMMRegister xmm_scratch = xmm0; 38954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org XMMRegister input_temp = ToDoubleRegister(instr->temp()); 3896a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ExternalReference one_half = ExternalReference::address_of_one_half(); 38978432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org ExternalReference minus_one_half = 38988432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org ExternalReference::address_of_minus_one_half(); 38998432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 39004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Label done, round_to_zero, below_one_half, do_not_compensate; 3901a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); 39024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ ucomisd(xmm_scratch, input_reg); 39034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ j(above, &below_one_half); 39044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 39054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x). 39064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ addsd(xmm_scratch, input_reg); 39074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ cvttsd2si(output_reg, Operand(xmm_scratch)); 39084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Overflow is signalled with minint. 39094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ cmp(output_reg, 0x80000000u); 39104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ RecordComment("D2I conversion overflow"); 39114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org DeoptimizeIf(equal, instr->environment()); 39124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ jmp(&done); 3913a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 39144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ bind(&below_one_half); 39154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ movdbl(xmm_scratch, Operand::StaticVariable(minus_one_half)); 39164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ ucomisd(xmm_scratch, input_reg); 39174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ j(below_equal, &round_to_zero); 39184a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 39194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then 39204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // compare and compensate. 39214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ movsd(input_temp, input_reg); // Do not alter input_reg. 39224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ subsd(input_temp, xmm_scratch); 39234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ cvttsd2si(output_reg, Operand(input_temp)); 39244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Catch minint due to overflow, and to prevent overflow when compensating. 39254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ cmp(output_reg, 0x80000000u); 39264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ RecordComment("D2I conversion overflow"); 39274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org DeoptimizeIf(equal, instr->environment()); 39288432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 39294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ cvtsi2sd(xmm_scratch, output_reg); 39304a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ ucomisd(xmm_scratch, input_temp); 39314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ j(equal, &done); 39324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ sub(output_reg, Immediate(1)); 39334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // No overflow because we already ruled out minint. 39344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ jmp(&done); 39358432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 39364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ bind(&round_to_zero); 39374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if 39384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // we can ignore the difference between a result of -0 and +0. 39394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 39404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // If the sign is positive, we return +0. 39414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ movmskpd(output_reg, input_reg); 39424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ test(output_reg, Immediate(1)); 39434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ RecordComment("Minus zero"); 39444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org DeoptimizeIf(not_zero, instr->environment()); 3945160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 39464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Set(output_reg, Immediate(0)); 39474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ bind(&done); 3948a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3949a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3950a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3951e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathSqrt(LMathSqrt* instr) { 3952750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 3953ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 3954a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 3955a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ sqrtsd(input_reg, input_reg); 3956a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3957a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3958a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 395964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { 3960750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 39615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org XMMRegister xmm_scratch = xmm0; 3962ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 396364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Register scratch = ToRegister(instr->temp()); 39645f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 396564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 396664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Note that according to ECMA-262 15.8.2.13: 396764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Math.pow(-Infinity, 0.5) == Infinity 396864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Math.sqrt(-Infinity) == NaN 396964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label done, sqrt; 397064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Check base for -Infinity. According to IEEE-754, single-precision 397164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // -Infinity has the highest 9 bits set and the lowest 23 bits cleared. 397264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ mov(scratch, 0xFF800000); 397364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ movd(xmm_scratch, scratch); 397464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ cvtss2sd(xmm_scratch, xmm_scratch); 397564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ ucomisd(input_reg, xmm_scratch); 397664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Comparing -Infinity with NaN results in "unordered", which sets the 397764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // zero flag as if both were equal. However, it also sets the carry flag. 397864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ j(not_equal, &sqrt, Label::kNear); 397964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ j(carry, &sqrt, Label::kNear); 398064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // If input is -Infinity, return Infinity. 398164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ xorps(input_reg, input_reg); 398264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ subsd(input_reg, xmm_scratch); 398364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ jmp(&done, Label::kNear); 398464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 398564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Square root. 398664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&sqrt); 3987fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org __ xorps(xmm_scratch, xmm_scratch); 398831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org __ addsd(input_reg, xmm_scratch); // Convert -0 to +0. 39895f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org __ sqrtsd(input_reg, input_reg); 399064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&done); 39915f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 39925f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 39935f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 39945f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid LCodeGen::DoPower(LPower* instr) { 39955f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Representation exponent_type = instr->hydrogen()->right()->representation(); 399664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Having marked this as a call, we can use any registers. 399764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Just make sure that the input/output registers are the expected ones. 399856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(!instr->right()->IsDoubleRegister() || 399956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ToDoubleRegister(instr->right()).is(xmm1)); 400056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(!instr->right()->IsRegister() || 400156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ToRegister(instr->right()).is(eax)); 400256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(ToDoubleRegister(instr->left()).is(xmm2)); 400364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(ToDoubleRegister(instr->result()).is(xmm3)); 400464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 400553ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (exponent_type.IsSmi()) { 400653ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org MathPowStub stub(MathPowStub::TAGGED); 400753ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org __ CallStub(&stub); 400853ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org } else if (exponent_type.IsTagged()) { 400964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label no_deopt; 401064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ JumpIfSmi(eax, &no_deopt); 401164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx); 401264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org DeoptimizeIf(not_equal, instr->environment()); 401364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&no_deopt); 401464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MathPowStub stub(MathPowStub::TAGGED); 401564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CallStub(&stub); 40165f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else if (exponent_type.IsInteger32()) { 401764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MathPowStub stub(MathPowStub::INTEGER); 401864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CallStub(&stub); 40195f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else { 402064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(exponent_type.IsDouble()); 402164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MathPowStub stub(MathPowStub::DOUBLE); 402264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CallStub(&stub); 40235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 40245f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 40255f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 40265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 4027f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid LCodeGen::DoRandom(LRandom* instr) { 4028bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com class DeferredDoRandom: public LDeferredCode { 4029bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com public: 4030bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com DeferredDoRandom(LCodeGen* codegen, LRandom* instr) 4031bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com : LDeferredCode(codegen), instr_(instr) { } 4032bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com virtual void Generate() { codegen()->DoDeferredRandom(instr_); } 4033bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com virtual LInstruction* instr() { return instr_; } 4034bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com private: 4035bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com LRandom* instr_; 4036bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com }; 4037bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 40387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); 4039bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 4040750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 4041f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Having marked this instruction as a call we can use any 4042f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // registers. 4043f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 404456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(ToRegister(instr->global_object()).is(eax)); 4045bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Assert that the register size is indeed the size of each seed. 4046bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com static const int kSeedSize = sizeof(uint32_t); 4047bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com STATIC_ASSERT(kPointerSize == kSeedSize); 4048f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 404946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ mov(eax, FieldOperand(eax, GlobalObject::kNativeContextOffset)); 4050bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com static const int kRandomSeedOffset = 4051bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize; 4052bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ mov(ebx, FieldOperand(eax, kRandomSeedOffset)); 405346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // ebx: FixedArray of the native context's random seeds 4054bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 4055bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Load state[0]. 4056bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ mov(ecx, FieldOperand(ebx, ByteArray::kHeaderSize)); 4057bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // If state[0] == 0, call runtime to initialize seeds. 4058bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ test(ecx, ecx); 4059bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(zero, deferred->entry()); 4060bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Load state[1]. 4061bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ mov(eax, FieldOperand(ebx, ByteArray::kHeaderSize + kSeedSize)); 4062bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // ecx: state[0] 4063bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // eax: state[1] 4064bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 4065bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16) 4066bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ movzx_w(edx, ecx); 4067bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ imul(edx, edx, 18273); 4068bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ shr(ecx, 16); 4069bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ add(ecx, edx); 4070bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Save state[0]. 4071bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ mov(FieldOperand(ebx, ByteArray::kHeaderSize), ecx); 4072bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 4073bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16) 4074bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ movzx_w(edx, eax); 4075bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ imul(edx, edx, 36969); 4076bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ shr(eax, 16); 4077bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ add(eax, edx); 4078bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Save state[1]. 4079bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ mov(FieldOperand(ebx, ByteArray::kHeaderSize + kSeedSize), eax); 4080bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 4081bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF) 4082bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ shl(ecx, 14); 4083bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ and_(eax, Immediate(0x3FFFF)); 4084bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ add(eax, ecx); 4085f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 4086bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ bind(deferred->exit()); 4087f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Convert 32 random bits in eax to 0.(32 random bits) in a double 4088f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // by computing: 4089f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). 4090f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single. 4091f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com __ movd(xmm2, ebx); 4092f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com __ movd(xmm1, eax); 4093f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com __ cvtss2sd(xmm2, xmm2); 4094f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com __ xorps(xmm1, xmm2); 4095f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com __ subsd(xmm1, xmm2); 4096f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 4097f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 4098f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 4099bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.comvoid LCodeGen::DoDeferredRandom(LRandom* instr) { 4100bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ PrepareCallCFunction(1, ebx); 4101bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ mov(Operand(esp, 0), eax); 4102bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); 4103bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Return value is in eax. 4104bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com} 4105bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 4106bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 4107e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathLog(LMathLog* instr) { 4108750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 4109ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org ASSERT(instr->value()->Equals(instr->result())); 4110ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 411183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label positive, done, zero; 4112fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org __ xorps(xmm0, xmm0); 411374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ ucomisd(input_reg, xmm0); 411483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(above, &positive, Label::kNear); 411583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &zero, Label::kNear); 411684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org ExternalReference nan = 411784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org ExternalReference::address_of_canonical_non_hole_nan(); 411874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ movdbl(input_reg, Operand::StaticVariable(nan)); 411983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 412074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ bind(&zero); 412174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ push(Immediate(0xFFF00000)); 412274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ push(Immediate(0)); 412374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ movdbl(input_reg, Operand(esp, 0)); 412474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ add(Operand(esp), Immediate(kDoubleSize)); 412583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 412674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ bind(&positive); 412774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ fldln2(); 412874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ sub(Operand(esp), Immediate(kDoubleSize)); 412974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ movdbl(Operand(esp, 0), input_reg); 413074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ fld_d(Operand(esp, 0)); 413174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ fyl2x(); 413274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ fstp_d(Operand(esp, 0)); 413374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ movdbl(input_reg, Operand(esp, 0)); 413474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ add(Operand(esp), Immediate(kDoubleSize)); 413574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org __ bind(&done); 4136023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org} 4137023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org 4138023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org 41391f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgvoid LCodeGen::DoMathExp(LMathExp* instr) { 4140750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 41411f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister input = ToDoubleRegister(instr->value()); 41421f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister result = ToDoubleRegister(instr->result()); 41431f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org Register temp1 = ToRegister(instr->temp1()); 41441f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org Register temp2 = ToRegister(instr->temp2()); 41451f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 41461f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org MathExpGenerator::EmitMathExp(masm(), input, result, xmm0, temp1, temp2); 41471f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org} 41481f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 41491f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 4150e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathTan(LMathTan* instr) { 41511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 4152594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // Set the context register to a GC-safe fake value. Clobbering it is 4153594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // OK because this instruction is marked as a call. 4154594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Set(esi, Immediate(0)); 41551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org TranscendentalCacheStub stub(TranscendentalCache::TAN, 41561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org TranscendentalCacheStub::UNTAGGED); 41578432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 41581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org} 41591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 41601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 4161e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathCos(LMathCos* instr) { 4162023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 4163594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // Set the context register to a GC-safe fake value. Clobbering it is 4164594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // OK because this instruction is marked as a call. 4165594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Set(esi, Immediate(0)); 4166023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org TranscendentalCacheStub stub(TranscendentalCache::COS, 4167023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org TranscendentalCacheStub::UNTAGGED); 41688432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4169023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org} 4170023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org 4171023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org 4172e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathSin(LMathSin* instr) { 4173023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 4174594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // Set the context register to a GC-safe fake value. Clobbering it is 4175594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // OK because this instruction is marked as a call. 4176594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Set(esi, Immediate(0)); 4177023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org TranscendentalCacheStub stub(TranscendentalCache::SIN, 4178023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org TranscendentalCacheStub::UNTAGGED); 41798432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 41805f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 41815f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 41825f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 4183160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgvoid LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 4184160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 4185160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(ToRegister(instr->function()).is(edi)); 4186160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(instr->HasPointerMap()); 4187fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org 418832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 418932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (known_function.is_null()) { 4190fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org LPointerMap* pointers = instr->pointer_map(); 4191fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org RecordPosition(pointers->position()); 4192fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org SafepointGenerator generator( 4193fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org this, pointers, Safepoint::kLazyDeopt); 4194fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org ParameterCount count(instr->arity()); 4195fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); 4196fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org } else { 419732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CallKnownFunction(known_function, 419832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->hydrogen()->formal_parameter_count(), 4199fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr->arity(), 4200fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr, 4201fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org CALL_AS_METHOD, 4202fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org EDI_CONTAINS_TARGET); 4203fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org } 4204160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org} 4205160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 4206160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 4207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallKeyed(LCallKeyed* instr) { 4208496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 4209496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(ToRegister(instr->key()).is(ecx)); 4210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 4211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int arity = instr->arity(); 421334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org Handle<Code> ic = 421434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org isolate()->stub_cache()->ComputeKeyedCallInitialize(arity); 4215ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 4216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallNamed(LCallNamed* instr) { 4220496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 4221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 4222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int arity = instr->arity(); 422440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org RelocInfo::Mode mode = RelocInfo::CODE_TARGET; 422540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Handle<Code> ic = 422634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org isolate()->stub_cache()->ComputeCallInitialize(arity, mode); 4227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(ecx, instr->name()); 4228ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallCode(ic, mode, instr); 4229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallFunction(LCallFunction* instr) { 4233496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 4234c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org ASSERT(ToRegister(instr->function()).is(edi)); 4235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 4236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int arity = instr->arity(); 4238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); 42398432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4240a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4241a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4242a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4243a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallGlobal(LCallGlobal* instr) { 4244496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 4245a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 4246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4247a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int arity = instr->arity(); 424840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; 424940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Handle<Code> ic = 425034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org isolate()->stub_cache()->ComputeCallInitialize(arity, mode); 4251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(ecx, instr->name()); 4252ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallCode(ic, mode, instr); 4253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4256a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 4257a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 425832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CallKnownFunction(instr->hydrogen()->target(), 425932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->hydrogen()->formal_parameter_count(), 4260fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr->arity(), 4261fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr, 4262fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org CALL_AS_FUNCTION, 4263fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org EDI_UNINITIALIZED); 4264a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4266a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallNew(LCallNew* instr) { 4268496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 4269496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(ToRegister(instr->constructor()).is(edi)); 4270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 4271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 42721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // No cell in ebx for construct type feedback in optimized code 42731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<Object> undefined_value(isolate()->factory()->undefined_value()); 42741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ mov(ebx, Immediate(undefined_value)); 4275fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 4276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ Set(eax, Immediate(instr->arity())); 42778432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 42814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid LCodeGen::DoCallNewArray(LCallNewArray* instr) { 42824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 42834a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(ToRegister(instr->constructor()).is(edi)); 42844a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(ToRegister(instr->result()).is(eax)); 42854a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 42864a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Set(eax, Immediate(instr->arity())); 4287ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ mov(ebx, instr->hydrogen()->property_cell()); 428857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ElementsKind kind = instr->hydrogen()->elements_kind(); 42891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org AllocationSiteOverrideMode override_mode = 4290bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) 42911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? DISABLE_ALLOCATION_SITES 42921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org : DONT_OVERRIDE; 42931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ContextCheckMode context_mode = CONTEXT_CHECK_NOT_REQUIRED; 4294d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 4295ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if (instr->arity() == 0) { 42961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ArrayNoArgumentConstructorStub stub(kind, context_mode, override_mode); 4297ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4298ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else if (instr->arity() == 1) { 429941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Label done; 430041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (IsFastPackedElementsKind(kind)) { 430141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Label packed_case; 430241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // We might need a change here 430341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // look at the first argument 430441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ mov(ecx, Operand(esp, 0)); 430541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ test(ecx, ecx); 430641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ j(zero, &packed_case); 430741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 430841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ElementsKind holey_kind = GetHoleyElementsKind(kind); 43091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ArraySingleArgumentConstructorStub stub(holey_kind, context_mode, 43101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org override_mode); 431141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 431241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ jmp(&done); 431341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ bind(&packed_case); 431441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } 431541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 43161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ArraySingleArgumentConstructorStub stub(kind, context_mode, override_mode); 4317ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 431841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ bind(&done); 4319ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else { 43201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode); 4321ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4322ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 43234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 43244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 43254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 4326a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallRuntime(LCallRuntime* instr) { 4327ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallRuntime(instr->function(), instr->arity(), instr); 4328a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4329a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 43312bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { 43322bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result = ToRegister(instr->result()); 43332bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register base = ToRegister(instr->base_object()); 43342bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ lea(result, Operand(base, instr->offset())); 43352bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org} 43362bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 43372bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 4338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 4339f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Representation representation = instr->representation(); 4340f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 434153ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org HObjectAccess access = instr->hydrogen()->access(); 434253ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org int offset = access.offset(); 4343a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4344d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (access.IsExternalMemory()) { 4345d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 4346d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org MemOperand operand = instr->object()->IsConstantOperand() 4347d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ? MemOperand::StaticVariable( 4348d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ToExternalReference(LConstantOperand::cast(instr->object()))) 4349d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org : MemOperand(ToRegister(instr->object()), offset); 4350d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->value()->IsConstantOperand()) { 4351d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4352d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ mov(operand, Immediate(ToInteger32(operand_value))); 4353d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 4354d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register value = ToRegister(instr->value()); 4355d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ mov(operand, value); 4356d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 4357d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return; 4358d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 4359d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 4360d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register object = ToRegister(instr->object()); 436157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Map> transition = instr->transition(); 436257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 4363f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (FLAG_track_fields && representation.IsSmi()) { 4364f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (instr->value()->IsConstantOperand()) { 4365f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4366a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (!IsSmi(operand_value)) { 4367f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org DeoptimizeIf(no_condition, instr->environment()); 4368f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 4369f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 4370906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 4371906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (instr->value()->IsConstantOperand()) { 4372906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4373906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (IsInteger32(operand_value)) { 4374906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org DeoptimizeIf(no_condition, instr->environment()); 4375906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 4376906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else { 4377906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (!instr->hydrogen()->value()->type().IsHeapObject()) { 4378906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org Register value = ToRegister(instr->value()); 4379906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org __ test(value, Immediate(kSmiTagMask)); 4380906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org DeoptimizeIf(zero, instr->environment()); 4381906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 4382906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 438357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else if (FLAG_track_double_fields && representation.IsDouble()) { 438457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT(transition.is_null()); 438553ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org ASSERT(access.IsInobject()); 438657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 438757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (CpuFeatures::IsSupported(SSE2)) { 438857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 438957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org XMMRegister value = ToDoubleRegister(instr->value()); 439057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movdbl(FieldOperand(object, offset), value); 439157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 4392169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Register value = ToX87Register(instr->value()); 4393169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Mov(FieldOperand(object, offset), value); 439457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 439557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org return; 4396f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 4397f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 4398f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!transition.is_null()) { 439937141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { 4400f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ mov(FieldOperand(object, HeapObject::kMapOffset), transition); 440137141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org } else { 440256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 440356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp_map = ToRegister(instr->temp_map()); 4404f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ mov(temp_map, transition); 440537141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map); 440637141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org // Update the write barrier for the map field. 440737141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org __ RecordWriteField(object, 440837141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org HeapObject::kMapOffset, 440937141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org temp_map, 441037141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org temp, 4411750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org GetSaveFPRegsMode(), 441237141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org OMIT_REMEMBERED_SET, 441337141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org OMIT_SMI_CHECK); 441437141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org } 4415a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4416a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4417a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Do the store. 4418394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com SmiCheck check_needed = 44191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->hydrogen()->value()->IsHeapObject() 44201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 442177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 442277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Register write_register = object; 442353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (!access.IsInobject()) { 442477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org write_register = ToRegister(instr->temp()); 4425d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ mov(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); 442677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 442777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 442877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (instr->value()->IsConstantOperand()) { 442977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4430a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (operand_value->IsRegister()) { 443132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ mov(FieldOperand(write_register, offset), ToRegister(operand_value)); 443277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 443332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Handle<Object> handle_value = ToHandle(operand_value); 443457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 443532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ mov(FieldOperand(write_register, offset), handle_value); 4436a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 443877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ mov(FieldOperand(write_register, offset), ToRegister(instr->value())); 443977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 444077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 444177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (instr->hydrogen()->NeedsWriteBarrier()) { 444277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Register value = ToRegister(instr->value()); 444353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object; 444477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // Update the write barrier for the object for in-object properties. 444577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ RecordWriteField(write_register, 444677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org offset, 444777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org value, 444877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org temp, 444977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org GetSaveFPRegsMode(), 445077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org EMIT_REMEMBERED_SET, 445177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org check_needed); 4452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4453a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4454a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4455a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4456a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { 4457496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 4458a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->object()).is(edx)); 4459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->value()).is(eax)); 4460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(ecx, instr->name()); 44621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 44637979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ? isolate()->builtins()->StoreIC_Initialize_Strict() 44647979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org : isolate()->builtins()->StoreIC_Initialize(); 4465ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 4466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4467a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4468a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4469fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgvoid LCodeGen::ApplyCheckIf(Condition cc, LBoundsCheck* check) { 4470fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (FLAG_debug_code && check->hydrogen()->skip_check()) { 4471fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Label done; 4472fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ j(NegateCondition(cc), &done, Label::kNear); 4473fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ int3(); 4474fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ bind(&done); 4475fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 4476fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org DeoptimizeIf(cc, check->environment()); 4477fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 4478fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org} 4479fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 4480fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 4481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 4482fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen()->skip_check() && !FLAG_debug_code) return; 44837c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 4484b645116853c677aca8a316381b87441ba6004f67danno@chromium.org if (instr->index()->IsConstantOperand()) { 4485fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Immediate immediate = 4486fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ToImmediate(LConstantOperand::cast(instr->index()), 4487fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org instr->hydrogen()->length()->representation()); 4488fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ cmp(ToOperand(instr->length()), immediate); 4489fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Condition condition = 4490fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org instr->hydrogen()->allow_equality() ? below : below_equal; 4491fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ApplyCheckIf(condition, instr); 4492b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } else { 4493b645116853c677aca8a316381b87441ba6004f67danno@chromium.org __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); 4494fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Condition condition = 4495fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org instr->hydrogen()->allow_equality() ? above : above_equal; 4496fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ApplyCheckIf(condition, instr); 4497b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } 4498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4501e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 450283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ElementsKind elements_kind = instr->elements_kind(); 4503eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org LOperand* key = instr->key(); 4504eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org if (!key->IsConstantOperand() && 4505eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), 4506eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org elements_kind)) { 4507eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org __ SmiUntag(ToRegister(key)); 4508304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 4509304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org Operand operand(BuildFastArrayOperand( 4510e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->elements(), 4511eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org key, 4512304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org instr->hydrogen()->key()->representation(), 4513304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org elements_kind, 4514304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 0, 4515304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org instr->additional_index())); 451683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 4517e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 4518e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CpuFeatureScope scope(masm(), SSE2); 4519e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); 4520e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movss(operand, xmm0); 4521e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 4522e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fld(0); 4523e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fstp_s(operand); 4524e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 452583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 4526e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 4527e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CpuFeatureScope scope(masm(), SSE2); 4528e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdbl(operand, ToDoubleRegister(instr->value())); 4529e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 4530169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Mov(operand, ToX87Register(instr->value())); 4531e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 45327979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } else { 45337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register value = ToRegister(instr->value()); 45346d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org switch (elements_kind) { 453583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org case EXTERNAL_PIXEL_ELEMENTS: 453683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 453783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org case EXTERNAL_BYTE_ELEMENTS: 453883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ mov_b(operand, value); 45397979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org break; 454083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org case EXTERNAL_SHORT_ELEMENTS: 454183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 454283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ mov_w(operand, value); 45437979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org break; 454483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org case EXTERNAL_INT_ELEMENTS: 454583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org case EXTERNAL_UNSIGNED_INT_ELEMENTS: 454683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ mov(operand, value); 45477979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org break; 454883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org case EXTERNAL_FLOAT_ELEMENTS: 454983e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org case EXTERNAL_DOUBLE_ELEMENTS: 4550830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org case FAST_SMI_ELEMENTS: 455183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org case FAST_ELEMENTS: 455283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org case FAST_DOUBLE_ELEMENTS: 4553830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org case FAST_HOLEY_SMI_ELEMENTS: 4554830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org case FAST_HOLEY_ELEMENTS: 4555830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org case FAST_HOLEY_DOUBLE_ELEMENTS: 455683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org case DICTIONARY_ELEMENTS: 455783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org case NON_STRICT_ARGUMENTS_ELEMENTS: 45587979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org UNREACHABLE(); 45597979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org break; 45607979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } 45613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 45623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 45633a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 4565e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { 4566e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ExternalReference canonical_nan_reference = 4567e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ExternalReference::address_of_canonical_non_hole_nan(); 4568e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Operand double_store_operand = BuildFastArrayOperand( 4569e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->elements(), 4570e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->key(), 4571e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->hydrogen()->key()->representation(), 4572e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org FAST_DOUBLE_ELEMENTS, 4573e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org FixedDoubleArray::kHeaderSize - kHeapObjectTag, 4574e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->additional_index()); 4575e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4576e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 4577e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CpuFeatureScope scope(masm(), SSE2); 4578e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org XMMRegister value = ToDoubleRegister(instr->value()); 4579e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4580e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (instr->NeedsCanonicalization()) { 4581e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label have_value; 4582e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4583e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ ucomisd(value, value); 4584e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(parity_odd, &have_value); // NaN. 4585e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4586e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); 4587e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&have_value); 4588e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 4589e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4590e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movdbl(double_store_operand, value); 4591e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 4592e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Can't use SSE2 in the serializer 4593e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (instr->hydrogen()->IsConstantHoleStore()) { 4594e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // This means we should store the (double) hole. No floating point 4595e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // registers required. 4596e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org double nan_double = FixedDoubleArray::hole_nan_as_double(); 4597e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint64_t int_val = BitCast<uint64_t, double>(nan_double); 4598e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int32_t lower = static_cast<int32_t>(int_val); 4599e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); 4600e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4601e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(double_store_operand, Immediate(lower)); 4602e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Operand double_store_operand2 = BuildFastArrayOperand( 4603e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org instr->elements(), 4604e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org instr->key(), 4605e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org instr->hydrogen()->key()->representation(), 4606e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org FAST_DOUBLE_ELEMENTS, 4607e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org FixedDoubleArray::kHeaderSize - kHeapObjectTag + kPointerSize, 4608e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org instr->additional_index()); 4609e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(double_store_operand2, Immediate(upper)); 4610e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 4611e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label no_special_nan_handling; 4612169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Register value = ToX87Register(instr->value()); 4613169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Fxch(value); 4614e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4615e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (instr->NeedsCanonicalization()) { 4616e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fld(0); 4617e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fld(0); 4618e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ FCmp(); 4619e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4620e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(parity_odd, &no_special_nan_handling); 4621e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ sub(esp, Immediate(kDoubleSize)); 4622e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fst_d(MemOperand(esp, 0)); 4623e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(MemOperand(esp, sizeof(kHoleNanLower32)), 4624e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Immediate(kHoleNanUpper32)); 4625e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ add(esp, Immediate(kDoubleSize)); 4626e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label canonicalize; 4627e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(not_equal, &canonicalize); 4628e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ jmp(&no_special_nan_handling); 4629e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&canonicalize); 4630e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fstp(0); 4631e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fld_d(Operand::StaticVariable(canonical_nan_reference)); 4632e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 4633e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4634e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&no_special_nan_handling); 4635e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fst_d(double_store_operand); 4636e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 4637e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 4638e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 4639e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 4640e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 4641e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 4642e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Register elements = ToRegister(instr->elements()); 4643a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; 4644a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 46450e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org Operand operand = BuildFastArrayOperand( 4646e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->elements(), 46470e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org instr->key(), 4648304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org instr->hydrogen()->key()->representation(), 46490e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org FAST_ELEMENTS, 46500e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org FixedArray::kHeaderSize - kHeapObjectTag, 46510e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org instr->additional_index()); 465277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (instr->value()->IsRegister()) { 465377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ mov(operand, ToRegister(instr->value())); 465477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 465577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4656fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (IsSmi(operand_value)) { 4657fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Immediate immediate = ToImmediate(operand_value, Representation::Smi()); 4658fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ mov(operand, immediate); 465977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 4660fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ASSERT(!IsInteger32(operand_value)); 466177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Handle<Object> handle_value = ToHandle(operand_value); 466277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ mov(operand, handle_value); 466377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 466477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 4665a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (instr->hydrogen()->NeedsWriteBarrier()) { 466777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org ASSERT(instr->value()->IsRegister()); 466877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Register value = ToRegister(instr->value()); 46690e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org ASSERT(!instr->key()->IsConstantOperand()); 4670394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com SmiCheck check_needed = 46711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->hydrogen()->value()->IsHeapObject() 46721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4673a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Compute address of modified element and store it into key register. 46740e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org __ lea(key, operand); 4675394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWrite(elements, 4676394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com key, 4677394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com value, 4678750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org GetSaveFPRegsMode(), 4679394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 4680394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com check_needed); 4681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4683a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4684a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4685e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { 4686e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org // By cases...external, fast-double, fast 4687e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (instr->is_external()) { 4688e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoStoreKeyedExternalArray(instr); 4689e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else if (instr->hydrogen()->value()->representation().IsDouble()) { 4690e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoStoreKeyedFixedDoubleArray(instr); 4691e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 4692e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoStoreKeyedFixedArray(instr); 469328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 4694717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org} 4695717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 4696717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 4697a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 4698496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 4699a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->object()).is(edx)); 4700a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->key()).is(ecx)); 4701a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(ToRegister(instr->value()).is(eax)); 4702a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 47031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 47047979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 47057979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org : isolate()->builtins()->KeyedStoreIC_Initialize(); 4706ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 4707a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4708a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 471094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 471194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register object = ToRegister(instr->object()); 471294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register temp = ToRegister(instr->temp()); 4713ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ TestJSArrayForAllocationMemento(object, temp); 471494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org DeoptimizeIf(equal, instr->environment()); 471594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 471694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 471794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 4718394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 4719394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register object_reg = ToRegister(instr->object()); 4720394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 4721394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Map> from_map = instr->original_map(); 4722394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Map> to_map = instr->transitioned_map(); 4723003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ElementsKind from_kind = instr->from_kind(); 4724003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ElementsKind to_kind = instr->to_kind(); 4725394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 4726394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label not_applicable; 47277028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org bool is_simple_map_transition = 47287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org IsSimpleMapChangeTransition(from_kind, to_kind); 47297028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Label::Distance branch_distance = 47307028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org is_simple_map_transition ? Label::kNear : Label::kFar; 4731394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); 47327028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ j(not_equal, ¬_applicable, branch_distance); 47337028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (is_simple_map_transition) { 473494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register new_map_reg = ToRegister(instr->new_map_temp()); 47357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Handle<Map> map = instr->hydrogen()->transitioned_map(); 47367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ mov(FieldOperand(object_reg, HeapObject::kMapOffset), 47377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Immediate(map)); 4738394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Write barrier. 473956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT_NE(instr->temp(), NULL); 47407028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ RecordWriteForMap(object_reg, to_map, new_map_reg, 474156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ToRegister(instr->temp()), 47427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org kDontSaveFPRegs); 4743d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 474494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org PushSafepointRegistersScope scope(this); 474594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (!object_reg.is(eax)) { 474694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ push(object_reg); 474794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 474894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org LoadContextFromDeferred(instr->context()); 474994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (!object_reg.is(eax)) { 475094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ pop(eax); 475194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 475294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ mov(ebx, to_map); 475394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org TransitionElementsKindStub stub(from_kind, to_kind); 475494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ CallStub(&stub); 475594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org RecordSafepointWithRegisters( 475694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 4757394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 4758394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(¬_applicable); 4759394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 4760394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 4761394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 47620a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgvoid LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { 47630a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org class DeferredStringCharCodeAt: public LDeferredCode { 47640a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org public: 47650a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 47660a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org : LDeferredCode(codegen), instr_(instr) { } 47670a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } 4768c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual LInstruction* instr() { return instr_; } 47690a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org private: 47700a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org LStringCharCodeAt* instr_; 47710a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org }; 47720a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 47730a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org DeferredStringCharCodeAt* deferred = 47747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredStringCharCodeAt(this, instr); 47750a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 47760ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry StringCharLoadGenerator::Generate(masm(), 47770ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry factory(), 47780ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry ToRegister(instr->string()), 47790ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry ToRegister(instr->index()), 47800ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry ToRegister(instr->result()), 47810ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry deferred->entry()); 47820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ bind(deferred->exit()); 47830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 47840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 47850a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 47860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgvoid LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { 47870a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Register string = ToRegister(instr->string()); 47880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Register result = ToRegister(instr->result()); 47890a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 47900a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 47910a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // result register contain a valid pointer because it is already 47920a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // contained in the register pointer map. 47930a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ Set(result, Immediate(0)); 47940a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 479544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 47960a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ push(string); 47970a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Push the index as a smi. This is safe because of the checks in 47980a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // DoStringCharCodeAt above. 47990a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); 48000a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (instr->index()->IsConstantOperand()) { 4801fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Immediate immediate = ToImmediate(LConstantOperand::cast(instr->index()), 4802fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Representation::Smi()); 4803fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ push(immediate); 48040a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 48050a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Register index = ToRegister(instr->index()); 48060a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ SmiTag(index); 48070a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ push(index); 48080a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 4809ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, 4810ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org instr, instr->context()); 4811c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ AssertSmi(eax); 48120a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ SmiUntag(eax); 48133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ StoreToSafepointRegisterSlot(result, eax); 48140a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 48150a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 48160a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 4817b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.orgvoid LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { 4818b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org class DeferredStringCharFromCode: public LDeferredCode { 4819b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org public: 4820b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) 4821b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org : LDeferredCode(codegen), instr_(instr) { } 4822b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } 4823c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual LInstruction* instr() { return instr_; } 4824b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org private: 4825b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org LStringCharFromCode* instr_; 4826b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org }; 4827b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4828b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org DeferredStringCharFromCode* deferred = 48297028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredStringCharFromCode(this, instr); 4830b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4831b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); 4832b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register char_code = ToRegister(instr->char_code()); 4833b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register result = ToRegister(instr->result()); 4834b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org ASSERT(!char_code.is(result)); 4835b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 483659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(char_code, String::kMaxOneByteCharCode); 4837b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ j(above, deferred->entry()); 4838ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ Set(result, Immediate(factory()->single_character_string_cache())); 4839b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ mov(result, FieldOperand(result, 4840b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org char_code, times_pointer_size, 4841b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org FixedArray::kHeaderSize)); 4842ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmp(result, factory()->undefined_value()); 4843b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ j(equal, deferred->entry()); 4844b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ bind(deferred->exit()); 4845b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org} 4846b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4847b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4848b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.orgvoid LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { 4849b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register char_code = ToRegister(instr->char_code()); 4850b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register result = ToRegister(instr->result()); 4851b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4852b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 4853b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // result register contain a valid pointer because it is already 4854b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // contained in the register pointer map. 4855b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ Set(result, Immediate(0)); 4856b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 485744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 4858b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ SmiTag(char_code); 4859b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ push(char_code); 4860ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context()); 4861b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ StoreToSafepointRegisterSlot(result, eax); 4862b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org} 4863b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4864b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4865160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgvoid LCodeGen::DoStringAdd(LStringAdd* instr) { 486664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org EmitPushTaggedOperand(instr->left()); 486764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org EmitPushTaggedOperand(instr->right()); 4868ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org StringAddStub stub(instr->hydrogen()->flags()); 48698432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4870160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org} 4871160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 4872160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 4873a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4874a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (CpuFeatures::IsSupported(SSE2)) { 4875750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 4876a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org LOperand* input = instr->value(); 4877a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(input->IsRegister() || input->IsStackSlot()); 4878a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org LOperand* output = instr->result(); 4879a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(output->IsDoubleRegister()); 4880a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 4881a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 4882a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org UNREACHABLE(); 4883a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 4884a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4885a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4886a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4887a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { 4888a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register input = ToRegister(instr->value()); 4889a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ SmiTag(input); 4890a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (!instr->hydrogen()->value()->HasRange() || 4891a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org !instr->hydrogen()->value()->range()->IsInSmiRange()) { 4892a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org DeoptimizeIf(overflow, instr->environment()); 4893a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 4894a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org} 4895a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 4896a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 489746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4898750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 489956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 490046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org LOperand* output = instr->result(); 490156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* temp = instr->temp(); 490246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 490346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ LoadUint32(ToDoubleRegister(output), 490446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ToRegister(input), 490546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ToDoubleRegister(temp)); 490646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 490746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 490846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4909a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4910a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class DeferredNumberTagI: public LDeferredCode { 4911a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public: 4912a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 4913a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org : LDeferredCode(codegen), instr_(instr) { } 491446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org virtual void Generate() { 491556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org codegen()->DoDeferredNumberTagI(instr_, instr_->value(), SIGNED_INT32); 491646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } 4917c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual LInstruction* instr() { return instr_; } 4918a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private: 4919a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LNumberTagI* instr_; 4920a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org }; 4921a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 492256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 4923a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(input->IsRegister() && input->Equals(instr->result())); 4924a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register reg = ToRegister(input); 4925a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 49267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); 4927a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ SmiTag(reg); 4928a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ j(overflow, deferred->entry()); 4929a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(deferred->exit()); 4930a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4931a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4932a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 493346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid LCodeGen::DoNumberTagU(LNumberTagU* instr) { 493446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org class DeferredNumberTagU: public LDeferredCode { 493546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org public: 493646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 493746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org : LDeferredCode(codegen), instr_(instr) { } 493846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org virtual void Generate() { 493956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org codegen()->DoDeferredNumberTagI(instr_, instr_->value(), UNSIGNED_INT32); 494046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } 494146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org virtual LInstruction* instr() { return instr_; } 494246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org private: 494346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org LNumberTagU* instr_; 494446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org }; 494546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 494656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 494746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ASSERT(input->IsRegister() && input->Equals(instr->result())); 494846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Register reg = ToRegister(input); 494946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 495046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 495146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ cmp(reg, Immediate(Smi::kMaxValue)); 495246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ j(above, deferred->entry()); 495346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ SmiTag(reg); 495446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ bind(deferred->exit()); 495546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 495646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 495746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 495846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid LCodeGen::DoDeferredNumberTagI(LInstruction* instr, 495946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org LOperand* value, 496046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org IntegerSignedness signedness) { 4961a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Label slow; 496246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Register reg = ToRegister(value); 4963a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register tmp = reg.is(eax) ? ecx : eax; 4964a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4965a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Preserve the value of all registers. 496644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 4967a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 496883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 496946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 497046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if (signedness == SIGNED_INT32) { 497146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // There was overflow, so bits 30 and 31 of the original integer 497246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // disagree. Try to allocate a heap number in new space and store 497346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // the value in there. If that fails, call the runtime system. 497446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ SmiUntag(reg); 497546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ xor_(reg, 0x80000000); 4976a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (CpuFeatures::IsSupported(SSE2)) { 4977750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope feature_scope(masm(), SSE2); 4978a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ cvtsi2sd(xmm0, Operand(reg)); 4979a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 4980a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ push(reg); 4981a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ fild_s(Operand(esp, 0)); 4982a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ pop(reg); 4983a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 498446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } else { 4985a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (CpuFeatures::IsSupported(SSE2)) { 4986750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope feature_scope(masm(), SSE2); 49871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ LoadUint32(xmm0, reg, 49881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ToDoubleRegister(LNumberTagU::cast(instr)->temp())); 4989a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 4990068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org // There's no fild variant for unsigned values, so zero-extend to a 64-bit 4991068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org // int manually. 4992068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org __ push(Immediate(0)); 4993068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org __ push(reg); 4994068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org __ fild_d(Operand(esp, 0)); 4995068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org __ pop(reg); 4996068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org __ pop(reg); 4997a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 499846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } 499946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 5000a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (FLAG_inline_new) { 5001a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ AllocateHeapNumber(reg, tmp, no_reg, &slow); 500283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 5003a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5004a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5005a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Slow case: Call the runtime system to do the number allocation. 5006a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&slow); 5007a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5008a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // TODO(3095996): Put a valid pointer value in the stack slot where the result 5009a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // register is stored, as this register is in the pointer map, but contains an 5010a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // integer value. 50113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ StoreToSafepointRegisterSlot(reg, Immediate(0)); 5012ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // NumberTagI and NumberTagD use the context from the frame, rather than 5013ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // the environment's HContext or HInlinedContext value. 5014ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // They only call Runtime::kAllocateHeapNumber. 5015ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // The corresponding HChange instructions are added in a phase that does 5016ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // not have easy access to the local context. 5017ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 5018ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 5019ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org RecordSafepointWithRegisters( 502027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 5021a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (!reg.is(eax)) __ mov(reg, eax); 5022a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5023a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Done. Put the value in xmm0 into the value of the allocated heap 5024a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // number. 5025a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&done); 5026a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (CpuFeatures::IsSupported(SSE2)) { 5027750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope feature_scope(masm(), SSE2); 5028a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0); 5029a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 5030a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); 5031a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 50323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ StoreToSafepointRegisterSlot(reg, reg); 5033a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5034a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5035a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5036a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoNumberTagD(LNumberTagD* instr) { 5037a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class DeferredNumberTagD: public LDeferredCode { 5038a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public: 5039a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 5040a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org : LDeferredCode(codegen), instr_(instr) { } 5041a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 5042c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual LInstruction* instr() { return instr_; } 5043a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private: 5044a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LNumberTagD* instr_; 5045a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org }; 5046a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5047a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register reg = ToRegister(instr->result()); 5048a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5049169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org bool use_sse2 = CpuFeatures::IsSupported(SSE2); 5050169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (!use_sse2) { 5051169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Put the value to the top of stack 5052169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Register src = ToX87Register(instr->value()); 5053169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87LoadForUsage(src); 5054169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 5055169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 50567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 5057a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (FLAG_inline_new) { 5058068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org Register tmp = ToRegister(instr->temp()); 5059a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); 5060a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 5061a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ jmp(deferred->entry()); 5062a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5063a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(deferred->exit()); 5064169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (use_sse2) { 5065750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 5066a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 5067a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 5068a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 5069169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); 5070a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 5071a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5072a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5073a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5074a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 5075a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 5076a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // result register contain a valid pointer because it is already 5077a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // contained in the register pointer map. 5078a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register reg = ToRegister(instr->result()); 5079a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ Set(reg, Immediate(0)); 5080a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 508144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 5082ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // NumberTagI and NumberTagD use the context from the frame, rather than 5083ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // the environment's HContext or HInlinedContext value. 5084ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // They only call Runtime::kAllocateHeapNumber. 5085ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // The corresponding HChange instructions are added in a phase that does 5086ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // not have easy access to the local context. 5087ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 5088ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 508927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepointWithRegisters( 509027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 50913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ StoreToSafepointRegisterSlot(reg, eax); 5092a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5093a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5094a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5095a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoSmiTag(LSmiTag* instr) { 509656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5097a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(input->IsRegister() && input->Equals(instr->result())); 5098a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 5099a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ SmiTag(ToRegister(input)); 5100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoSmiUntag(LSmiUntag* instr) { 510456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5105a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register result = ToRegister(input); 5106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(input->IsRegister() && input->Equals(instr->result())); 5107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (instr->needs_check()) { 5108a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ test(result, Immediate(kSmiTagMask)); 5109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(not_zero, instr->environment()); 51107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } else { 5111a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ AssertSmi(result); 5112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5113a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ SmiUntag(result); 5114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5117e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::EmitNumberUntagDNoSSE2(Register input_reg, 5118e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register temp_reg, 5119169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87Register res_reg, 5120c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org bool can_convert_undefined_to_nan, 5121e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool deoptimize_on_minus_zero, 5122e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org LEnvironment* env, 5123e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org NumberUntagDMode mode) { 5124e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label load_smi, done; 5125e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5126169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87PrepareToWrite(res_reg); 5127c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 5128e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Smi check. 5129e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ JumpIfSmi(input_reg, &load_smi, Label::kNear); 5130e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5131e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Heap number map check. 5132e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5133e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org factory()->heap_number_map()); 5134c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (!can_convert_undefined_to_nan) { 5135e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(not_equal, env); 5136e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 5137c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Label heap_number, convert; 5138e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(equal, &heap_number, Label::kNear); 5139e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5140c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org // Convert undefined (or hole) to NaN. 5141e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(input_reg, factory()->undefined_value()); 5142e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(not_equal, env); 5143e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5144c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org __ bind(&convert); 5145e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ExternalReference nan = 5146e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ExternalReference::address_of_canonical_non_hole_nan(); 5147e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fld_d(Operand::StaticVariable(nan)); 5148e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ jmp(&done, Label::kNear); 5149c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 5150e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&heap_number); 5151e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5152e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Heap number to x87 conversion. 5153e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 5154e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (deoptimize_on_minus_zero) { 5155e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fldz(); 5156e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ FCmp(); 5157e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 5158e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(not_zero, &done, Label::kNear); 5159e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5160e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Use general purpose registers to check if we have -0.0 5161e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(temp_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 5162e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ test(temp_reg, Immediate(HeapNumber::kSignMask)); 5163e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(zero, &done, Label::kNear); 5164e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5165e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Pop FPU stack before deoptimizing. 5166e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fstp(0); 5167e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(not_zero, env); 5168e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5169e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ jmp(&done, Label::kNear); 5170e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 5171e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); 5172e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5173e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5174e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&load_smi); 5175e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ SmiUntag(input_reg); // Untag smi before converting to float. 5176e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ push(input_reg); 5177e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ fild_s(Operand(esp, 0)); 5178e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ pop(input_reg); 5179e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ SmiTag(input_reg); // Retag smi. 5180e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&done); 5181169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org X87CommitWrite(res_reg); 5182e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 5183e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5184e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::EmitNumberUntagD(Register input_reg, 5186f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Register temp_reg, 5187a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org XMMRegister result_reg, 5188c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org bool can_convert_undefined_to_nan, 5189f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com bool deoptimize_on_minus_zero, 519094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org LEnvironment* env, 519194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org NumberUntagDMode mode) { 51926d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Label load_smi, done; 5193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5194c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 519594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // Smi check. 519694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ JumpIfSmi(input_reg, &load_smi, Label::kNear); 5197a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 519894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // Heap number map check. 519994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 520094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org factory()->heap_number_map()); 5201c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (!can_convert_undefined_to_nan) { 520294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org DeoptimizeIf(not_equal, env); 520394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } else { 5204c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Label heap_number, convert; 520594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ j(equal, &heap_number, Label::kNear); 5206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5207c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org // Convert undefined (and hole) to NaN. 520894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ cmp(input_reg, factory()->undefined_value()); 520994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org DeoptimizeIf(not_equal, env); 5210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5211c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org __ bind(&convert); 521294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ExternalReference nan = 521394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ExternalReference::address_of_canonical_non_hole_nan(); 521494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ movdbl(result_reg, Operand::StaticVariable(nan)); 521594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ jmp(&done, Label::kNear); 5216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 521794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ bind(&heap_number); 521894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 521994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // Heap number to XMM conversion. 522094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); 522194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (deoptimize_on_minus_zero) { 522294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org XMMRegister xmm_scratch = xmm0; 522394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ xorps(xmm_scratch, xmm_scratch); 522494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ ucomisd(result_reg, xmm_scratch); 522594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ j(not_zero, &done, Label::kNear); 522694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ movmskpd(temp_reg, result_reg); 522794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ test_b(temp_reg, 1); 522894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org DeoptimizeIf(not_zero, env); 522994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 523094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ jmp(&done, Label::kNear); 523194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } else { 523294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); 5233f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } 5234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Smi to XMM conversion 5236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&load_smi); 5237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ SmiUntag(input_reg); // Untag smi before converting to float. 5238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cvtsi2sd(result_reg, Operand(input_reg)); 5239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ SmiTag(input_reg); // Retag smi. 5240a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&done); 5241a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5242a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5243a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5244a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 524583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done, heap_number; 524656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input_reg = ToRegister(instr->value()); 5247a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5248a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Heap number map check. 5249a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5250ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org factory()->heap_number_map()); 5251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (instr->truncating()) { 525383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &heap_number, Label::kNear); 5254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Check for undefined. Undefined is converted to zero for truncating 5255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // conversions. 5256ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmp(input_reg, factory()->undefined_value()); 5257fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ RecordComment("Deferred TaggedToI: cannot truncate"); 5258a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5259a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(input_reg, 0); 526083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 5261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&heap_number); 5263c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (CpuFeatures::IsSupported(SSE3)) { 5264750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE3); 526583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label convert; 5266a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Use more powerful conversion when sse3 is available. 5267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Load x87 register with heap number. 5268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 5269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Get exponent alone and check for too-big exponent. 5270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 5271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ and_(input_reg, HeapNumber::kExponentMask); 5272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const uint32_t kTooBigExponent = 5273a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; 5274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(Operand(input_reg), Immediate(kTooBigExponent)); 527583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(less, &convert, Label::kNear); 5276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Pop FPU stack before deoptimizing. 52771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ fstp(0); 5278fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ RecordComment("Deferred TaggedToI: exponent too big"); 5279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(no_condition, instr->environment()); 5280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Reserve space for 64 bit answer. 5282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&convert); 5283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ sub(Operand(esp), Immediate(kDoubleSize)); 5284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Do conversion, which cannot fail because we checked the exponent. 5285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ fisttp_d(Operand(esp, 0)); 5286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result. 5287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ add(Operand(esp), Immediate(kDoubleSize)); 5288e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else if (CpuFeatures::IsSupported(SSE2)) { 5289750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 529056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 5291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5292a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cvttsd2si(input_reg, Operand(xmm0)); 5293a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(input_reg, 0x80000000u); 5294a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ j(not_equal, &done); 5295a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Check if the input was 0x8000000 (kMinInt). 5296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // If no, then we got an overflow and we deoptimize. 5297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ExternalReference min_int = ExternalReference::address_of_min_int(); 5298a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ movdbl(xmm_temp, Operand::StaticVariable(min_int)); 5299a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ucomisd(xmm_temp, xmm0); 5300a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5301a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(parity_even, instr->environment()); // NaN. 5302e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 5303e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org UNREACHABLE(); 5304a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5305a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else if (CpuFeatures::IsSupported(SSE2)) { 5306750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 5307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Deoptimize if we don't have a heap number. 5308fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ RecordComment("Deferred TaggedToI: not a heap number"); 5309a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5310a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 531156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 5312a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cvttsd2si(input_reg, Operand(xmm0)); 5314a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cvtsi2sd(xmm_temp, Operand(input_reg)); 5315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ucomisd(xmm0, xmm_temp); 5316fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ RecordComment("Deferred TaggedToI: lost precision"); 5317a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5318fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ RecordComment("Deferred TaggedToI: NaN"); 5319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(parity_even, instr->environment()); // NaN. 5320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5321a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(input_reg, Operand(input_reg)); 5322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ j(not_zero, &done); 5323a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ movmskpd(input_reg, xmm0); 5324a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ and_(input_reg, 1); 5325fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ RecordComment("Deferred TaggedToI: minus zero"); 5326a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(not_zero, instr->environment()); 5327a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5328a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 5329a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org UNREACHABLE(); 5330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&done); 5332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5333a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5334a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5335a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoTaggedToI(LTaggedToI* instr) { 5336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class DeferredTaggedToI: public LDeferredCode { 5337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 5338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 5339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : LDeferredCode(codegen), instr_(instr) { } 5340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 5341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual LInstruction* instr() { return instr_; } 5342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 5343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LTaggedToI* instr_; 5344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 5345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 534656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5347a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(input->IsRegister()); 5348a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register input_reg = ToRegister(input); 5349e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(input_reg.is(ToRegister(instr->result()))); 5350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 53517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); 5352a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 53537b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org __ JumpIfNotSmi(input_reg, deferred->entry()); 5354e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ SmiUntag(input_reg); 5355e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(deferred->exit()); 5356e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 5357a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5358a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5359e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoDeferredTaggedToINoSSE2(LTaggedToINoSSE2* instr) { 5360e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label done, heap_number; 5361e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register result_reg = ToRegister(instr->result()); 5362e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register input_reg = ToRegister(instr->value()); 5363e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5364e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Heap number map check. 5365e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5366e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org factory()->heap_number_map()); 5367b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org if (instr->truncating()) { 5368b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ j(equal, &heap_number, Label::kNear); 5369b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org // Check for undefined. Undefined is converted to zero for truncating 5370b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org // conversions. 5371b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ cmp(input_reg, factory()->undefined_value()); 5372b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ RecordComment("Deferred TaggedToI: cannot truncate"); 5373b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5374b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ xor_(result_reg, result_reg); 5375b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ jmp(&done, Label::kFar); 5376b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ bind(&heap_number); 5377b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org } else { 5378b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org // Deoptimize if we don't have a heap number. 5379b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5380b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org } 5381e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5382e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Surprisingly, all of this crazy bit manipulation is considerably 5383e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // faster than using the built-in x86 CPU conversion functions (about 6x). 5384e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label right_exponent, adjust_bias, zero_result; 5385e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register scratch = ToRegister(instr->scratch()); 5386e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register scratch2 = ToRegister(instr->scratch2()); 5387e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Get exponent word. 5388e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(scratch, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 5389e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Get exponent alone in scratch2. 5390e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(scratch2, scratch); 5391e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ and_(scratch2, HeapNumber::kExponentMask); 5392e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ shr(scratch2, HeapNumber::kExponentShift); 5393e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (instr->truncating()) { 5394e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(zero, &zero_result); 5395e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 5396e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(not_zero, &adjust_bias); 5397e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ test(scratch, Immediate(HeapNumber::kMantissaMask)); 5398e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(not_zero, instr->environment()); 5399e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(FieldOperand(input_reg, HeapNumber::kMantissaOffset), Immediate(0)); 5400e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5401e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&adjust_bias); 5402e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5403e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ sub(scratch2, Immediate(HeapNumber::kExponentBias)); 5404e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (!instr->truncating()) { 5405e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(negative, instr->environment()); 5406e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 5407e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(negative, &zero_result); 5408e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5409e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5410e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Get the second half of the double. For some exponents we don't 5411e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // actually need this because the bits get shifted out again, but 5412e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // it's probably slower to test than just to do it. 5413e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register scratch3 = ToRegister(instr->scratch3()); 5414e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(scratch3, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); 5415e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ xor_(result_reg, result_reg); 5416e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5417e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const uint32_t non_int32_exponent = 31; 5418e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(scratch2, Immediate(non_int32_exponent)); 5419e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If we have a match of the int32 exponent then skip some logic. 5420e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(equal, &right_exponent, Label::kNear); 5421e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If the number doesn't find in an int32, deopt. 5422e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(greater, instr->environment()); 5423e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5424e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Exponent word in scratch, exponent in scratch2. We know that 0 <= exponent 5425e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // < 31. 5426e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(result_reg, Immediate(31)); 5427e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ sub(result_reg, scratch2); 5428e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5429e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&right_exponent); 5430e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5431e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Save off exponent for negative check later. 5432e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(scratch2, scratch); 5433e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5434e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Here result_reg is the shift, scratch is the exponent word. 5435e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Get the top bits of the mantissa. 5436e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ and_(scratch, HeapNumber::kMantissaMask); 5437e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Put back the implicit 1. 5438e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ or_(scratch, 1 << HeapNumber::kExponentShift); 5439e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Shift up the mantissa bits to take up the space the exponent used to 5440e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // take. We have kExponentShift + 1 significant bits int he low end of the 5441e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // word. Shift them to the top bits. 5442e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 1; 5443e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ shl(scratch, shift_distance); 5444e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (!instr->truncating()) { 5445e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If not truncating, a non-zero value in the bottom 22 bits means a 5446e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // non-integral value --> trigger a deopt. 5447e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ test(scratch3, Immediate((1 << (32 - shift_distance)) - 1)); 5448e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5449e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5450e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Shift down 22 bits to get the most significant 10 bits or the low 5451e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // mantissa word. 5452e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ shr(scratch3, 32 - shift_distance); 5453e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ or_(scratch3, scratch); 5454e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (!instr->truncating()) { 5455e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If truncating, a non-zero value in the bits that will be shifted away 5456e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // when adjusting the exponent means rounding --> deopt. 5457e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(scratch, 0x1); 5458e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(result_reg.is(ecx)); 5459e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ shl_cl(scratch); 5460e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ dec(scratch); 5461e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ test(scratch3, scratch); 5462e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5463e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5464e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Move down according to the exponent. 5465e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(result_reg.is(ecx)); 5466e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ shr_cl(scratch3); 5467e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Now the unsigned 32-bit answer is in scratch3. We need to move it to 5468e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // result_reg and we may need to fix the sign. 5469e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label negative_result; 5470e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ xor_(result_reg, result_reg); 5471e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(scratch2, result_reg); 5472e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(less, &negative_result, Label::kNear); 5473e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(scratch3, result_reg); 5474e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(result_reg, scratch3); 5475e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If the result is > MAX_INT, result doesn't fit in signed 32-bit --> deopt. 5476e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(less, instr->environment()); 5477e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ jmp(&done, Label::kNear); 5478e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&zero_result); 5479e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ xor_(result_reg, result_reg); 5480e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ jmp(&done, Label::kNear); 5481e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&negative_result); 5482e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ sub(result_reg, scratch3); 5483e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (!instr->truncating()) { 5484e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // -0.0 triggers a deopt. 5485e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(zero, instr->environment()); 5486e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5487e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If the negative subtraction overflows into a positive number, there was an 5488e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // overflow --> deopt. 5489e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(positive, instr->environment()); 5490e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&done); 5491e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 5492e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5493e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5494e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoTaggedToINoSSE2(LTaggedToINoSSE2* instr) { 5495e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org class DeferredTaggedToINoSSE2: public LDeferredCode { 5496e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org public: 5497e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeferredTaggedToINoSSE2(LCodeGen* codegen, LTaggedToINoSSE2* instr) 5498e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org : LDeferredCode(codegen), instr_(instr) { } 5499e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org virtual void Generate() { codegen()->DoDeferredTaggedToINoSSE2(instr_); } 5500e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org virtual LInstruction* instr() { return instr_; } 5501e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org private: 5502e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org LTaggedToINoSSE2* instr_; 5503e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org }; 5504e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5505e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org LOperand* input = instr->value(); 5506e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(input->IsRegister()); 5507e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register input_reg = ToRegister(input); 5508e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(input_reg.is(ToRegister(instr->result()))); 5509e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5510e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeferredTaggedToINoSSE2* deferred = 5511e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org new(zone()) DeferredTaggedToINoSSE2(this, instr); 5512e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5513e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Smi check. 5514e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ JumpIfNotSmi(input_reg, deferred->entry()); 5515e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ SmiUntag(input_reg); // Untag smi. 5516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(deferred->exit()); 5517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 552156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5522a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(input->IsRegister()); 552356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* temp = instr->temp(); 5524f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ASSERT(temp == NULL || temp->IsRegister()); 5525a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LOperand* result = instr->result(); 5526a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(result->IsDoubleRegister()); 5527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5528e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register input_reg = ToRegister(input); 5529e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool deoptimize_on_minus_zero = 5530e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org instr->hydrogen()->deoptimize_on_minus_zero(); 5531e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register temp_reg = deoptimize_on_minus_zero ? ToRegister(temp) : no_reg; 5532e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5533e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org HValue* value = instr->hydrogen()->value(); 5534c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org NumberUntagDMode mode = value->representation().IsSmi() 5535c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED; 553694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 5537e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (CpuFeatures::IsSupported(SSE2)) { 5538e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CpuFeatureScope scope(masm(), SSE2); 5539e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org XMMRegister result_reg = ToDoubleRegister(result); 5540a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org EmitNumberUntagD(input_reg, 5541a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org temp_reg, 5542a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org result_reg, 5543c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org instr->hydrogen()->can_convert_undefined_to_nan(), 5544a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org deoptimize_on_minus_zero, 554594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org instr->environment(), 554694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org mode); 5547a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 5548e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org EmitNumberUntagDNoSSE2(input_reg, 5549e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org temp_reg, 5550169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ToX87Register(instr->result()), 5551c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org instr->hydrogen()->can_convert_undefined_to_nan(), 5552e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org deoptimize_on_minus_zero, 5553e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org instr->environment(), 5554e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mode); 5555a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 5556a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5557a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5558a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5559a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoDoubleToI(LDoubleToI* instr) { 556056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5561a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(input->IsDoubleRegister()); 5562a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LOperand* result = instr->result(); 5563a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(result->IsRegister()); 5564750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 5565a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org XMMRegister input_reg = ToDoubleRegister(input); 5567a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register result_reg = ToRegister(result); 5568a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5569169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ cvttsd2si(result_reg, Operand(input_reg)); 5570169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 5571a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (instr->truncating()) { 5572a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Performs a truncating conversion of a floating point number as used by 5573a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // the JS bitwise operations. 5574169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Label fast_case_succeeded; 5575a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(result_reg, 0x80000000u); 5576169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ j(not_equal, &fast_case_succeeded); 5577169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ sub(esp, Immediate(kDoubleSize)); 5578169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ movdbl(MemOperand(esp, 0), input_reg); 5579169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org DoubleToIStub stub(esp, result_reg, 0, true); 5580169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); 5581169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ add(esp, Immediate(kDoubleSize)); 5582169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ bind(&fast_case_succeeded); 5583a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 558483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 5585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cvtsi2sd(xmm0, Operand(result_reg)); 5586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ucomisd(xmm0, input_reg); 5587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(parity_even, instr->environment()); // NaN. 5589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5590a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // The integer converted back is equal to the original. We 5591a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // only have to test if we got -0 as an input. 5592a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test(result_reg, Operand(result_reg)); 559383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_zero, &done, Label::kNear); 5594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ movmskpd(result_reg, input_reg); 5595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Bit 0 contains the sign of the double in input_reg. 5596a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // If input was positive, we are ok and return 0, otherwise 5597a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // deoptimize. 5598a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ and_(result_reg, 1); 5599a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(not_zero, instr->environment()); 5600a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5601a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&done); 5602a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5603a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5604a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5605a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5606a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 5607a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org LOperand* input = instr->value(); 5608a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ASSERT(input->IsDoubleRegister()); 5609a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org LOperand* result = instr->result(); 5610a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ASSERT(result->IsRegister()); 5611a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org CpuFeatureScope scope(masm(), SSE2); 5612a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5613a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org XMMRegister input_reg = ToDoubleRegister(input); 5614a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register result_reg = ToRegister(result); 5615a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5616a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Label done; 5617a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ cvttsd2si(result_reg, Operand(input_reg)); 5618a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ cvtsi2sd(xmm0, Operand(result_reg)); 5619a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ ucomisd(xmm0, input_reg); 5620a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5621a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org DeoptimizeIf(parity_even, instr->environment()); // NaN. 5622a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5623a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5624a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org // The integer converted back is equal to the original. We 5625a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org // only have to test if we got -0 as an input. 5626a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ test(result_reg, Operand(result_reg)); 5627a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ j(not_zero, &done, Label::kNear); 5628a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ movmskpd(result_reg, input_reg); 5629a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org // Bit 0 contains the sign of the double in input_reg. 5630a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org // If input was positive, we are ok and return 0, otherwise 5631a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org // deoptimize. 5632a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ and_(result_reg, 1); 5633a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org DeoptimizeIf(not_zero, instr->environment()); 5634a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ bind(&done); 5635a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 5636a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ SmiTag(result_reg); 5637a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org DeoptimizeIf(overflow, instr->environment()); 5638a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org} 5639a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5640a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5641a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCheckSmi(LCheckSmi* instr) { 564256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 56434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org __ test(ToOperand(input), Immediate(kSmiTagMask)); 5644badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org DeoptimizeIf(not_zero, instr->environment()); 5645badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org} 5646badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 5647badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 5648badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 56491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!instr->hydrogen()->value()->IsHeapObject()) { 56501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org LOperand* input = instr->value(); 56511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ test(ToOperand(input), Immediate(kSmiTagMask)); 56521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org DeoptimizeIf(zero, instr->environment()); 56531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 5654a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5655a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5656a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5657a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 565856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 565956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 5660a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 5662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 566383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (instr->hydrogen()->is_interval_check()) { 566483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org InstanceType first; 566583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org InstanceType last; 566683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org instr->hydrogen()->GetCheckInterval(&first, &last); 566783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 56680a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 56690a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org static_cast<int8_t>(first)); 567083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 567183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // If there is only one type in the interval check for equality. 567283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (first == last) { 567383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org DeoptimizeIf(not_equal, instr->environment()); 567483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 567583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org DeoptimizeIf(below, instr->environment()); 567683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Omit check for the last type. 567783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (last != LAST_TYPE) { 567883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 567983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static_cast<int8_t>(last)); 568083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org DeoptimizeIf(above, instr->environment()); 568183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 568283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 568383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 568483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org uint8_t mask; 568583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org uint8_t tag; 568683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); 568783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 568883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (IsPowerOf2(mask)) { 568983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(tag == 0 || IsPowerOf2(tag)); 569083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), mask); 569183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org DeoptimizeIf(tag == 0 ? not_zero : zero, instr->environment()); 569283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 569383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); 569483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ and_(temp, mask); 569556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ cmp(temp, tag); 569683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5697a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5698a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5699a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5700a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5701a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5702a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCheckFunction(LCheckFunction* instr) { 5703c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Handle<JSFunction> target = instr->hydrogen()->target(); 5704003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (instr->hydrogen()->target_in_new_space()) { 5705c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register reg = ToRegister(instr->value()); 570641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(target); 570741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ cmp(reg, Operand::ForCell(cell)); 5708c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 5709c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Operand operand = ToOperand(instr->value()); 571064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ cmp(operand, target); 5711c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 5712a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5713a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5714a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5715a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5716594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 5717594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org { 5718594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org PushSafepointRegistersScope scope(this); 5719594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ push(object); 5720594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ xor_(esi, esi); 5721594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ CallRuntimeSaveDoubles(Runtime::kMigrateInstance); 5722594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org RecordSafepointWithRegisters( 5723594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org instr->pointer_map(), 1, Safepoint::kNoLazyDeopt); 5724594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5725594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ test(eax, Immediate(kSmiTagMask)); 5726594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5727594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeoptimizeIf(zero, instr->environment()); 5728f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 5729f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 5730f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 57311456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid LCodeGen::DoCheckMaps(LCheckMaps* instr) { 5732594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org class DeferredCheckMaps: public LDeferredCode { 5733594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org public: 5734594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) 5735594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org : LDeferredCode(codegen), instr_(instr), object_(object) { 5736594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org SetExit(check_maps()); 5737594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5738594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org virtual void Generate() { 5739594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org codegen()->DoDeferredInstanceMigration(instr_, object_); 5740594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5741594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label* check_maps() { return &check_maps_; } 5742594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org virtual LInstruction* instr() { return instr_; } 5743594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org private: 5744594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org LCheckMaps* instr_; 5745594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label check_maps_; 5746594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Register object_; 5747594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org }; 5748594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5749c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (instr->hydrogen()->CanOmitMapChecks()) return; 5750594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 575156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5752a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(input->IsRegister()); 5753a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register reg = ToRegister(input); 57541456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 5755abafe3dbcc62abc040625a8356be42bbd0cf7608danno@chromium.org SmallMapList* map_set = instr->hydrogen()->map_set(); 5756594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5757594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeferredCheckMaps* deferred = NULL; 5758594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (instr->hydrogen()->has_migration_target()) { 5759594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org deferred = new(zone()) DeferredCheckMaps(this, instr, reg); 5760594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ bind(deferred->check_maps()); 5761594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5762594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5763594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label success; 57641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org for (int i = 0; i < map_set->length() - 1; i++) { 57651456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Handle<Map> map = map_set->at(i); 5766a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ CompareMap(reg, map, &success); 57671456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ j(equal, &success); 57681456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 5769594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 57701456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Handle<Map> map = map_set->last(); 5771594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ CompareMap(reg, map, &success); 5772594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (instr->hydrogen()->has_migration_target()) { 5773594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ j(not_equal, deferred->entry()); 5774594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 5775594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5776594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5777594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 57781456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ bind(&success); 5779a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5780a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5782c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 5783750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 5784c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org XMMRegister value_reg = ToDoubleRegister(instr->unclamped()); 5785c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register result_reg = ToRegister(instr->result()); 5786c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ ClampDoubleToUint8(value_reg, xmm0, result_reg); 5787c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 5788c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5789c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5790c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 5791c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(instr->unclamped()->Equals(instr->result())); 5792c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register value_reg = ToRegister(instr->result()); 5793c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ ClampUint8(value_reg); 5794c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 5795c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5796c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5797c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 5798750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE2); 5799a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 5800c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(instr->unclamped()->Equals(instr->result())); 5801c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register input_reg = ToRegister(instr->unclamped()); 5802c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label is_smi, done, heap_number; 5803c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5804c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ JumpIfSmi(input_reg, &is_smi); 5805c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5806c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check for heap number 5807c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5808c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org factory()->heap_number_map()); 5809c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ j(equal, &heap_number, Label::kNear); 5810c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5811c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check for undefined. Undefined is converted to zero for clamping 5812c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // conversions. 5813c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ cmp(input_reg, factory()->undefined_value()); 5814c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5815c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ mov(input_reg, 0); 5816c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ jmp(&done, Label::kNear); 5817c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5818c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Heap number 5819c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&heap_number); 5820c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5821c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ ClampDoubleToUint8(xmm0, xmm1, input_reg); 5822c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ jmp(&done, Label::kNear); 5823c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5824c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // smi 5825c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&is_smi); 5826c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ SmiUntag(input_reg); 5827c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ ClampUint8(input_reg); 5828e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&done); 5829e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 5830e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5831e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5832e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoClampTToUint8NoSSE2(LClampTToUint8NoSSE2* instr) { 5833e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register input_reg = ToRegister(instr->unclamped()); 5834e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register result_reg = ToRegister(instr->result()); 5835e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register scratch = ToRegister(instr->scratch()); 5836e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register scratch2 = ToRegister(instr->scratch2()); 5837e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Register scratch3 = ToRegister(instr->scratch3()); 5838e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label is_smi, done, heap_number, valid_exponent, 5839e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org largest_value, zero_result, maybe_nan_or_infinity; 5840c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5841e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ JumpIfSmi(input_reg, &is_smi); 5842e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5843e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Check for heap number 5844e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5845e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org factory()->heap_number_map()); 5846e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(equal, &heap_number, Label::kFar); 5847e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5848e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Check for undefined. Undefined is converted to zero for clamping 5849e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // conversions. 5850e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(input_reg, factory()->undefined_value()); 5851e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5852e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ jmp(&zero_result); 5853e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5854e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Heap number 5855e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&heap_number); 5856e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5857e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Surprisingly, all of the hand-crafted bit-manipulations below are much 5858e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // faster than the x86 FPU built-in instruction, especially since "banker's 5859e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // rounding" would be additionally very expensive 5860e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5861e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Get exponent word. 5862e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(scratch, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 5863e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(scratch3, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); 5864e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5865e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Test for negative values --> clamp to zero 5866e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ test(scratch, scratch); 5867e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(negative, &zero_result); 5868e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5869e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Get exponent alone in scratch2. 5870e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(scratch2, scratch); 5871e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ and_(scratch2, HeapNumber::kExponentMask); 5872e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ shr(scratch2, HeapNumber::kExponentShift); 5873e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(zero, &zero_result); 5874e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ sub(scratch2, Immediate(HeapNumber::kExponentBias - 1)); 5875e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(negative, &zero_result); 5876e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5877e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const uint32_t non_int8_exponent = 7; 5878e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(scratch2, Immediate(non_int8_exponent + 1)); 5879e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If the exponent is too big, check for special values. 5880e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(greater, &maybe_nan_or_infinity, Label::kNear); 5881e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5882e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&valid_exponent); 5883e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Exponent word in scratch, exponent in scratch2. We know that 0 <= exponent 5884e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // < 7. The shift bias is the number of bits to shift the mantissa such that 5885e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // with an exponent of 7 such the that top-most one is in bit 30, allowing 5886e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // detection the rounding overflow of a 255.5 to 256 (bit 31 goes from 0 to 5887e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // 1). 5888e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int shift_bias = (30 - HeapNumber::kExponentShift) - 7 - 1; 5889e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ lea(result_reg, MemOperand(scratch2, shift_bias)); 5890e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Here result_reg (ecx) is the shift, scratch is the exponent word. Get the 5891e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // top bits of the mantissa. 5892e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ and_(scratch, HeapNumber::kMantissaMask); 5893e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Put back the implicit 1 of the mantissa 5894e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ or_(scratch, 1 << HeapNumber::kExponentShift); 5895e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Shift up to round 5896e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ shl_cl(scratch); 5897e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Use "banker's rounding" to spec: If fractional part of number is 0.5, then 5898e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // use the bit in the "ones" place and add it to the "halves" place, which has 5899e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // the effect of rounding to even. 5900e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(scratch2, scratch); 5901e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const uint32_t one_half_bit_shift = 30 - sizeof(uint8_t) * 8; 5902e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const uint32_t one_bit_shift = one_half_bit_shift + 1; 5903e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ and_(scratch2, Immediate((1 << one_bit_shift) - 1)); 5904e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(scratch2, Immediate(1 << one_half_bit_shift)); 5905e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label no_round; 5906e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(less, &no_round); 5907e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label round_up; 5908e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(scratch2, Immediate(1 << one_half_bit_shift)); 5909e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(greater, &round_up); 5910e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ test(scratch3, scratch3); 5911e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(not_zero, &round_up); 5912e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(scratch2, scratch); 5913e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ and_(scratch2, Immediate(1 << one_bit_shift)); 5914e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ shr(scratch2, 1); 5915e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&round_up); 5916e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ add(scratch, scratch2); 5917e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(overflow, &largest_value); 5918e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&no_round); 5919e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ shr(scratch, 23); 5920e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(result_reg, scratch); 5921e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ jmp(&done, Label::kNear); 5922e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5923e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&maybe_nan_or_infinity); 5924e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Check for NaN/Infinity, all other values map to 255 5925e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cmp(scratch2, Immediate(HeapNumber::kInfinityOrNanExponent + 1)); 5926e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(not_equal, &largest_value, Label::kNear); 5927e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5928e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Check for NaN, which differs from Infinity in that at least one mantissa 5929e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // bit is set. 5930e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ and_(scratch, HeapNumber::kMantissaMask); 5931e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ or_(scratch, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); 5932e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(not_zero, &zero_result); // M!=0 --> NaN 5933e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Infinity -> Fall through to map to 255. 5934e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5935e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&largest_value); 5936e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(result_reg, Immediate(255)); 5937e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ jmp(&done, Label::kNear); 5938e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5939e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&zero_result); 5940e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ xor_(result_reg, result_reg); 5941e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ jmp(&done); 5942e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5943e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // smi 5944e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&is_smi); 5945e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (!input_reg.is(result_reg)) { 5946e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(result_reg, input_reg); 5947e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5948e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ SmiUntag(result_reg); 5949e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ ClampUint8(result_reg); 5950c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&done); 5951c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 5952c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5953c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 595494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::DoAllocate(LAllocate* instr) { 595594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org class DeferredAllocate: public LDeferredCode { 595694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org public: 595794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org DeferredAllocate(LCodeGen* codegen, LAllocate* instr) 595894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org : LDeferredCode(codegen), instr_(instr) { } 595994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org virtual void Generate() { codegen()->DoDeferredAllocate(instr_); } 596094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org virtual LInstruction* instr() { return instr_; } 596194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org private: 596294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org LAllocate* instr_; 596394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org }; 596494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 596594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org DeferredAllocate* deferred = 596694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org new(zone()) DeferredAllocate(this, instr); 596794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 596894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register result = ToRegister(instr->result()); 596994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register temp = ToRegister(instr->temp()); 597094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 597171fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org // Allocate memory for the object. 597271fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org AllocationFlags flags = TAG_OBJECT; 597371fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org if (instr->hydrogen()->MustAllocateDoubleAligned()) { 597471fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); 597571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org } 5976d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { 5977d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5978d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5979e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE); 5980d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5981d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5982c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE); 5983e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5984c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 598571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org if (instr->size()->IsConstantOperand()) { 598671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 59872bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); 598894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } else { 598971fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org Register size = ToRegister(instr->size()); 5990f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); 599194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 599294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 599394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ bind(deferred->exit()); 5994c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 5995c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (instr->hydrogen()->MustPrefillWithFiller()) { 5996c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (instr->size()->IsConstantOperand()) { 5997c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5998c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ mov(temp, (size / kPointerSize) - 1); 5999c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } else { 6000c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org temp = ToRegister(instr->size()); 6001c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ shr(temp, kPointerSizeLog2); 6002c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ dec(temp); 6003c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 6004c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Label loop; 6005c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ bind(&loop); 6006c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ mov(FieldOperand(result, temp, times_pointer_size, 0), 6007c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org isolate()->factory()->one_pointer_filler_map()); 6008c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ dec(temp); 6009c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ j(not_zero, &loop); 6010c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 601194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 601294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 601394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 601494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::DoDeferredAllocate(LAllocate* instr) { 601594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register result = ToRegister(instr->result()); 601694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 601794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 601894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // result register contain a valid pointer because it is already 601994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // contained in the register pointer map. 6020f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ mov(result, Immediate(Smi::FromInt(0))); 6021f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 6022f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org PushSafepointRegistersScope scope(this); 6023f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (instr->size()->IsRegister()) { 6024f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Register size = ToRegister(instr->size()); 6025f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ASSERT(!size.is(result)); 6026f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ SmiTag(ToRegister(instr->size())); 6027f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ push(size); 6028f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } else { 6029f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 6030f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ push(Immediate(Smi::FromInt(size))); 603194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 6032f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 6033d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { 6034d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); 6035d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 6036e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CallRuntimeFromDeferred( 6037e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Runtime::kAllocateInOldPointerSpace, 1, instr, instr->context()); 6038d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 6039d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 6040c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org CallRuntimeFromDeferred( 6041c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Runtime::kAllocateInOldDataSpace, 1, instr, instr->context()); 6042e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 6043e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CallRuntimeFromDeferred( 6044e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Runtime::kAllocateInNewSpace, 1, instr, instr->context()); 6045e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 6046967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org __ StoreToSafepointRegisterSlot(result, eax); 6047967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 6048967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 6049967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 6050ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid LCodeGen::DoToFastProperties(LToFastProperties* instr) { 605156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(ToRegister(instr->value()).is(eax)); 6052ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ push(eax); 6053ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallRuntime(Runtime::kToFastProperties, 1, instr); 6054ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 6055ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 6056ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 6057a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 6058ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 605983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label materialized; 6060a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Registers will be used as follows: 6061a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // ecx = literals array. 6062a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // ebx = regexp literal. 6063a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // eax = regexp literal clone. 6064ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // esi = context. 60659c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org int literal_offset = 60669c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); 60679c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org __ LoadHeapObject(ecx, instr->hydrogen()->literals()); 6068a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(ebx, FieldOperand(ecx, literal_offset)); 6069ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmp(ebx, factory()->undefined_value()); 607083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_equal, &materialized, Label::kNear); 6071a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6072a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Create regexp literal using runtime function 6073a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Result will be in eax. 6074a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(ecx); 6075a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); 6076a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(Immediate(instr->hydrogen()->pattern())); 6077a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(Immediate(instr->hydrogen()->flags())); 6078ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); 6079a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(ebx, eax); 6080a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6081a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&materialized); 6082a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 6083a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Label allocated, runtime_allocate; 60842bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ Allocate(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT); 6085a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ jmp(&allocated); 6086a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6087a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&runtime_allocate); 6088a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(ebx); 6089a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ push(Immediate(Smi::FromInt(size))); 6090ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); 6091a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ pop(ebx); 6092a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6093a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&allocated); 6094a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Copy the content into the newly allocated memory. 6095a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // (Unroll copy loop once for better throughput). 6096a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { 6097a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(edx, FieldOperand(ebx, i)); 6098a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(ecx, FieldOperand(ebx, i + kPointerSize)); 6099a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(FieldOperand(eax, i), edx); 6100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(FieldOperand(eax, i + kPointerSize), ecx); 6101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 6102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if ((size % (2 * kPointerSize)) != 0) { 6103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(edx, FieldOperand(ebx, size - kPointerSize)); 6104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(FieldOperand(eax, size - kPointerSize), edx); 6105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 6106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { 6110ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 6111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Use the fast case closure allocation code that allocates in new 6112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // space for nested functions that don't need literals cloning. 611383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org bool pretenure = instr->hydrogen()->pretenure(); 611432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (!pretenure && instr->hydrogen()->has_no_literals()) { 611532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org FastNewClosureStub stub(instr->hydrogen()->language_mode(), 611632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->hydrogen()->is_generator()); 611732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ push(Immediate(instr->hydrogen()->shared_info())); 61188432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 6119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 6120be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ push(esi); 612132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ push(Immediate(instr->hydrogen()->shared_info())); 612232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ push(Immediate(pretenure ? factory()->true_value() 612332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org : factory()->false_value())); 6124ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallRuntime(Runtime::kNewClosure, 3, instr); 6125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 6126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoTypeof(LTypeof* instr) { 613056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 613164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org EmitPushTaggedOperand(input); 6132ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CallRuntime(Runtime::kTypeof, 1, instr); 6133a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6134a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 613756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 6138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6139394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Condition final_branch_condition = 61401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitTypeofIs(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), 61411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org input, instr->type_literal()); 6142394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (final_branch_condition != no_condition) { 61431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, final_branch_condition); 6144394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 6145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6146a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6147a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6148a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgCondition LCodeGen::EmitTypeofIs(Label* true_label, 6149a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Label* false_label, 6150a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Register input, 6151a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Handle<String> type_name) { 6152a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Condition final_branch_condition = no_condition; 61534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (type_name->Equals(heap()->number_string())) { 61548f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ JumpIfSmi(input, true_label); 6155a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(FieldOperand(input, HeapObject::kMapOffset), 6156ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org factory()->heap_number_map()); 6157a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org final_branch_condition = equal; 6158a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 61594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } else if (type_name->Equals(heap()->string_string())) { 61608f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ JumpIfSmi(input, false_label); 61618f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); 61628f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ j(above_equal, false_label); 6163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test_b(FieldOperand(input, Map::kBitFieldOffset), 6164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1 << Map::kIsUndetectable); 61658f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org final_branch_condition = zero; 6166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6167f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } else if (type_name->Equals(heap()->symbol_string())) { 6168f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ JumpIfSmi(input, false_label); 6169f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ CmpObjectType(input, SYMBOL_TYPE, input); 6170f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org final_branch_condition = equal; 6171f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 61724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } else if (type_name->Equals(heap()->boolean_string())) { 6173ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmp(input, factory()->true_value()); 6174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ j(equal, true_label); 6175ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmp(input, factory()->false_value()); 6176a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org final_branch_condition = equal; 6177a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 61784a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { 61794acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ cmp(input, factory()->null_value()); 61804acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org final_branch_condition = equal; 61814acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 61824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } else if (type_name->Equals(heap()->undefined_string())) { 6183ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmp(input, factory()->undefined_value()); 6184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ j(equal, true_label); 61858f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ JumpIfSmi(input, false_label); 6186a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Check for undetectable objects => true. 6187a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); 6188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test_b(FieldOperand(input, Map::kBitFieldOffset), 6189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1 << Map::kIsUndetectable); 6190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org final_branch_condition = not_zero; 6191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 61924a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } else if (type_name->Equals(heap()->function_string())) { 6193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 61948f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ JumpIfSmi(input, false_label); 6195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CmpObjectType(input, JS_FUNCTION_TYPE, input); 6196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ j(equal, true_label); 6197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); 6198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com final_branch_condition = equal; 6199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 62004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } else if (type_name->Equals(heap()->object_string())) { 62018f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ JumpIfSmi(input, false_label); 62024acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (!FLAG_harmony_typeof) { 62034acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ cmp(input, factory()->null_value()); 62044acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ j(equal, true_label); 62054acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 6206f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); 62078f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ j(below, false_label); 6208d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 6209d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ j(above, false_label); 6210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Check for undetectable objects => false. 6211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ test_b(FieldOperand(input, Map::kBitFieldOffset), 6212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1 << Map::kIsUndetectable); 62138f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org final_branch_condition = zero; 6214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 6216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ jmp(false_label); 6217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 6218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return final_branch_condition; 6219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6220a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6222d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.comvoid LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 622356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 6224d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 6225d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com EmitIsConstructCall(temp); 62261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 6227d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com} 6228d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 6229d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 6230d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.comvoid LCodeGen::EmitIsConstructCall(Register temp) { 6231d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Get the frame pointer for the calling frame. 6232d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 6233d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 6234d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Skip the arguments adaptor frame if it exists. 623583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label check_frame_marker; 6236d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ cmp(Operand(temp, StandardFrameConstants::kContextOffset), 6237d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 623883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_equal, &check_frame_marker, Label::kNear); 6239d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset)); 6240d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 6241d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Check the marker in the calling frame. 6242d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ bind(&check_frame_marker); 6243d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset), 6244d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com Immediate(Smi::FromInt(StackFrame::CONSTRUCT))); 6245d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com} 6246d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 6247d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 624827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::EnsureSpaceForLazyDeopt() { 6249a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (!info()->IsStub()) { 6250a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Ensure that we have enough space after the previous lazy-bailout 6251a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // instruction for patching the code here. 6252a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int current_pc = masm()->pc_offset(); 6253a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int patch_size = Deoptimizer::patch_size(); 6254a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (current_pc < last_lazy_deopt_pc_ + patch_size) { 6255a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc; 6256a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ Nop(padding_size); 6257a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 625827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } 62591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org last_lazy_deopt_pc_ = masm()->pc_offset(); 626027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org} 626127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org 626227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org 6263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoLazyBailout(LLazyBailout* instr) { 626427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org EnsureSpaceForLazyDeopt(); 626527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(instr->HasEnvironment()); 626627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org LEnvironment* env = instr->environment(); 626727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 626827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 6269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoDeoptimize(LDeoptimize* instr) { 6273c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Deoptimizer::BailoutType type = instr->hydrogen()->type(); 6274c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the 6275c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // needed return address), even though the implementation of LAZY and EAGER is 6276c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // now identical. When LAZY is eventually completely folded into EAGER, remove 6277c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // the special case below. 6278c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (info()->IsStub() && type == Deoptimizer::EAGER) { 6279c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org type = Deoptimizer::LAZY; 6280c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 6281594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Comment(";;; deoptimize: %s", instr->hydrogen()->reason()); 6282c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org DeoptimizeIf(no_condition, instr->environment(), type); 6283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 628646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgvoid LCodeGen::DoDummyUse(LDummyUse* instr) { 628746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org // Nothing to see here, move on! 628846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org} 628946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 629046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 629104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgvoid LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { 629227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org PushSafepointRegistersScope scope(this); 629327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 629427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org __ CallRuntimeSaveDoubles(Runtime::kStackGuard); 629527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepointWithLazyDeopt( 629627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 629727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(instr->HasEnvironment()); 629827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org LEnvironment* env = instr->environment(); 629927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 630004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org} 630104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org 630204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org 6303a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoStackCheck(LStackCheck* instr) { 630404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org class DeferredStackCheck: public LDeferredCode { 630504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org public: 630604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) 630704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org : LDeferredCode(codegen), instr_(instr) { } 630804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } 6309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual LInstruction* instr() { return instr_; } 631004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org private: 631104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org LStackCheck* instr_; 631204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org }; 6313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 631427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(instr->HasEnvironment()); 631527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org LEnvironment* env = instr->environment(); 631627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // There is no LLazyBailout instruction for stack-checks. We have to 631727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // prepare for lazy deoptimization explicitly here. 631804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (instr->hydrogen()->is_function_entry()) { 631904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org // Perform stack overflow check. 632004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org Label done; 632104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org ExternalReference stack_limit = 632204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org ExternalReference::address_of_stack_limit(isolate()); 632304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ cmp(esp, Operand::StaticVariable(stack_limit)); 632404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ j(above_equal, &done, Label::kNear); 632504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org 6326ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org ASSERT(instr->context()->IsRegister()); 6327ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org ASSERT(ToRegister(instr->context()).is(esi)); 632804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org StackCheckStub stub; 63298432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 633027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org EnsureSpaceForLazyDeopt(); 633104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ bind(&done); 633227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 633327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 633404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } else { 633504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org ASSERT(instr->hydrogen()->is_backwards_branch()); 633604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org // Perform stack overflow check if this goto needs it before jumping. 633704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org DeferredStackCheck* deferred_stack_check = 63387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredStackCheck(this, instr); 633904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org ExternalReference stack_limit = 634004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org ExternalReference::address_of_stack_limit(isolate()); 634104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ cmp(esp, Operand::StaticVariable(stack_limit)); 634204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ j(below, deferred_stack_check->entry()); 634327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org EnsureSpaceForLazyDeopt(); 634404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ bind(instr->done_label()); 634504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org deferred_stack_check->SetExit(instr->done_label()); 634627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 634727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // Don't record a deoptimization index for the safepoint here. 634827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // This will be done explicitly when emitting call and the safepoint in 634927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // the deferred code. 635004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } 6351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6352a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6354a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoOsrEntry(LOsrEntry* instr) { 6355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // This is a pseudo-instruction that ensures that the environment here is 6356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // properly registered for deoptimization and records the assembler's PC 6357a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // offset. 6358a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LEnvironment* environment = instr->environment(); 6359a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6360a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // If the environment were already registered, we would have no way of 6361a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // backpatching it with the spill slot operands. 6362a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!environment->HasBeenRegistered()); 636327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 63641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 63651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Normally we record the first unknown OSR value as the entrypoint to the OSR 63661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // code, but if there were none, record the entrypoint here. 63671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (osr_pc_offset_ == -1) osr_pc_offset_ = masm()->pc_offset(); 6368a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6370a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6371be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { 6372be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ cmp(eax, isolate()->factory()->undefined_value()); 6373be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org DeoptimizeIf(equal, instr->environment()); 6374be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6375be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ cmp(eax, isolate()->factory()->null_value()); 6376be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org DeoptimizeIf(equal, instr->environment()); 6377be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6378be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ test(eax, Immediate(kSmiTagMask)); 6379be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org DeoptimizeIf(zero, instr->environment()); 6380be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6381be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 6382be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ CmpObjectType(eax, LAST_JS_PROXY_TYPE, ecx); 6383be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org DeoptimizeIf(below_equal, instr->environment()); 6384be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6385be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Label use_cache, call_runtime; 6386be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ CheckEnumCache(&call_runtime); 6387be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6388be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); 6389be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ jmp(&use_cache, Label::kNear); 6390be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6391be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Get the set of properties to enumerate. 6392be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ bind(&call_runtime); 6393be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ push(eax); 6394be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); 6395be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6396be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 6397be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org isolate()->factory()->meta_map()); 6398be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org DeoptimizeIf(not_equal, instr->environment()); 6399be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ bind(&use_cache); 6400be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 6401be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6402be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6403be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { 6404be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register map = ToRegister(instr->map()); 6405be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register result = ToRegister(instr->result()); 6406355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Label load_cache, done; 6407355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ EnumLength(result, map); 6408355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ cmp(result, Immediate(Smi::FromInt(0))); 6409355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ j(not_equal, &load_cache); 6410355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ mov(result, isolate()->factory()->empty_fixed_array()); 6411355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ jmp(&done); 6412355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 6413355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ bind(&load_cache); 6414be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ LoadInstanceDescriptors(map, result); 6415be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ mov(result, 6416304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FieldOperand(result, DescriptorArray::kEnumCacheOffset)); 6417be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ mov(result, 6418be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org FieldOperand(result, FixedArray::SizeFor(instr->idx()))); 6419355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ bind(&done); 6420be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ test(result, result); 6421be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org DeoptimizeIf(equal, instr->environment()); 6422be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 6423be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6424be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6425be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { 6426be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register object = ToRegister(instr->value()); 6427be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ cmp(ToRegister(instr->map()), 6428be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org FieldOperand(object, HeapObject::kMapOffset)); 6429be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org DeoptimizeIf(not_equal, instr->environment()); 6430be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 6431be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6432be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6433be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { 6434be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register object = ToRegister(instr->object()); 6435be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register index = ToRegister(instr->index()); 6436be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6437be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Label out_of_object, done; 6438be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ cmp(index, Immediate(0)); 6439be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ j(less, &out_of_object); 6440be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ mov(object, FieldOperand(object, 6441be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org index, 6442be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org times_half_pointer_size, 6443be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org JSObject::kHeaderSize)); 6444be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ jmp(&done, Label::kNear); 6445be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6446be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ bind(&out_of_object); 6447be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ mov(object, FieldOperand(object, JSObject::kPropertiesOffset)); 6448be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ neg(index); 6449be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Index is now equal to out of object property index plus 1. 6450be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ mov(object, FieldOperand(object, 6451be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org index, 6452be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org times_half_pointer_size, 6453be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org FixedArray::kHeaderSize - kPointerSize)); 6454be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ bind(&done); 6455be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 6456be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6457be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 6458a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#undef __ 6459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} } // namespace v8::internal 6461c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 6462c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#endif // V8_TARGET_ARCH_IA32 6463