1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved. 2c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// Redistribution and use in source and binary forms, with or without 3c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// modification, are permitted provided that the following conditions are 4c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// met: 5c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// 6c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// * Redistributions of source code must retain the above copyright 7c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// notice, this list of conditions and the following disclaimer. 8c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// * Redistributions in binary form must reproduce the above 9c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// copyright notice, this list of conditions and the following 10c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// disclaimer in the documentation and/or other materials provided 11c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// with the distribution. 12c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// * Neither the name of Google Inc. nor the names of its 13c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// contributors may be used to endorse or promote products derived 14c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// from this software without specific prior written permission. 15c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// 16c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 28c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#include "v8.h" 29c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 30c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#include "mips/lithium-codegen-mips.h" 31c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#include "mips/lithium-gap-resolver-mips.h" 32c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#include "code-stubs.h" 33c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#include "stub-cache.h" 34c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 35c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgnamespace v8 { 36c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgnamespace internal { 37c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 38c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 39c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgclass SafepointGenerator : public CallWrapper { 40c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org public: 41c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org SafepointGenerator(LCodeGen* codegen, 42c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LPointerMap* pointers, 430ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Safepoint::DeoptMode mode) 44c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : codegen_(codegen), 45c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org pointers_(pointers), 460ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry deopt_mode_(mode) { } 47c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual ~SafepointGenerator() { } 48c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 490ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry virtual void BeforeCall(int call_size) const { } 50c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 51c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual void AfterCall() const { 520ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry codegen_->RecordSafepoint(pointers_, deopt_mode_); 53c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 54c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 55c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org private: 56c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LCodeGen* codegen_; 57c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LPointerMap* pointers_; 580ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Safepoint::DeoptMode deopt_mode_; 59c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}; 60c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 61c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 62c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#define __ masm()-> 63c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 64c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool LCodeGen::GenerateCode() { 651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org LPhase phase("Z_Code generation", chunk()); 66c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(is_unused()); 67c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org status_ = GENERATING; 68c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 69c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Open a frame scope to indicate that there is a frame on the stack. The 70c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // NONE indicates that the scope shouldn't actually generate code to set up 71c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // the frame (that is done in GeneratePrologue). 72c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FrameScope frame_scope(masm_, StackFrame::NONE); 73c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 74c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return GeneratePrologue() && 75c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org GenerateBody() && 76c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org GenerateDeferredCode() && 7759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org GenerateDeoptJumpTable() && 78c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org GenerateSafepointTable(); 79c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 80c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 81c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 82c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::FinishCode(Handle<Code> code) { 83c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(is_done()); 84c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org code->set_stack_slots(GetStackSlotCount()); 85c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); 866ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org if (FLAG_weak_embedded_maps_in_optimized_code) { 876ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org RegisterDependentCodeForEmbeddedMaps(code); 886ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org } 89c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PopulateDeoptimizationData(code); 901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org info()->CommitDependencies(code); 91c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 92c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 93c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 94594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LChunkBuilder::Abort(BailoutReason reason) { 9546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org info()->set_bailout_reason(reason); 96c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org status_ = ABORTED; 97c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 98c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 99c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 100c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::Comment(const char* format, ...) { 101c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!FLAG_code_comments) return; 102c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org char buffer[4 * KB]; 103c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org StringBuilder builder(buffer, ARRAY_SIZE(buffer)); 104c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org va_list arguments; 105c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org va_start(arguments, format); 106c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org builder.AddFormattedList(format, arguments); 107c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org va_end(arguments); 108c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 109c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Copy the string before recording it in the assembler to avoid 110c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // issues when the stack allocated buffer goes out of scope. 111c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org size_t length = builder.position(); 112c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Vector<char> copy = Vector<char>::New(length + 1); 113e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::MemCopy(copy.start(), builder.Finalize(), copy.length()); 114c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org masm()->RecordComment(copy.start()); 115c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 116c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 117c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 118c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool LCodeGen::GeneratePrologue() { 119c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(is_generating()); 120c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 12159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (info()->IsOptimizing()) { 12259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ProfileEntryHookStub::MaybeCallEntryHook(masm_); 123129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org 124c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#ifdef DEBUG 12559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (strlen(FLAG_stop_at) > 0 && 12659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 12759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ stop("stop_at"); 12859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 129c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#endif 130c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 13159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // a1: Callee's JS function. 13259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // cp: Callee's context. 13359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // fp: Caller's frame pointer. 13459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // lr: Caller's pc. 13559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 13659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // Strict mode functions and builtins need to replace the receiver 13759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // with undefined when called as functions (without an explicit 13859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // receiver object). r5 is zero for method calls and non-zero for 13959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // function calls. 14059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (!info_->is_classic_mode() || info_->is_native()) { 14159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Label ok; 14259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ Branch(&ok, eq, t1, Operand(zero_reg)); 14359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 14459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org int receiver_offset = scope()->num_parameters() * kPointerSize; 14559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 14659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ sw(a2, MemOperand(sp, receiver_offset)); 14759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ bind(&ok); 14859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 149c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 150c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 15183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org info()->set_prologue_offset(masm_->pc_offset()); 15259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (NeedsEagerFrame()) { 1537c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (info()->IsStub()) { 1547c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ Push(ra, fp, cp); 1557c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ Push(Smi::FromInt(StackFrame::STUB)); 1567c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // Adjust FP to point to saved FP. 1577c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ Addu(fp, sp, Operand(2 * kPointerSize)); 1587c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } else { 1597c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // The following three instructions must remain together and unmodified 1607c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // for code aging to work properly. 1617c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ Push(ra, fp, cp, a1); 162ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Add unused nop to ensure prologue sequence is identical for 1637c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // full-codegen and lithium-codegen. 164ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ nop(Assembler::CODE_AGE_SEQUENCE_NOP); 1657c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // Adj. FP to point to saved FP. 1667c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ Addu(fp, sp, Operand(2 * kPointerSize)); 1677c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 16859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org frame_is_built_ = true; 1694e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org info_->AddNoFrameRange(0, masm_->pc_offset()); 17059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 171c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 172c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Reserve space for the stack slots needed by the code. 173c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int slots = GetStackSlotCount(); 174c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (slots > 0) { 175c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (FLAG_debug_code) { 1767c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ Subu(sp, sp, Operand(slots * kPointerSize)); 1777c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ push(a0); 1787c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ push(a1); 1797c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ Addu(a0, sp, Operand(slots * kPointerSize)); 1807c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ li(a1, Operand(kSlotsZapValue)); 181c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label loop; 182c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&loop); 1837c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ Subu(a0, a0, Operand(kPointerSize)); 1847c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ sw(a1, MemOperand(a0, 2 * kPointerSize)); 1857c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ Branch(&loop, ne, a0, Operand(sp)); 1867c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ pop(a1); 1877c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ pop(a0); 188c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 189c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Subu(sp, sp, Operand(slots * kPointerSize)); 190c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 191c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 192c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 193e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (info()->saves_caller_doubles()) { 1947c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Comment(";;; Save clobbered callee double registers"); 1957c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org int count = 0; 1967c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org BitVector* doubles = chunk()->allocated_double_registers(); 1977c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org BitVector::Iterator save_iterator(doubles); 1987c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org while (!save_iterator.Done()) { 1997c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ sdc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), 2007c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org MemOperand(sp, count * kDoubleSize)); 2017c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org save_iterator.Advance(); 2027c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org count++; 2037c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 2047c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 2057c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 206c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Possibly allocate a local context. 20759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 208c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (heap_slots > 0) { 209c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Comment(";;; Allocate local context"); 210c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Argument to NewContext is the function, which is in a1. 211c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(a1); 212c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (heap_slots <= FastNewContextStub::kMaximumSlots) { 213c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FastNewContextStub stub(heap_slots); 214c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ CallStub(&stub); 215c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 216c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ CallRuntime(Runtime::kNewFunctionContext, 1); 217c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2180ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RecordSafepoint(Safepoint::kNoLazyDeopt); 219c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Context is returned in both v0 and cp. It replaces the context 220c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // passed to us. It's saved in the stack and kept live in cp. 221c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 222c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Copy any necessary parameters into the context. 223c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int num_parameters = scope()->num_parameters(); 224c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = 0; i < num_parameters; i++) { 225c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Variable* var = scope()->parameter(i); 226c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (var->IsContextSlot()) { 227c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int parameter_offset = StandardFrameConstants::kCallerSPOffset + 228c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org (num_parameters - 1 - i) * kPointerSize; 229c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Load parameter from stack. 230c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(a0, MemOperand(fp, parameter_offset)); 231c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Store it in the context. 232c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MemOperand target = ContextOperand(cp, var->index()); 233c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(a0, target); 234c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Update the write barrier. This clobbers a3 and a0. 235c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ RecordWriteContextSlot( 236c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org cp, target.offset(), a0, a3, GetRAState(), kSaveFPRegs); 237c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 238c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 239c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Comment(";;; End allocate local context"); 240c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 241c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 242c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Trace the call. 24359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (FLAG_trace && info()->IsOptimizing()) { 244c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ CallRuntime(Runtime::kTraceEnter, 0); 245c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 246c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return !is_aborted(); 247c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 248c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 249c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 250c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool LCodeGen::GenerateBody() { 251c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(is_generating()); 252c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org bool emit_instructions = true; 253c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (current_instruction_ = 0; 254c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org !is_aborted() && current_instruction_ < instructions_->length(); 255c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org current_instruction_++) { 256c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LInstruction* instr = instructions_->at(current_instruction_); 25732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org 25832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org // Don't emit code for basic blocks with a replacement. 259c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->IsLabel()) { 26032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org emit_instructions = !LLabel::cast(instr)->HasReplacement(); 261c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 26232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (!emit_instructions) continue; 263c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 26432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (FLAG_code_comments && instr->HasInterestingComment(this)) { 26532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; <@%d,#%d> %s", 26632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org current_instruction_, 26732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->hydrogen_value()->id(), 26832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->Mnemonic()); 269c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 27032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org 271594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org RecordAndUpdatePosition(instr->position()); 272594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 27332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->CompileToNative(this); 274c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EnsureSpaceForLazyDeopt(); 2766fe0fda6a144bf4a3991162c622e8745376b755aulan@chromium.org last_lazy_deopt_pc_ = masm()->pc_offset(); 277c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return !is_aborted(); 278c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 279c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 280c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 281c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool LCodeGen::GenerateDeferredCode() { 282c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(is_generating()); 283c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (deferred_.length() > 0) { 284c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 285c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LDeferredCode* code = deferred_[i]; 286594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 287594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int pos = instructions_->at(code->instruction_index())->position(); 288594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org RecordAndUpdatePosition(pos); 289594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 29032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; <@%d,#%d> " 29132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org "-------------------- Deferred %s --------------------", 29232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org code->instruction_index(), 29332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org code->instr()->hydrogen_value()->id(), 29432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org code->instr()->Mnemonic()); 295c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(code->entry()); 29659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (NeedsDeferredFrame()) { 29732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; Build frame"); 29859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ASSERT(!frame_is_built_); 29959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ASSERT(info()->IsStub()); 30059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org frame_is_built_ = true; 30159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ MultiPush(cp.bit() | fp.bit() | ra.bit()); 30259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); 30359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ push(scratch0()); 30459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ Addu(fp, sp, Operand(2 * kPointerSize)); 30532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; Deferred code"); 30659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 307c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org code->Generate(); 30859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (NeedsDeferredFrame()) { 30932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; Destroy frame"); 31059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ASSERT(frame_is_built_); 31159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ pop(at); 31259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ MultiPop(cp.bit() | fp.bit() | ra.bit()); 31359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org frame_is_built_ = false; 31459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 315c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ jmp(code->exit()); 316c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 317c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 318c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Deferred code is the last part of the instruction sequence. Mark 319c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // the generated code as done unless we bailed out. 320c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!is_aborted()) status_ = DONE; 321c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return !is_aborted(); 322c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 323c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 324c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 325c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool LCodeGen::GenerateDeoptJumpTable() { 32659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // Check that the jump table is accessible from everywhere in the function 32759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // code, i.e. that offsets to the table can be encoded in the 16bit signed 32859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // immediate of a branch instruction. 32959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // To simplify we consider the code size from the first instruction to the 33059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // end of the jump table. 33159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (!is_int16((masm()->pc_offset() / Assembler::kInstrSize) + 33259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org deopt_jump_table_.length() * 12)) { 333594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kGeneratedCodeIsTooLarge); 33459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 33559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 33632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (deopt_jump_table_.length() > 0) { 33732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; -------------------- Jump table --------------------"); 33832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org } 33959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 34059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Label table_start; 34159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ bind(&table_start); 342169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Label needs_frame; 34359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org for (int i = 0; i < deopt_jump_table_.length(); i++) { 34459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ bind(&deopt_jump_table_[i].label); 34559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Address entry = deopt_jump_table_[i].address; 3460410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com Deoptimizer::BailoutType type = deopt_jump_table_[i].bailout_type; 347876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); 348068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org if (id == Deoptimizer::kNotDeoptimizationEntry) { 349068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org Comment(";;; jump table entry %d.", i); 350068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } else { 351068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); 352068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } 35359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ li(t9, Operand(ExternalReference::ForDeoptEntry(entry))); 35459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (deopt_jump_table_[i].needs_frame) { 355169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (needs_frame.is_bound()) { 356169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ Branch(&needs_frame); 35759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } else { 358169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ bind(&needs_frame); 359169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ MultiPush(cp.bit() | fp.bit() | ra.bit()); 360169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // This variant of deopt can only be used with stubs. Since we don't 361169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // have a function pointer to install in the stack frame that we're 362169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // building, install a special marker there instead. 363169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(info()->IsStub()); 364169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); 365169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ push(scratch0()); 366169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ Addu(fp, sp, Operand(2 * kPointerSize)); 36759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ Call(t9); 36859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 369169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } else { 370169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ Call(t9); 37159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 37259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 37359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ RecordComment("]"); 37459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 37559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // The deoptimization jump table is the last part of the instruction 37659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // sequence. Mark the generated code as done unless we bailed out. 37759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (!is_aborted()) status_ = DONE; 37859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org return !is_aborted(); 379c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 380c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 381c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 382c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool LCodeGen::GenerateSafepointTable() { 383c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(is_done()); 384c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org safepoints_.Emit(masm(), GetStackSlotCount()); 385c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return !is_aborted(); 386c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 387c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 388c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 389c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgRegister LCodeGen::ToRegister(int index) const { 390c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return Register::FromAllocationIndex(index); 391c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 392c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 393c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 394c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgDoubleRegister LCodeGen::ToDoubleRegister(int index) const { 395c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return DoubleRegister::FromAllocationIndex(index); 396c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 397c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 398c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 399c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgRegister LCodeGen::ToRegister(LOperand* op) const { 400c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(op->IsRegister()); 401c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return ToRegister(op->index()); 402c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 403c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 404c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 405c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgRegister LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) { 406c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (op->IsRegister()) { 407c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return ToRegister(op->index()); 408c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (op->IsConstantOperand()) { 40964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org LConstantOperand* const_op = LConstantOperand::cast(op); 41028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org HConstant* constant = chunk_->LookupConstant(const_op); 41128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org Handle<Object> literal = constant->handle(); 41264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Representation r = chunk_->LookupLiteralRepresentation(const_op); 41364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (r.IsInteger32()) { 41464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(literal->IsNumber()); 41564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ li(scratch, Operand(static_cast<int32_t>(literal->Number()))); 41609b3454f8cdcc19655f7e1d6362f8f0216941235palfia@homejinni.com } else if (r.IsSmi()) { 41709b3454f8cdcc19655f7e1d6362f8f0216941235palfia@homejinni.com ASSERT(constant->HasSmiValue()); 41809b3454f8cdcc19655f7e1d6362f8f0216941235palfia@homejinni.com __ li(scratch, Operand(Smi::FromInt(constant->Integer32Value()))); 41964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (r.IsDouble()) { 420594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kEmitLoadRegisterUnsupportedDoubleImmediate); 42164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 42264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(r.IsTagged()); 423fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ LoadObject(scratch, literal); 42464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 425c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return scratch; 426c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (op->IsStackSlot() || op->IsArgument()) { 427c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(scratch, ToMemOperand(op)); 428c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return scratch; 429c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 430c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 431c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return scratch; 432c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 433c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 434c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 435c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgDoubleRegister LCodeGen::ToDoubleRegister(LOperand* op) const { 436c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(op->IsDoubleRegister()); 437c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return ToDoubleRegister(op->index()); 438c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 439c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 440c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 441c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgDoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op, 442c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FloatRegister flt_scratch, 443c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoubleRegister dbl_scratch) { 444c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (op->IsDoubleRegister()) { 445c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return ToDoubleRegister(op->index()); 446c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (op->IsConstantOperand()) { 447c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LConstantOperand* const_op = LConstantOperand::cast(op); 44828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org HConstant* constant = chunk_->LookupConstant(const_op); 44928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org Handle<Object> literal = constant->handle(); 450c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Representation r = chunk_->LookupLiteralRepresentation(const_op); 451c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (r.IsInteger32()) { 452c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(literal->IsNumber()); 453c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(at, Operand(static_cast<int32_t>(literal->Number()))); 454c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mtc1(at, flt_scratch); 455c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ cvt_d_w(dbl_scratch, flt_scratch); 456c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return dbl_scratch; 457c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (r.IsDouble()) { 458594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kUnsupportedDoubleImmediate); 459c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (r.IsTagged()) { 460594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kUnsupportedTaggedImmediate); 461c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 462c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (op->IsStackSlot() || op->IsArgument()) { 463c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MemOperand mem_op = ToMemOperand(op); 464c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ ldc1(dbl_scratch, mem_op); 465c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return dbl_scratch; 466c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 467c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 468c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return dbl_scratch; 469c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 471c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 472fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.orgHandle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { 47328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org HConstant* constant = chunk_->LookupConstant(op); 474a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); 47528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org return constant->handle(); 476fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org} 477fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org 478fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org 479fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.orgbool LCodeGen::IsInteger32(LConstantOperand* op) const { 480c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); 481fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org} 482fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org 483fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org 484a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgbool LCodeGen::IsSmi(LConstantOperand* op) const { 485a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org return chunk_->LookupLiteralRepresentation(op).IsSmi(); 486a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org} 487a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 488a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 489fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgint32_t LCodeGen::ToInteger32(LConstantOperand* op) const { 490fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org return ToRepresentation(op, Representation::Integer32()); 491fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org} 492fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 493fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 494fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgint32_t LCodeGen::ToRepresentation(LConstantOperand* op, 495fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org const Representation& r) const { 49628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org HConstant* constant = chunk_->LookupConstant(op); 497fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org int32_t value = constant->Integer32Value(); 498fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (r.IsInteger32()) return value; 499fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ASSERT(r.IsSmiOrTagged()); 500fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org return reinterpret_cast<int32_t>(Smi::FromInt(value)); 501c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 502c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 503c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 504b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgSmi* LCodeGen::ToSmi(LConstantOperand* op) const { 505b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org HConstant* constant = chunk_->LookupConstant(op); 506b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org return Smi::FromInt(constant->Integer32Value()); 507b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org} 508b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org 509b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org 510c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgdouble LCodeGen::ToDouble(LConstantOperand* op) const { 51128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org HConstant* constant = chunk_->LookupConstant(op); 51228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org ASSERT(constant->HasDoubleValue()); 51328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org return constant->DoubleValue(); 514c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 515c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 516c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 517c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgOperand LCodeGen::ToOperand(LOperand* op) { 518c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (op->IsConstantOperand()) { 519c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LConstantOperand* const_op = LConstantOperand::cast(op); 52028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org HConstant* constant = chunk()->LookupConstant(const_op); 521c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Representation r = chunk_->LookupLiteralRepresentation(const_op); 522fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (r.IsSmi()) { 523fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ASSERT(constant->HasSmiValue()); 524fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org return Operand(Smi::FromInt(constant->Integer32Value())); 525fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else if (r.IsInteger32()) { 52628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org ASSERT(constant->HasInteger32Value()); 52728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org return Operand(constant->Integer32Value()); 528c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (r.IsDouble()) { 529594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kToOperandUnsupportedDoubleImmediate); 530c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 531c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(r.IsTagged()); 53228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org return Operand(constant->handle()); 533c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (op->IsRegister()) { 534c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return Operand(ToRegister(op)); 535c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (op->IsDoubleRegister()) { 536594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kToOperandIsDoubleRegisterUnimplemented); 537c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return Operand(0); 538c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 539c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Stack slots not implemented, use ToMemOperand instead. 540c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 541c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return Operand(0); 542c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 543c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 544c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 545c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgMemOperand LCodeGen::ToMemOperand(LOperand* op) const { 546c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!op->IsRegister()); 547c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!op->IsDoubleRegister()); 548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); 549ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org return MemOperand(fp, StackSlotOffset(op->index())); 550c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 551c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 552c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 553c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgMemOperand LCodeGen::ToHighMemOperand(LOperand* op) const { 554c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(op->IsDoubleStackSlot()); 555ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize); 556c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 557c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 558c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 559c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::WriteTranslation(LEnvironment* environment, 560b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Translation* translation) { 561c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (environment == NULL) return; 562c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 563c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // The translation includes one command per value in the environment. 564b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org int translation_size = environment->translation_size(); 565c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // The output frame height does not include the parameters. 566c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int height = translation_size - environment->parameter_count(); 567c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 568b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org WriteTranslation(environment->outer(), translation); 56959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org bool has_closure_id = !info()->closure().is_null() && 57032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org !info()->closure().is_identical_to(environment->closure()); 57159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org int closure_id = has_closure_id 5725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ? DefineDeoptimizationLiteral(environment->closure()) 5735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org : Translation::kSelfLiteralId; 5745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 575812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org switch (environment->frame_type()) { 576812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case JS_FUNCTION: 577812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org translation->BeginJSFrame(environment->ast_id(), closure_id, height); 578812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org break; 579812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case JS_CONSTRUCT: 580812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org translation->BeginConstructStubFrame(closure_id, translation_size); 581812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org break; 582de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org case JS_GETTER: 583de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org ASSERT(translation_size == 1); 584de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org ASSERT(height == 0); 585de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org translation->BeginGetterStubFrame(closure_id); 586de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org break; 587471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org case JS_SETTER: 58846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ASSERT(translation_size == 2); 58946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ASSERT(height == 0); 59046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org translation->BeginSetterStubFrame(closure_id); 591471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org break; 59259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org case STUB: 59359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org translation->BeginCompiledStubFrame(); 59459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org break; 595812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org case ARGUMENTS_ADAPTOR: 596812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); 597812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org break; 598fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org } 59956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 600594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int object_index = 0; 601594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int dematerialized_index = 0; 602c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = 0; i < translation_size; ++i) { 603c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LOperand* value = environment->values()->at(i); 604594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org AddToTranslation(environment, 605594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation, 60678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org value, 60778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org environment->HasTaggedValueAt(i), 608594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org environment->HasUint32ValueAt(i), 609594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org &object_index, 610594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org &dematerialized_index); 611c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 612c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 613c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 614c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 615594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::AddToTranslation(LEnvironment* environment, 616594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Translation* translation, 617c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LOperand* op, 61878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org bool is_tagged, 619594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org bool is_uint32, 620594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int* object_index_pointer, 621594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int* dematerialized_index_pointer) { 622594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (op == LEnvironment::materialization_marker()) { 623594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int object_index = (*object_index_pointer)++; 624594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (environment->ObjectIsDuplicateAt(object_index)) { 625594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int dupe_of = environment->ObjectDuplicateOfAt(object_index); 626594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation->DuplicateObject(dupe_of); 627594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return; 628594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 629594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int object_length = environment->ObjectLengthAt(object_index); 630594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (environment->ObjectIsArgumentsAt(object_index)) { 631594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation->BeginArgumentsObject(object_length); 632594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 633594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation->BeginCapturedObject(object_length); 634594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 635594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int dematerialized_index = *dematerialized_index_pointer; 636594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int env_offset = environment->translation_size() + dematerialized_index; 637594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org *dematerialized_index_pointer += object_length; 638594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org for (int i = 0; i < object_length; ++i) { 639594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org LOperand* value = environment->values()->at(env_offset + i); 640594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org AddToTranslation(environment, 641594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation, 642594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org value, 643594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org environment->HasTaggedValueAt(env_offset + i), 644594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org environment->HasUint32ValueAt(env_offset + i), 645594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org object_index_pointer, 646594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org dematerialized_index_pointer); 647594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 648594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return; 649594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 650594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 651b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (op->IsStackSlot()) { 652c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (is_tagged) { 653c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org translation->StoreStackSlot(op->index()); 65478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } else if (is_uint32) { 65578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org translation->StoreUint32StackSlot(op->index()); 656c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 657c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org translation->StoreInt32StackSlot(op->index()); 658c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 659c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (op->IsDoubleStackSlot()) { 660c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org translation->StoreDoubleStackSlot(op->index()); 661c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (op->IsArgument()) { 662c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(is_tagged); 663c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int src_index = GetStackSlotCount() + op->index(); 664c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org translation->StoreStackSlot(src_index); 665c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (op->IsRegister()) { 666c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register reg = ToRegister(op); 667c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (is_tagged) { 668c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org translation->StoreRegister(reg); 66978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } else if (is_uint32) { 67078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org translation->StoreUint32Register(reg); 671c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 672c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org translation->StoreInt32Register(reg); 673c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 674c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (op->IsDoubleRegister()) { 675c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoubleRegister reg = ToDoubleRegister(op); 676c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org translation->StoreDoubleRegister(reg); 677c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (op->IsConstantOperand()) { 67828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op)); 67928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org int src_index = DefineDeoptimizationLiteral(constant->handle()); 680c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org translation->StoreLiteral(src_index); 681c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 682c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 683c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 684c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 685c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 686c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 687c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::CallCode(Handle<Code> code, 688c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RelocInfo::Mode mode, 689c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LInstruction* instr) { 690c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT); 691c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 692c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 693c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 694c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::CallCodeGeneric(Handle<Code> code, 695c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RelocInfo::Mode mode, 696c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LInstruction* instr, 697c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org SafepointMode safepoint_mode) { 6981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EnsureSpaceForLazyDeopt(); 699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(instr != NULL); 700c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LPointerMap* pointers = instr->pointer_map(); 701c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RecordPosition(pointers->position()); 702c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Call(code, mode); 7030ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RecordSafepointWithLazyDeopt(instr, safepoint_mode); 704c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 705c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 706c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 707c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::CallRuntime(const Runtime::Function* function, 708c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int num_arguments, 709c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LInstruction* instr) { 710c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(instr != NULL); 711c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LPointerMap* pointers = instr->pointer_map(); 712c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(pointers != NULL); 713c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RecordPosition(pointers->position()); 714c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 715c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ CallRuntime(function, num_arguments); 7160ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 717c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 718c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 719c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 720c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 721c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int argc, 722c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LInstruction* instr) { 723c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ CallRuntimeSaveDoubles(id); 724c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RecordSafepointWithRegisters( 7250ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry instr->pointer_map(), argc, Safepoint::kNoLazyDeopt); 726c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 727c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 728c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 7290ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, 7300ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Safepoint::DeoptMode mode) { 731c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!environment->HasBeenRegistered()) { 732c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Physical stack frame layout: 733c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // -x ............. -4 0 ..................................... y 734c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // [incoming arguments] [spill slots] [pushed outgoing arguments] 735c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 736c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Layout of the environment: 737c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // 0 ..................................................... size-1 738c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // [parameters] [locals] [expression stack including arguments] 739c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 740c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Layout of the translation: 741c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // 0 ........................................................ size - 1 + 4 742c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // [expression stack including arguments] [locals] [4 words] [parameters] 743c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // |>------------ translation_size ------------<| 744c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 745c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int frame_count = 0; 746fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org int jsframe_count = 0; 747c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (LEnvironment* e = environment; e != NULL; e = e->outer()) { 748c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ++frame_count; 749812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org if (e->frame_type() == JS_FUNCTION) { 750fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org ++jsframe_count; 751fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org } 752c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 7537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Translation translation(&translations_, frame_count, jsframe_count, zone()); 754b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org WriteTranslation(environment, &translation); 755c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int deoptimization_index = deoptimizations_.length(); 7560ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry int pc_offset = masm()->pc_offset(); 7570ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry environment->Register(deoptimization_index, 7580ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry translation.index(), 7590ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 7607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org deoptimizations_.Add(environment, zone()); 761c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 762c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 763c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 764c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 765c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.comvoid LCodeGen::DeoptimizeIf(Condition condition, 766c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LEnvironment* environment, 7670410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com Deoptimizer::BailoutType bailout_type, 768c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register src1, 769c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const Operand& src2) { 7700ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 771c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(environment->HasBeenRegistered()); 772c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int id = environment->deoptimization_index(); 7737c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org ASSERT(info()->IsOptimizing() || info()->IsStub()); 7748432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Address entry = 7758432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); 776c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (entry == NULL) { 777594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kBailoutWasNotPrepared); 778c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return; 779c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 780c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 781c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on MIPS. 782e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (FLAG_deopt_every_n_times == 1 && 783e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org !info()->IsStub() && 784e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org info()->opt_count() == id) { 78510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org ASSERT(frame_is_built_); 78610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org __ Call(entry, RelocInfo::RUNTIME_ENTRY); 787c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return; 788c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 789c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 790594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (info()->ShouldTrapOnDeopt()) { 791c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label skip; 792c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com if (condition != al) { 793c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com __ Branch(&skip, NegateCondition(condition), src1, src2); 794c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 795c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ stop("trap_on_deopt"); 796c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&skip); 797c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 798c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 79959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ASSERT(info()->IsStub() || frame_is_built_); 800c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com if (condition == al && frame_is_built_) { 801c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com __ Call(entry, RelocInfo::RUNTIME_ENTRY, condition, src1, src2); 80259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } else { 80359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // We often have several deopts to the same entry, reuse the last 80459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // jump entry if this is the case. 80559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (deopt_jump_table_.is_empty() || 80659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org (deopt_jump_table_.last().address != entry) || 8070410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com (deopt_jump_table_.last().bailout_type != bailout_type) || 80859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org (deopt_jump_table_.last().needs_frame != !frame_is_built_)) { 8090410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com Deoptimizer::JumpTableEntry table_entry(entry, 8100410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com bailout_type, 8110410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com !frame_is_built_); 81259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org deopt_jump_table_.Add(table_entry, zone()); 81359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 814c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com __ Branch(&deopt_jump_table_.last().label, condition, src1, src2); 81559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 816c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 817c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 818c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 819c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.comvoid LCodeGen::DeoptimizeIf(Condition condition, 8200410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com LEnvironment* environment, 8210410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com Register src1, 8220410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com const Operand& src2) { 8230410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com Deoptimizer::BailoutType bailout_type = info()->IsStub() 8240410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com ? Deoptimizer::LAZY 8250410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com : Deoptimizer::EAGER; 826c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com DeoptimizeIf(condition, environment, bailout_type, src1, src2); 8270410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com} 8280410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com 8290410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com 8306ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.orgvoid LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) { 8316ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org ZoneList<Handle<Map> > maps(1, zone()); 8326ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 8336ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { 8346ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org RelocInfo::Mode mode = it.rinfo()->rmode(); 8356ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org if (mode == RelocInfo::EMBEDDED_OBJECT && 8366ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org it.rinfo()->target_object()->IsMap()) { 8376ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org Handle<Map> map(Map::cast(it.rinfo()->target_object())); 8386ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org if (map->CanTransition()) { 8396ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org maps.Add(map, zone()); 8406ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org } 8416ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org } 8426ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org } 8436ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org#ifdef VERIFY_HEAP 8446ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org // This disables verification of weak embedded maps after full GC. 8456ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org // AddDependentCode can cause a GC, which would observe the state where 8466ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org // this code is not yet in the depended code lists of the embedded maps. 8476ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org NoWeakEmbeddedMapsVerificationScope disable_verification_of_embedded_maps; 8486ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org#endif 8496ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org for (int i = 0; i < maps.length(); i++) { 8502e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code); 8516ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org } 8526ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org} 8536ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org 8546ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org 855c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 856c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int length = deoptimizations_.length(); 857c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (length == 0) return; 858c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<DeoptimizationInputData> data = 859c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org factory()->NewDeoptimizationInputData(length, TENURED); 860c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 861876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org Handle<ByteArray> translations = 862876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org translations_.CreateByteArray(isolate()->factory()); 863c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org data->SetTranslationByteArray(*translations); 864c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); 865c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 866c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<FixedArray> literals = 867c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); 86879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org { AllowDeferredHandleDereference copy_handles; 86932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org for (int i = 0; i < deoptimization_literals_.length(); i++) { 87032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org literals->set(i, *deoptimization_literals_[i]); 87132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org } 87232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org data->SetLiteralArray(*literals); 873c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 874c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 875471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); 876c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); 877c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 878c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Populate the deoptimization entries. 879c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = 0; i < length; i++) { 880c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LEnvironment* env = deoptimizations_[i]; 881471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org data->SetAstId(i, env->ast_id()); 882c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); 883c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org data->SetArgumentsStackHeight(i, 884c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Smi::FromInt(env->arguments_stack_height())); 8850ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry data->SetPc(i, Smi::FromInt(env->pc_offset())); 886c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 887c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org code->set_deoptimization_data(*data); 888c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 889c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 890c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 891c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgint LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) { 892c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int result = deoptimization_literals_.length(); 893c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = 0; i < deoptimization_literals_.length(); ++i) { 894c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (deoptimization_literals_[i].is_identical_to(literal)) return i; 895c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 8967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org deoptimization_literals_.Add(literal, zone()); 897c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return result; 898c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 899c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 900c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 901c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() { 902c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(deoptimization_literals_.length() == 0); 903c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 904c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const ZoneList<Handle<JSFunction> >* inlined_closures = 905c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org chunk()->inlined_closures(); 906c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 907c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = 0, length = inlined_closures->length(); 908c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org i < length; 909c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org i++) { 910c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DefineDeoptimizationLiteral(inlined_closures->at(i)); 911c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 912c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 913c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org inlined_function_count_ = deoptimization_literals_.length(); 914c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 915c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 916c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 9170ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::RecordSafepointWithLazyDeopt( 9180ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry LInstruction* instr, SafepointMode safepoint_mode) { 9190ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { 9200ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt); 9210ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry } else { 9220ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 9230ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RecordSafepointWithRegisters( 9240ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry instr->pointer_map(), 0, Safepoint::kLazyDeopt); 9250ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry } 9260ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry} 9270ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 9280ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 929c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::RecordSafepoint( 930c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LPointerMap* pointers, 931c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Safepoint::Kind kind, 932c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int arguments, 9330ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Safepoint::DeoptMode deopt_mode) { 934c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(expected_safepoint_kind_ == kind); 935c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 936c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const ZoneList<LOperand*>* operands = pointers->GetNormalizedOperands(); 937c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Safepoint safepoint = safepoints_.DefineSafepoint(masm(), 9380ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry kind, arguments, deopt_mode); 939c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = 0; i < operands->length(); i++) { 940c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LOperand* pointer = operands->at(i); 941c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (pointer->IsStackSlot()) { 9427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org safepoint.DefinePointerSlot(pointer->index(), zone()); 943c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { 9447028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org safepoint.DefinePointerRegister(ToRegister(pointer), zone()); 945c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 946c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 947c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (kind & Safepoint::kWithRegisters) { 948c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Register cp always contains a pointer to the context. 9497028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org safepoint.DefinePointerRegister(cp, zone()); 950c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 952c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 953c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 954c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::RecordSafepoint(LPointerMap* pointers, 9550ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Safepoint::DeoptMode deopt_mode) { 9560ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode); 957c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 958c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 959c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 9600ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) { 9617028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org LPointerMap empty_pointers(RelocInfo::kNoPosition, zone()); 9620ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RecordSafepoint(&empty_pointers, deopt_mode); 963c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 964c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 965c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 966c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, 967c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int arguments, 9680ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Safepoint::DeoptMode deopt_mode) { 9690ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RecordSafepoint( 9700ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry pointers, Safepoint::kWithRegisters, arguments, deopt_mode); 971c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 972c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 974c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::RecordSafepointWithRegistersAndDoubles( 975c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LPointerMap* pointers, 976c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int arguments, 9770ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Safepoint::DeoptMode deopt_mode) { 9780ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RecordSafepoint( 9790ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry pointers, Safepoint::kWithRegistersAndDoubles, arguments, deopt_mode); 980c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 981c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 982c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 983c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::RecordPosition(int position) { 984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (position == RelocInfo::kNoPosition) return; 985c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org masm()->positions_recorder()->RecordPosition(position); 986c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 987c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 988c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 989594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::RecordAndUpdatePosition(int position) { 990594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (position >= 0 && position != old_position_) { 991594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org masm()->positions_recorder()->RecordPosition(position); 992594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org old_position_ = position; 993594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 994594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 995594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 996594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 99732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.orgstatic const char* LabelType(LLabel* label) { 99832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (label->is_loop_header()) return " (loop header)"; 99932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (label->is_osr_entry()) return " (OSR entry)"; 100032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org return ""; 100132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org} 100232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org 100332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org 1004c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLabel(LLabel* label) { 100532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", 100632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org current_instruction_, 100732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org label->hydrogen_value()->id(), 1008b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org label->block_id(), 100932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org LabelType(label)); 1010c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(label->label()); 1011c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org current_block_ = label->block_id(); 1012c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoGap(label); 1013c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1014c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1015c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1016c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoParallelMove(LParallelMove* move) { 1017c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org resolver_.Resolve(move); 1018c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1019c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1020c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1021c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoGap(LGap* gap) { 1022c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = LGap::FIRST_INNER_POSITION; 1023c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org i <= LGap::LAST_INNER_POSITION; 1024c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org i++) { 1025c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LGap::InnerPosition inner_pos = static_cast<LGap::InnerPosition>(i); 1026c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LParallelMove* move = gap->GetParallelMove(inner_pos); 1027c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (move != NULL) DoParallelMove(move); 1028c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1029c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1030c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1031c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1032c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoInstructionGap(LInstructionGap* instr) { 1033c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoGap(instr); 1034c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1035c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1036c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1037c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoParameter(LParameter* instr) { 1038c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Nothing to do. 1039c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1040c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1041c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1042c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallStub(LCallStub* instr) { 1043c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 1044c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org switch (instr->hydrogen()->major_key()) { 1045c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case CodeStub::RegExpConstructResult: { 1046c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RegExpConstructResultStub stub; 10478432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1048c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1049c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1050c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case CodeStub::RegExpExec: { 1051c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RegExpExecStub stub; 10528432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1053c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1054c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1055c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case CodeStub::SubString: { 1056c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org SubStringStub stub; 10578432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1058c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1059c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1060c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case CodeStub::NumberToString: { 1061c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org NumberToStringStub stub; 10628432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1063c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1064c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1065c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case CodeStub::StringCompare: { 1066c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org StringCompareStub stub; 10678432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1068c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1069c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1070c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case CodeStub::TranscendentalCache: { 1071c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(a0, MemOperand(sp, 0)); 1072c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org TranscendentalCacheStub stub(instr->transcendental_type(), 1073c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org TranscendentalCacheStub::TAGGED); 10748432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1075c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1076c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1077c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org default: 1078c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 1079c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1080c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1081c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1082c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1083c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 10841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Record the address of the first unknown OSR value as the place to enter. 10851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (osr_pc_offset_ == -1) osr_pc_offset_ = masm()->pc_offset(); 1086c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1087c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1088c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1089c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoModI(LModI* instr) { 10908a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org HMod* hmod = instr->hydrogen(); 10918a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org HValue* left = hmod->left(); 10928a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org HValue* right = hmod->right(); 10938a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (hmod->HasPowerOf2Divisor()) { 10948a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org const Register left_reg = ToRegister(instr->left()); 10958a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org const Register result_reg = ToRegister(instr->result()); 10968a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org 10978a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // Note: The code below even works when right contains kMinInt. 10988a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org int32_t divisor = Abs(right->GetInteger32Constant()); 10998a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org 11008a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org Label left_is_not_negative, done; 11018a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (left->CanBeNegative()) { 1102c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org __ Branch(left_reg.is(result_reg) ? PROTECT : USE_DELAY_SLOT, 1103c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org &left_is_not_negative, ge, left_reg, Operand(zero_reg)); 11048a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ subu(result_reg, zero_reg, left_reg); 11058a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ And(result_reg, result_reg, divisor - 1); 11068a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 11078a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg)); 11088a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org } 11098a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Branch(USE_DELAY_SLOT, &done); 11108a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ subu(result_reg, zero_reg, result_reg); 11118a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org } 1112c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 11138a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ bind(&left_is_not_negative); 1114c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org __ And(result_reg, left_reg, divisor - 1); 11158a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ bind(&done); 1116c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 11171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (hmod->fixed_right_arg().has_value) { 11181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org const Register left_reg = ToRegister(instr->left()); 11191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org const Register result_reg = ToRegister(instr->result()); 1120c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org const Register right_reg = ToRegister(instr->right()); 11218a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org 11221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org int32_t divisor = hmod->fixed_right_arg().value; 11231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(IsPowerOf2(divisor)); 11241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 11251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Check if our assumption of a fixed right operand still holds. 11261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org DeoptimizeIf(ne, instr->environment(), right_reg, Operand(divisor)); 11271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 11281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label left_is_not_negative, done; 11291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (left->CanBeNegative()) { 1130c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org __ Branch(left_reg.is(result_reg) ? PROTECT : USE_DELAY_SLOT, 1131c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org &left_is_not_negative, ge, left_reg, Operand(zero_reg)); 11321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ subu(result_reg, zero_reg, left_reg); 11331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ And(result_reg, result_reg, divisor - 1); 11341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 11351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg)); 11361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 11371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Branch(USE_DELAY_SLOT, &done); 11381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ subu(result_reg, zero_reg, result_reg); 11391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 11401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 11411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ bind(&left_is_not_negative); 11421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ And(result_reg, left_reg, divisor - 1); 11431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ bind(&done); 11441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 11451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else { 11468a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org const Register scratch = scratch0(); 11478a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org const Register left_reg = ToRegister(instr->left()); 11488a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org const Register result_reg = ToRegister(instr->result()); 11498a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org 11500ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // div runs in the background while we check for special cases. 11518a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org Register right_reg = EmitLoadRegister(instr->right(), scratch); 11528a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ div(left_reg, right_reg); 1153c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 11548a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org Label done; 11558a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // Check for x % 0, we have to deopt in this case because we can't return a 11568a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // NaN. 11578a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (right->CanBeZero()) { 11588a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org DeoptimizeIf(eq, instr->environment(), right_reg, Operand(zero_reg)); 11590ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry } 1160c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 11618a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // Check for kMinInt % -1, we have to deopt if we care about -0, because we 11628a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // can't return that. 11638a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) { 116459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Label left_not_min_int; 11658a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Branch(&left_not_min_int, ne, left_reg, Operand(kMinInt)); 11668a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // TODO(svenpanne) Don't deopt when we don't care about -0. 11678a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org DeoptimizeIf(eq, instr->environment(), right_reg, Operand(-1)); 116859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ bind(&left_not_min_int); 116959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 117059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 11718a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // TODO(svenpanne) Only emit the test/deopt if we have to. 11728a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Branch(USE_DELAY_SLOT, &done, ge, left_reg, Operand(zero_reg)); 11738a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ mfhi(result_reg); 11740ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 11758a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 11768a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg)); 11770ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry } 11788a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ bind(&done); 1179c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1180c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1181c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1182c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1183b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgvoid LCodeGen::EmitSignedIntegerDivisionByConstant( 1184b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Register result, 1185b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Register dividend, 1186b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org int32_t divisor, 1187b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Register remainder, 1188b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Register scratch, 1189b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org LEnvironment* environment) { 1190b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ASSERT(!AreAliased(dividend, scratch, at, no_reg)); 1191b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1192b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org uint32_t divisor_abs = abs(divisor); 1193b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1194b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org int32_t power_of_2_factor = 1195b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org CompilerIntrinsics::CountTrailingZeros(divisor_abs); 1196b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1197b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org switch (divisor_abs) { 1198b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org case 0: 1199b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org DeoptimizeIf(al, environment); 1200b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org return; 1201b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1202b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org case 1: 1203b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (divisor > 0) { 1204b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Move(result, dividend); 1205b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } else { 1206b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ SubuAndCheckForOverflow(result, zero_reg, dividend, scratch); 1207b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org DeoptimizeIf(lt, environment, scratch, Operand(zero_reg)); 1208b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 1209b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Compute the remainder. 1210b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Move(remainder, zero_reg); 1211b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org return; 1212b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1213b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org default: 1214b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (IsPowerOf2(divisor_abs)) { 1215b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Branch and condition free code for integer division by a power 1216b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // of two. 1217b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org int32_t power = WhichPowerOf2(divisor_abs); 1218b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (power > 1) { 1219b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ sra(scratch, dividend, power - 1); 1220b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 1221b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ srl(scratch, scratch, 32 - power); 1222b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Addu(scratch, dividend, Operand(scratch)); 1223b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ sra(result, scratch, power); 1224b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Negate if necessary. 1225b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // We don't need to check for overflow because the case '-1' is 1226b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // handled separately. 1227b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (divisor < 0) { 1228b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ASSERT(divisor != -1); 1229b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Subu(result, zero_reg, Operand(result)); 1230b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 1231b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Compute the remainder. 1232b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (divisor > 0) { 1233b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ sll(scratch, result, power); 1234b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Subu(remainder, dividend, Operand(scratch)); 1235b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } else { 1236b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ sll(scratch, result, power); 1237b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Addu(remainder, dividend, Operand(scratch)); 1238b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 1239b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org return; 1240b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } else if (LChunkBuilder::HasMagicNumberForDivisor(divisor)) { 1241b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Use magic numbers for a few specific divisors. 1242b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Details and proofs can be found in: 1243b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // - Hacker's Delight, Henry S. Warren, Jr. 1244b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // - The PowerPC Compiler Writer's Guide 1245b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // and probably many others. 1246b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // 1247b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // We handle 1248b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // <divisor with magic numbers> * <power of 2> 1249b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // but not 1250b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // <divisor with magic numbers> * <other divisor with magic numbers> 1251b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org DivMagicNumbers magic_numbers = 1252b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org DivMagicNumberFor(divisor_abs >> power_of_2_factor); 1253b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Branch and condition free code for integer division by a power 1254b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // of two. 1255b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org const int32_t M = magic_numbers.M; 1256b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org const int32_t s = magic_numbers.s + power_of_2_factor; 1257b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1258b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ li(scratch, Operand(M)); 1259b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ mult(dividend, scratch); 1260b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ mfhi(scratch); 1261b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (M < 0) { 1262b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Addu(scratch, scratch, Operand(dividend)); 1263b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 1264b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (s > 0) { 1265b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ sra(scratch, scratch, s); 1266b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ mov(scratch, scratch); 1267b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 1268b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ srl(at, dividend, 31); 1269b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Addu(result, scratch, Operand(at)); 1270b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (divisor < 0) __ Subu(result, zero_reg, Operand(result)); 1271b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Compute the remainder. 1272b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ li(scratch, Operand(divisor)); 1273b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Mul(scratch, result, Operand(scratch)); 1274b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Subu(remainder, dividend, Operand(scratch)); 1275b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } else { 1276b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ li(scratch, Operand(divisor)); 1277b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ div(dividend, scratch); 1278b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ mfhi(remainder); 1279b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ mflo(result); 1280b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 1281b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 1282b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org} 1283b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1284b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1285c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDivI(LDivI* instr) { 1286c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org const Register left = ToRegister(instr->left()); 1287c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org const Register right = ToRegister(instr->right()); 1288c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const Register result = ToRegister(instr->result()); 1289c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1290c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // On MIPS div is asynchronous - it will run in the background while we 1291c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // check for special cases. 1292c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ div(left, right); 1293c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1294c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Check for x / 0. 1295c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 1296c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg)); 1297c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1298c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1299c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Check for (0 / -x) that will produce negative zero. 1300c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1301c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label left_not_zero; 1302c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&left_not_zero, ne, left, Operand(zero_reg)); 1303c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(lt, instr->environment(), right, Operand(zero_reg)); 1304c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&left_not_zero); 1305c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1306c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 130759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // Check for (kMinInt / -1). 1308c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1309c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label left_not_min_int; 1310c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&left_not_min_int, ne, left, Operand(kMinInt)); 1311c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(eq, instr->environment(), right, Operand(-1)); 1312c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&left_not_min_int); 1313c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1314c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 131541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (!instr->hydrogen()->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { 131641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ mfhi(result); 131741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org DeoptimizeIf(ne, instr->environment(), result, Operand(zero_reg)); 131841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } 1319c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mflo(result); 1320c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1321c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1322c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 132359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgvoid LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { 132459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org DoubleRegister addend = ToDoubleRegister(instr->addend()); 132559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org DoubleRegister multiplier = ToDoubleRegister(instr->multiplier()); 132659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand()); 132759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 132859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // This is computed in-place. 132959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ASSERT(addend.is(ToDoubleRegister(instr->result()))); 133059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 133159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ madd_d(addend, addend, multiplier, multiplicand); 133259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org} 133359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 133459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 1335b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgvoid LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { 1336b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org const Register result = ToRegister(instr->result()); 1337b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org const Register left = ToRegister(instr->left()); 1338b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org const Register remainder = ToRegister(instr->temp()); 1339b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org const Register scratch = scratch0(); 1340b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1341b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (instr->right()->IsConstantOperand()) { 1342b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label done; 1343b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right())); 1344b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (divisor < 0) { 1345b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg)); 1346b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 1347b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org EmitSignedIntegerDivisionByConstant(result, 1348b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org left, 1349b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org divisor, 1350b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org remainder, 1351b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org scratch, 1352b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org instr->environment()); 1353b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // We performed a truncating division. Correct the result if necessary. 1354b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Branch(&done, eq, remainder, Operand(zero_reg), USE_DELAY_SLOT); 1355b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Xor(scratch , remainder, Operand(divisor)); 1356b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Branch(&done, ge, scratch, Operand(zero_reg)); 1357b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Subu(result, result, Operand(1)); 1358b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ bind(&done); 1359b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } else { 1360b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label done; 1361b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org const Register right = ToRegister(instr->right()); 1362b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1363b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // On MIPS div is asynchronous - it will run in the background while we 1364b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // check for special cases. 1365b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ div(left, right); 1366b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1367b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Check for x / 0. 1368b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg)); 1369b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1370b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Check for (0 / -x) that will produce negative zero. 1371b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1372b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label left_not_zero; 1373b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Branch(&left_not_zero, ne, left, Operand(zero_reg)); 1374b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org DeoptimizeIf(lt, instr->environment(), right, Operand(zero_reg)); 1375b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ bind(&left_not_zero); 1376b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 1377b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1378b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Check for (kMinInt / -1). 1379b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1380b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label left_not_min_int; 1381b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Branch(&left_not_min_int, ne, left, Operand(kMinInt)); 1382b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org DeoptimizeIf(eq, instr->environment(), right, Operand(-1)); 1383b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ bind(&left_not_min_int); 1384b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 1385b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1386b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ mfhi(remainder); 1387b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ mflo(result); 1388b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1389b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // We performed a truncating division. Correct the result if necessary. 1390b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Branch(&done, eq, remainder, Operand(zero_reg), USE_DELAY_SLOT); 1391b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Xor(scratch , remainder, Operand(right)); 1392b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Branch(&done, ge, scratch, Operand(zero_reg)); 1393b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Subu(result, result, Operand(1)); 1394b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ bind(&done); 1395b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 1396b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org} 1397b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1398b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1399c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoMulI(LMulI* instr) { 1400c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 1401c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 1402c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Note that result may alias left. 1403c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register left = ToRegister(instr->left()); 1404c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* right_op = instr->right(); 1405c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1406c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1407c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org bool bailout_on_minus_zero = 1408c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1409c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1410c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (right_op->IsConstantOperand() && !can_overflow) { 1411c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Use optimized code for specific constants. 1412fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org int32_t constant = ToRepresentation( 1413fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org LConstantOperand::cast(right_op), 1414fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org instr->hydrogen()->right()->representation()); 1415c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1416c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (bailout_on_minus_zero && (constant < 0)) { 1417c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // The case of a null constant will be handled separately. 1418c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If constant is negative and left is null, the result should be -0. 1419c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg)); 1420c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1421c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1422c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org switch (constant) { 1423c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case -1: 1424c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Subu(result, zero_reg, left); 1425c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1426c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case 0: 1427c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (bailout_on_minus_zero) { 1428c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If left is strictly negative and the constant is null, the 1429c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // result is -0. Deoptimize if required, otherwise return 0. 1430c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(lt, instr->environment(), left, Operand(zero_reg)); 1431c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1432c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov(result, zero_reg); 1433c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1434c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case 1: 1435c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Nothing to do. 1436c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Move(result, left); 1437c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1438c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org default: 1439c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Multiplying by powers of two and powers of two plus or minus 1440c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // one can be done faster with shifted operands. 1441c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // For other constants we emit standard code. 1442c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int32_t mask = constant >> 31; 1443c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org uint32_t constant_abs = (constant + mask) ^ mask; 1444c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1445c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (IsPowerOf2(constant_abs) || 1446c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org IsPowerOf2(constant_abs - 1) || 1447c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org IsPowerOf2(constant_abs + 1)) { 1448c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (IsPowerOf2(constant_abs)) { 1449c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int32_t shift = WhichPowerOf2(constant_abs); 1450c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sll(result, left, shift); 1451c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (IsPowerOf2(constant_abs - 1)) { 1452c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int32_t shift = WhichPowerOf2(constant_abs - 1); 14532bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ sll(scratch, left, shift); 14542bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ Addu(result, scratch, left); 1455c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (IsPowerOf2(constant_abs + 1)) { 1456c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int32_t shift = WhichPowerOf2(constant_abs + 1); 14572bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ sll(scratch, left, shift); 14582bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ Subu(result, scratch, left); 1459c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1460c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1461c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Correct the sign of the result is the constant is negative. 1462c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (constant < 0) { 1463c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Subu(result, zero_reg, result); 1464c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1465c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1466c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 1467c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Generate standard code. 1468c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(at, constant); 14693233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org __ Mul(result, left, at); 1470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1471c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1472c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1473c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 1474c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register right = EmitLoadRegister(right_op, scratch); 1475c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (bailout_on_minus_zero) { 1476c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ Or(ToRegister(instr->temp()), left, right); 1477c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1478c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1479c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (can_overflow) { 1480c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // hi:lo = left * right. 1481fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen()->representation().IsSmi()) { 1482fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ SmiUntag(result, left); 1483fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ mult(result, right); 1484fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ mfhi(scratch); 1485fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ mflo(result); 1486fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1487fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ mult(left, right); 1488fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ mfhi(scratch); 1489fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ mflo(result); 1490fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 1491c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sra(at, result, 31); 1492c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); 1493c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 1494fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen()->representation().IsSmi()) { 1495fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ SmiUntag(result, left); 1496fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ Mul(result, result, right); 1497fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1498fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ Mul(result, left, right); 1499fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 1500c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1501c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1502c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (bailout_on_minus_zero) { 1503c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Bail out if the result is supposed to be negative zero. 1504c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label done; 1505c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done, ne, result, Operand(zero_reg)); 1506c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(lt, 1507c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org instr->environment(), 1508c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ToRegister(instr->temp()), 1509c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Operand(zero_reg)); 1510c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 1511c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1512c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1513c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1514c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1515c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1516c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoBitI(LBitI* instr) { 1517c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* left_op = instr->left(); 1518c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* right_op = instr->right(); 1519c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(left_op->IsRegister()); 1520c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register left = ToRegister(left_op); 1521c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 1522c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Operand right(no_reg); 1523c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1524c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (right_op->IsStackSlot() || right_op->IsArgument()) { 1525c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org right = Operand(EmitLoadRegister(right_op, at)); 1526c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 1527c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(right_op->IsRegister() || right_op->IsConstantOperand()); 1528c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org right = ToOperand(right_op); 1529c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1530c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1531c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org switch (instr->op()) { 1532c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::BIT_AND: 1533c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(result, left, right); 1534c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1535c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::BIT_OR: 1536c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Or(result, left, right); 1537c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1538c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::BIT_XOR: 1539594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (right_op->IsConstantOperand() && right.immediate() == int32_t(~0)) { 1540594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Nor(result, zero_reg, left); 1541594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 1542594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Xor(result, left, right); 1543594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 1544c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1545c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org default: 1546c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 1547c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1549c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1550c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1551c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1552c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoShiftI(LShiftI* instr) { 1553c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so 1554c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // result may alias either of them. 1555c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* right_op = instr->right(); 1556c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register left = ToRegister(instr->left()); 1557c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 1558d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register scratch = scratch0(); 1559c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1560c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (right_op->IsRegister()) { 1561c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // No need to mask the right operand on MIPS, it is built into the variable 1562c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // shift instructions. 1563c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org switch (instr->op()) { 1564fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org case Token::ROR: 1565fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ Ror(result, left, Operand(ToRegister(right_op))); 1566fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org break; 1567c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::SAR: 1568c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ srav(result, left, ToRegister(right_op)); 1569c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1570c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::SHR: 1571c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ srlv(result, left, ToRegister(right_op)); 1572c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->can_deopt()) { 1573c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); 1574c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1575c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1576c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::SHL: 1577c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sllv(result, left, ToRegister(right_op)); 1578c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1579c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org default: 1580c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 1581c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1582c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1583c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 1584c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Mask the right_op operand. 1585c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int value = ToInteger32(LConstantOperand::cast(right_op)); 1586c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); 1587c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org switch (instr->op()) { 1588fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org case Token::ROR: 1589fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (shift_count != 0) { 1590fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ Ror(result, left, Operand(shift_count)); 1591fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } else { 1592fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ Move(result, left); 1593fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 1594fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org break; 1595c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::SAR: 1596c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (shift_count != 0) { 1597c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sra(result, left, shift_count); 1598c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 1599c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Move(result, left); 1600c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1601c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1602c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::SHR: 1603c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (shift_count != 0) { 1604c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ srl(result, left, shift_count); 1605c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 1606c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->can_deopt()) { 1607c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(at, left, Operand(0x80000000)); 1608c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 1609c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1610c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Move(result, left); 1611c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1612c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1613c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::SHL: 1614c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (shift_count != 0) { 1615d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen_value()->representation().IsSmi() && 1616d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org instr->can_deopt()) { 1617d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (shift_count != 1) { 1618d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ sll(result, left, shift_count - 1); 1619d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ SmiTagCheckOverflow(result, result, scratch); 1620d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 1621d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ SmiTagCheckOverflow(result, left, scratch); 1622d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 1623d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg)); 1624d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 1625d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ sll(result, left, shift_count); 1626d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 1627c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 1628c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Move(result, left); 1629c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1630c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1631c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org default: 1632c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 1633c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1634c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1635c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1636c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1637c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1638c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1639c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoSubI(LSubI* instr) { 1640c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* left = instr->left(); 1641c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* right = instr->right(); 1642c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LOperand* result = instr->result(); 1643c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1644c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1645c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!can_overflow) { 1646c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (right->IsStackSlot() || right->IsArgument()) { 1647c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register right_reg = EmitLoadRegister(right, at); 1648c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Subu(ToRegister(result), ToRegister(left), Operand(right_reg)); 1649c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 1650c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(right->IsRegister() || right->IsConstantOperand()); 1651c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Subu(ToRegister(result), ToRegister(left), ToOperand(right)); 1652c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1653c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { // can_overflow. 1654c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register overflow = scratch0(); 1655c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch1(); 1656c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (right->IsStackSlot() || 1657c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org right->IsArgument() || 1658c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org right->IsConstantOperand()) { 1659c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register right_reg = EmitLoadRegister(right, scratch); 1660c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ SubuAndCheckForOverflow(ToRegister(result), 1661c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ToRegister(left), 1662c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org right_reg, 1663c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org overflow); // Reg at also used as scratch. 1664c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 1665c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(right->IsRegister()); 1666c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Due to overflow check macros not supporting constant operands, 1667c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // handling the IsConstantOperand case was moved to prev if clause. 1668c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ SubuAndCheckForOverflow(ToRegister(result), 1669c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ToRegister(left), 1670c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ToRegister(right), 1671c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org overflow); // Reg at also used as scratch. 1672c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1673c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg)); 1674c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1675c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1676c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1677c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1678c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoConstantI(LConstantI* instr) { 1679b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ li(ToRegister(instr->result()), Operand(instr->value())); 1680b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org} 1681b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org 1682b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org 1683b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgvoid LCodeGen::DoConstantS(LConstantS* instr) { 1684c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(ToRegister(instr->result()), Operand(instr->value())); 1685c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1686c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1687c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1688c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoConstantD(LConstantD* instr) { 1689c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(instr->result()->IsDoubleRegister()); 1690c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoubleRegister result = ToDoubleRegister(instr->result()); 1691c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org double v = instr->value(); 1692c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Move(result, v); 1693c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1694c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1695c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1696d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid LCodeGen::DoConstantE(LConstantE* instr) { 1697d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ li(ToRegister(instr->result()), Operand(instr->value())); 1698d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 1699d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 1700d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 1701c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoConstantT(LConstantT* instr) { 170264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Handle<Object> value = instr->value(); 170379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 1704fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ LoadObject(ToRegister(instr->result()), value); 1705c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1706c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1707c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 170878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgvoid LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 170978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org Register result = ToRegister(instr->result()); 1710c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register map = ToRegister(instr->value()); 171178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ EnumLength(result, map); 171278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org} 171378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 171478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 1715c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoElementsKind(LElementsKind* instr) { 1716c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 1717c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 1718c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1719c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Load map into |result|. 1720c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(result, FieldMemOperand(input, HeapObject::kMapOffset)); 1721c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Load the map's "bit field 2" into |result|. We only need the first byte, 1722c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // but the following bit field extraction takes care of that anyway. 1723c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lbu(result, FieldMemOperand(result, Map::kBitField2Offset)); 1724c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Retrieve elements_kind from bit field 2. 1725c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Ext(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount); 1726c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1727c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1728c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1729c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoValueOf(LValueOf* instr) { 1730c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 1731c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 1732c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register map = ToRegister(instr->temp()); 1733c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label done; 1734c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 17351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!instr->hydrogen()->value()->IsHeapObject()) { 17361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // If the object is a smi return the object. 17371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Move(result, input); 17381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(input, &done); 17391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 1740c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1741c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If the object is not a value type, return the object. 1742c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ GetObjectType(input, map, map); 1743c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done, ne, map, Operand(JS_VALUE_TYPE)); 1744c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(result, FieldMemOperand(input, JSValue::kValueOffset)); 1745c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1746c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 1747c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1748c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1749c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1750154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgvoid LCodeGen::DoDateField(LDateField* instr) { 1751c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register object = ToRegister(instr->date()); 1752154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Register result = ToRegister(instr->result()); 1753c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register scratch = ToRegister(instr->temp()); 1754154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Smi* index = instr->index(); 1755154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Label runtime, done; 1756154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ASSERT(object.is(a0)); 1757154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ASSERT(result.is(v0)); 1758154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ASSERT(!scratch.is(scratch0())); 1759154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ASSERT(!scratch.is(object)); 1760154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 1761de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ And(at, object, Operand(kSmiTagMask)); 1762de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 1763154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ GetObjectType(object, scratch, scratch); 1764de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_DATE_TYPE)); 1765154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 1766154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org if (index->value() == 0) { 1767154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ lw(result, FieldMemOperand(object, JSDate::kValueOffset)); 1768154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org } else { 1769154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org if (index->value() < JSDate::kFirstUncachedField) { 1770154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); 1771154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ li(scratch, Operand(stamp)); 1772154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ lw(scratch, MemOperand(scratch)); 1773154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ lw(scratch0(), FieldMemOperand(object, JSDate::kCacheStampOffset)); 1774154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ Branch(&runtime, ne, scratch, Operand(scratch0())); 1775154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ lw(result, FieldMemOperand(object, JSDate::kValueOffset + 1776154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org kPointerSize * index->value())); 1777154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ jmp(&done); 1778154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org } 1779154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ bind(&runtime); 1780154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ PrepareCallCFunction(2, scratch); 1781154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ li(a1, Operand(index)); 1782154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 1783154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ bind(&done); 1784154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org } 1785154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org} 1786154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 1787154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 1788a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { 1789a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register string = ToRegister(instr->string()); 1790a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register index = ToRegister(instr->index()); 1791a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register value = ToRegister(instr->value()); 1792a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register scratch = scratch0(); 1793a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org String::Encoding encoding = instr->encoding(); 1794a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 1795a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (FLAG_debug_code) { 1796a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ lw(at, FieldMemOperand(string, HeapObject::kMapOffset)); 1797a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset)); 1798a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 1799a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ And(at, at, Operand(kStringRepresentationMask | kStringEncodingMask)); 1800a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 1801a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 1802a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ Subu(at, at, Operand(encoding == String::ONE_BYTE_ENCODING 1803a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ? one_byte_seq_type : two_byte_seq_type)); 1804594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Check(eq, kUnexpectedStringType, at, Operand(zero_reg)); 1805a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 1806a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 1807a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ Addu(scratch, 1808a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org string, 1809a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Operand(SeqString::kHeaderSize - kHeapObjectTag)); 1810a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (encoding == String::ONE_BYTE_ENCODING) { 1811a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ Addu(at, scratch, index); 1812a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ sb(value, MemOperand(at)); 1813a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } else { 1814a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ sll(at, index, 1); 1815a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ Addu(at, scratch, at); 1816a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ sh(value, MemOperand(at)); 1817a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 1818a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 1819a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1820a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1821c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoThrow(LThrow* instr) { 1822c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input_reg = EmitLoadRegister(instr->value(), at); 1823c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(input_reg); 1824c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallRuntime(Runtime::kThrow, 1, instr); 1825c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1826c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (FLAG_debug_code) { 1827c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ stop("Unreachable code."); 1828c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1829c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1830c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1831c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1832c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoAddI(LAddI* instr) { 1833c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* left = instr->left(); 1834c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* right = instr->right(); 1835c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LOperand* result = instr->result(); 1836c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1837c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1838c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!can_overflow) { 1839c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (right->IsStackSlot() || right->IsArgument()) { 1840c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register right_reg = EmitLoadRegister(right, at); 1841c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Addu(ToRegister(result), ToRegister(left), Operand(right_reg)); 1842c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 1843c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(right->IsRegister() || right->IsConstantOperand()); 1844c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Addu(ToRegister(result), ToRegister(left), ToOperand(right)); 1845c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1846c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { // can_overflow. 1847c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register overflow = scratch0(); 1848c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch1(); 1849c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (right->IsStackSlot() || 1850c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org right->IsArgument() || 1851c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org right->IsConstantOperand()) { 1852c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register right_reg = EmitLoadRegister(right, scratch); 1853c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ AdduAndCheckForOverflow(ToRegister(result), 1854c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ToRegister(left), 1855c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org right_reg, 1856c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org overflow); // Reg at also used as scratch. 1857c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 1858c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(right->IsRegister()); 1859c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Due to overflow check macros not supporting constant operands, 1860c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // handling the IsConstantOperand case was moved to prev if clause. 1861c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ AdduAndCheckForOverflow(ToRegister(result), 1862c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ToRegister(left), 1863c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ToRegister(right), 1864c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org overflow); // Reg at also used as scratch. 1865c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1866c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg)); 1867c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1868c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1869c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1870c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1871471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid LCodeGen::DoMathMinMax(LMathMinMax* instr) { 1872c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* left = instr->left(); 1873c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* right = instr->right(); 1874471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1875471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; 1876fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen()->representation().IsSmiOrInteger32()) { 1877471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Register left_reg = ToRegister(left); 1878471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Operand right_op = (right->IsRegister() || right->IsConstantOperand()) 1879471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ? ToOperand(right) 1880471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org : Operand(EmitLoadRegister(right, at)); 1881471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Register result_reg = ToRegister(instr->result()); 1882471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Label return_right, done; 1883471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (!result_reg.is(left_reg)) { 1884471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ Branch(&return_right, NegateCondition(condition), left_reg, right_op); 1885471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ mov(result_reg, left_reg); 1886471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ Branch(&done); 1887471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 1888471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ Branch(&done, condition, left_reg, right_op); 1889471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&return_right); 1890471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ Addu(result_reg, zero_reg, right_op); 1891471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&done); 1892471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 1893471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ASSERT(instr->hydrogen()->representation().IsDouble()); 1894471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org FPURegister left_reg = ToDoubleRegister(left); 1895471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org FPURegister right_reg = ToDoubleRegister(right); 1896471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org FPURegister result_reg = ToDoubleRegister(instr->result()); 1897471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Label check_nan_left, check_zero, return_left, return_right, done; 1898471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ BranchF(&check_zero, &check_nan_left, eq, left_reg, right_reg); 1899471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ BranchF(&return_left, NULL, condition, left_reg, right_reg); 1900471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ Branch(&return_right); 1901471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 1902471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&check_zero); 1903471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // left == right != 0. 1904471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ BranchF(&return_left, NULL, ne, left_reg, kDoubleRegZero); 1905471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // At this point, both left and right are either 0 or -0. 1906471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (operation == HMathMinMax::kMathMin) { 1907471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ neg_d(left_reg, left_reg); 1908471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ sub_d(result_reg, left_reg, right_reg); 1909471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ neg_d(result_reg, result_reg); 1910471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 1911471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ add_d(result_reg, left_reg, right_reg); 1912471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 1913471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ Branch(&done); 1914471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 1915471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&check_nan_left); 1916471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // left == NaN. 1917471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ BranchF(NULL, &return_left, eq, left_reg, left_reg); 1918471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&return_right); 1919471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (!right_reg.is(result_reg)) { 1920471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ mov_d(result_reg, right_reg); 1921471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 1922471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ Branch(&done); 1923471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 1924471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&return_left); 1925471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (!left_reg.is(result_reg)) { 1926471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ mov_d(result_reg, left_reg); 1927471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 1928471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&done); 1929471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 1930471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org} 1931471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 1932471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 1933c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1934c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org DoubleRegister left = ToDoubleRegister(instr->left()); 1935c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org DoubleRegister right = ToDoubleRegister(instr->right()); 1936c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoubleRegister result = ToDoubleRegister(instr->result()); 1937c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org switch (instr->op()) { 1938c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::ADD: 1939c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ add_d(result, left, right); 1940c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1941c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::SUB: 1942c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sub_d(result, left, right); 1943c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1944c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::MUL: 1945c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mul_d(result, left, right); 1946c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1947c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::DIV: 1948c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ div_d(result, left, right); 1949c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1950c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::MOD: { 1951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Save a0-a3 on the stack. 1952c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RegList saved_regs = a0.bit() | a1.bit() | a2.bit() | a3.bit(); 1953c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ MultiPush(saved_regs); 1954c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1955c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ PrepareCallCFunction(0, 2, scratch0()); 1956c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ SetCallCDoubleArguments(left, right); 1957c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ CallCFunction( 1958c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ExternalReference::double_fp_operation(Token::MOD, isolate()), 1959c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 0, 2); 1960c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Move the result in the double result register. 1961c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ GetCFunctionDoubleResult(result); 1962c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1963c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Restore saved register. 1964c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ MultiPop(saved_regs); 1965c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1966c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1967c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org default: 1968c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 1969c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 1970c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1971c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1972c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1974c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoArithmeticT(LArithmeticT* instr) { 1975c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(ToRegister(instr->left()).is(a1)); 1976c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(ToRegister(instr->right()).is(a0)); 1977c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 1978c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1979c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org BinaryOpStub stub(instr->op(), NO_OVERWRITE); 19808432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1981c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Other arch use a nop here, to signal that there is no inlined 1982c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // patchable code. Mips does not need the nop, since our marker 1983c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // instruction (andi zero_reg) will never be used in normal code. 1984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1985c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1986c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 198732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.orgint LCodeGen::GetNextEmittedBlock() const { 198877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { 198977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (!chunk_->GetLabel(i)->HasReplacement()) return i; 1990c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1991c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return -1; 1992c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1993c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 19941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<class InstrType> 19951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid LCodeGen::EmitBranch(InstrType instr, 1996c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com Condition condition, 1997c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com Register src1, 1998c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com const Operand& src2) { 19991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org int left_block = instr->TrueDestination(chunk_); 2000e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org int right_block = instr->FalseDestination(chunk_); 20011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 200277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org int next_block = GetNextEmittedBlock(); 2003c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com if (right_block == left_block || condition == al) { 2004c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EmitGoto(left_block); 2005c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (left_block == next_block) { 2006c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(chunk_->GetAssemblyLabel(right_block), 2007c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com NegateCondition(condition), src1, src2); 2008c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (right_block == next_block) { 2009c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com __ Branch(chunk_->GetAssemblyLabel(left_block), condition, src1, src2); 2010c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 2011c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com __ Branch(chunk_->GetAssemblyLabel(left_block), condition, src1, src2); 2012c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(chunk_->GetAssemblyLabel(right_block)); 2013c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2014c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2015c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2016c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 20171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<class InstrType> 20181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid LCodeGen::EmitBranchF(InstrType instr, 2019c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com Condition condition, 2020c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com FPURegister src1, 2021c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com FPURegister src2) { 20221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org int right_block = instr->FalseDestination(chunk_); 20231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org int left_block = instr->TrueDestination(chunk_); 20241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 202577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org int next_block = GetNextEmittedBlock(); 2026c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (right_block == left_block) { 2027c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EmitGoto(left_block); 2028c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (left_block == next_block) { 2029c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ BranchF(chunk_->GetAssemblyLabel(right_block), NULL, 2030c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com NegateCondition(condition), src1, src2); 2031c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (right_block == next_block) { 2032c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL, 2033c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com condition, src1, src2); 2034c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 2035c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL, 2036c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com condition, src1, src2); 2037c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(chunk_->GetAssemblyLabel(right_block)); 2038c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2039c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2040c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2041c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2042c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.comtemplate<class InstrType> 2043c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.comvoid LCodeGen::EmitFalseBranchF(InstrType instr, 2044c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com Condition condition, 2045c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com FPURegister src1, 2046c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com FPURegister src2) { 2047c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com int false_block = instr->FalseDestination(chunk_); 2048c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com __ BranchF(chunk_->GetAssemblyLabel(false_block), NULL, 2049c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com condition, src1, src2); 2050c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com} 2051c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com 2052c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com 20534e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid LCodeGen::DoDebugBreak(LDebugBreak* instr) { 20544e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ stop("LDebugBreak"); 20554e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org} 20564e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 20574e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 2058e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgvoid LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) { 2059e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Representation r = instr->hydrogen()->value()->representation(); 2060e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (r.IsSmiOrInteger32() || r.IsDouble()) { 2061e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org EmitBranch(instr, al, zero_reg, Operand(zero_reg)); 2062e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } else { 2063e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org ASSERT(r.IsTagged()); 2064e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Register reg = ToRegister(instr->value()); 2065e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org HType type = instr->hydrogen()->value()->type(); 2066e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (type.IsTaggedNumber()) { 2067e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org EmitBranch(instr, al, zero_reg, Operand(zero_reg)); 2068e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } 2069e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); 2070e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org __ lw(scratch0(), FieldMemOperand(reg, HeapObject::kMapOffset)); 2071e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 2072e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org EmitBranch(instr, eq, scratch0(), Operand(at)); 2073e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } 2074e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org} 2075e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 2076e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 2077c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoBranch(LBranch* instr) { 2078c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Representation r = instr->hydrogen()->value()->representation(); 2079a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (r.IsInteger32() || r.IsSmi()) { 2080b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(!info()->IsStub()); 2081c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register reg = ToRegister(instr->value()); 20821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, ne, reg, Operand(zero_reg)); 2083c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (r.IsDouble()) { 2084b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(!info()->IsStub()); 2085c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org DoubleRegister reg = ToDoubleRegister(instr->value()); 2086c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Test the double value. Zero and NaN are false. 20871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranchF(instr, nue, reg, kDoubleRegZero); 2088c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 2089c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(r.IsTagged()); 2090c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register reg = ToRegister(instr->value()); 2091c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org HType type = instr->hydrogen()->value()->type(); 2092c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (type.IsBoolean()) { 2093b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(!info()->IsStub()); 2094c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kTrueValueRootIndex); 20951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, eq, reg, Operand(at)); 2096c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (type.IsSmi()) { 2097b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(!info()->IsStub()); 20981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, ne, reg, Operand(zero_reg)); 20991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (type.IsJSArray()) { 21001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(!info()->IsStub()); 21011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, al, zero_reg, Operand(zero_reg)); 21021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (type.IsHeapNumber()) { 21031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(!info()->IsStub()); 21041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org DoubleRegister dbl_scratch = double_scratch0(); 21051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); 21061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Test the double value. Zero and NaN are false. 21071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranchF(instr, nue, dbl_scratch, kDoubleRegZero); 21081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (type.IsString()) { 21091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(!info()->IsStub()); 21101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ lw(at, FieldMemOperand(reg, String::kLengthOffset)); 21111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, ne, at, Operand(zero_reg)); 2112c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 2113c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 2114c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Avoid deopts in the case where we've never executed this path before. 21151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); 2116c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2117c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (expected.Contains(ToBooleanStub::UNDEFINED)) { 2118c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // undefined -> false. 2119c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 21201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at)); 2121c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2122c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (expected.Contains(ToBooleanStub::BOOLEAN)) { 2123c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Boolean -> its value. 2124c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kTrueValueRootIndex); 21251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Branch(instr->TrueLabel(chunk_), eq, reg, Operand(at)); 2126c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kFalseValueRootIndex); 21271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at)); 2128c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2129c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (expected.Contains(ToBooleanStub::NULL_TYPE)) { 2130c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // 'null' -> false. 2131c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kNullValueRootIndex); 21321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at)); 2133c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2134c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2135c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (expected.Contains(ToBooleanStub::SMI)) { 2136c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Smis: 0 -> false, all other -> true. 21371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg)); 21381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); 2139c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (expected.NeedsMap()) { 2140c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If we need a map later and have a Smi -> deopt. 2141c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(at, reg, Operand(kSmiTagMask)); 2142c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 2143c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2144c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2145c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const Register map = scratch0(); 2146c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (expected.NeedsMap()) { 2147c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(map, FieldMemOperand(reg, HeapObject::kMapOffset)); 2148c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (expected.CanBeUndetectable()) { 2149c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Undetectable -> false. 2150c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset)); 2151c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(at, at, Operand(1 << Map::kIsUndetectable)); 21521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Branch(instr->FalseLabel(chunk_), ne, at, Operand(zero_reg)); 2153c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2154c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2155c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2156c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { 2157c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // spec object -> true. 2158c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); 21591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Branch(instr->TrueLabel(chunk_), 21601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ge, at, Operand(FIRST_SPEC_OBJECT_TYPE)); 2161c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2162c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2163c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (expected.Contains(ToBooleanStub::STRING)) { 2164c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // String value -> false iff empty. 2165c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label not_string; 2166c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); 2167c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(¬_string, ge , at, Operand(FIRST_NONSTRING_TYPE)); 2168c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(at, FieldMemOperand(reg, String::kLengthOffset)); 21691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Branch(instr->TrueLabel(chunk_), ne, at, Operand(zero_reg)); 21701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Branch(instr->FalseLabel(chunk_)); 2171c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(¬_string); 2172c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2173c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2174f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org if (expected.Contains(ToBooleanStub::SYMBOL)) { 2175f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Symbol value -> true. 2176f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org const Register scratch = scratch1(); 2177f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); 21781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Branch(instr->TrueLabel(chunk_), eq, scratch, Operand(SYMBOL_TYPE)); 2179f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } 2180f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 2181c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 2182c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // heap number -> false iff +0, -0, or NaN. 2183c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoubleRegister dbl_scratch = double_scratch0(); 2184c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label not_heap_number; 2185c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 2186c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(¬_heap_number, ne, map, Operand(at)); 2187c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); 21881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), 21891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ne, dbl_scratch, kDoubleRegZero); 2190c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Falls through if dbl_scratch == 0. 21911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Branch(instr->FalseLabel(chunk_)); 2192c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(¬_heap_number); 2193c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2194c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 21951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!expected.IsGeneric()) { 21961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // We've seen something for the first time -> deopt. 21971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // This can only happen if we are not generic already. 21981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg)); 21991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 2200c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2201c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2202c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2203c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2204c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2205c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::EmitGoto(int block) { 220632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (!IsNextEmittedBlock(block)) { 22071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block))); 2208c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2209c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2210c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2211c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2212c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoGoto(LGoto* instr) { 2213c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EmitGoto(instr->block_id()); 2214c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2215c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2216c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2217c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgCondition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { 2218c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Condition cond = kNoCondition; 2219c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org switch (op) { 2220c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::EQ: 2221c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::EQ_STRICT: 2222c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cond = eq; 2223c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 2224c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::LT: 2225c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cond = is_unsigned ? lo : lt; 2226c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 2227c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::GT: 2228c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cond = is_unsigned ? hi : gt; 2229c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 2230c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::LTE: 2231c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cond = is_unsigned ? ls : le; 2232c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 2233c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::GTE: 2234c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cond = is_unsigned ? hs : ge; 2235c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 2236c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::IN: 2237c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case Token::INSTANCEOF: 2238c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org default: 2239c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 2240c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2241c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return cond; 2242c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2243c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2244c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2245e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgvoid LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { 2246c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* left = instr->left(); 2247c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* right = instr->right(); 2248c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Condition cond = TokenToCondition(instr->op(), false); 2249c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2250c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (left->IsConstantOperand() && right->IsConstantOperand()) { 2251c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // We can statically evaluate the comparison. 2252c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org double left_val = ToDouble(LConstantOperand::cast(left)); 2253c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org double right_val = ToDouble(LConstantOperand::cast(right)); 22541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org int next_block = EvalComparison(instr->op(), left_val, right_val) ? 22551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_); 2256c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EmitGoto(next_block); 2257c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 2258c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->is_double()) { 2259c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Compare left and right as doubles and load the 2260c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // resulting flags into the normal status register. 2261c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FPURegister left_reg = ToDoubleRegister(left); 2262c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FPURegister right_reg = ToDoubleRegister(right); 2263c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2264c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If a NaN is involved, i.e. the result is unordered, 2265c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // jump to false block label. 22661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ BranchF(NULL, instr->FalseLabel(chunk_), eq, 2267c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org left_reg, right_reg); 2268c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 22691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranchF(instr, cond, left_reg, right_reg); 2270c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 2271c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register cmp_left; 2272c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Operand cmp_right = Operand(0); 2273c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2274c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (right->IsConstantOperand()) { 2275b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org int32_t value = ToInteger32(LConstantOperand::cast(right)); 2276b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 2277b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org cmp_left = ToRegister(left); 2278b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org cmp_right = Operand(Smi::FromInt(value)); 2279b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org } else { 2280b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org cmp_left = ToRegister(left); 2281b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org cmp_right = Operand(value); 2282b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org } 2283c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (left->IsConstantOperand()) { 2284b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org int32_t value = ToInteger32(LConstantOperand::cast(left)); 2285b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 2286b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org cmp_left = ToRegister(right); 2287b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org cmp_right = Operand(Smi::FromInt(value)); 2288b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org } else { 2289b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org cmp_left = ToRegister(right); 2290b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org cmp_right = Operand(value); 2291b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org } 2292c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // We transposed the operands. Reverse the condition. 2293c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cond = ReverseCondition(cond); 2294c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 2295c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp_left = ToRegister(left); 2296c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp_right = Operand(ToRegister(right)); 2297c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2298c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 22991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, cond, cmp_left, cmp_right); 2300c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2301c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2302c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2303c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2304c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2305c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 2306c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register left = ToRegister(instr->left()); 2307c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register right = ToRegister(instr->right()); 2308c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 23091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, eq, left, Operand(right)); 2310c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2311c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2312c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2313c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.comvoid LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) { 2314c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com if (instr->hydrogen()->representation().IsTagged()) { 2315c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com Register input_reg = ToRegister(instr->object()); 2316c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com __ li(at, Operand(factory()->the_hole_value())); 2317c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com EmitBranch(instr, eq, input_reg, Operand(at)); 2318c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com return; 2319c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com } 2320c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com 2321c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com DoubleRegister input_reg = ToDoubleRegister(instr->object()); 2322c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com EmitFalseBranchF(instr, eq, input_reg, input_reg); 2323c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com 2324c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com Register scratch = scratch0(); 2325c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com __ FmoveHigh(scratch, input_reg); 2326c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com EmitBranch(instr, eq, scratch, Operand(kHoleNanUpper32)); 2327c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com} 2328c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com 2329c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com 2330c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgCondition LCodeGen::EmitIsObject(Register input, 2331c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register temp1, 23320ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Register temp2, 2333c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* is_not_object, 2334c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* is_object) { 2335c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(input, is_not_object); 2336c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2337c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(temp2, Heap::kNullValueRootIndex); 2338c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(is_object, eq, input, Operand(temp2)); 2339c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2340c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Load map. 2341c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(temp1, FieldMemOperand(input, HeapObject::kMapOffset)); 2342c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Undetectable objects behave like undefined. 2343c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lbu(temp2, FieldMemOperand(temp1, Map::kBitFieldOffset)); 2344c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(temp2, temp2, Operand(1 << Map::kIsUndetectable)); 2345c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(is_not_object, ne, temp2, Operand(zero_reg)); 2346c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2347c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Load instance type and check that it is in object type range. 2348c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lbu(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset)); 2349c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(is_not_object, 2350c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org lt, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2351c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2352c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return le; 2353c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2354c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2355c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2356c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 2357c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register reg = ToRegister(instr->value()); 2358c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register temp1 = ToRegister(instr->temp()); 2359c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register temp2 = scratch0(); 2360c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2361c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Condition true_cond = 23621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitIsObject(reg, temp1, temp2, 23631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->FalseLabel(chunk_), instr->TrueLabel(chunk_)); 2364c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 23651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, true_cond, temp2, 2366c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2367c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2368c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2369c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2370f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.orgCondition LCodeGen::EmitIsString(Register input, 2371f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org Register temp1, 23721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label* is_not_string, 23731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org SmiCheck check_needed = INLINE_SMI_CHECK) { 23741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (check_needed == INLINE_SMI_CHECK) { 23751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(input, is_not_string); 23761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 2377f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org __ GetObjectType(input, temp1, temp1); 2378f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 2379f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org return lt; 2380f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org} 2381f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 2382f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 2383f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.orgvoid LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 2384c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register reg = ToRegister(instr->value()); 2385c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register temp1 = ToRegister(instr->temp()); 2386f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 23871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org SmiCheck check_needed = 23881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->hydrogen()->value()->IsHeapObject() 23891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 2390f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org Condition true_cond = 23911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitIsString(reg, temp1, instr->FalseLabel(chunk_), check_needed); 2392f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 23931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, true_cond, temp1, 2394f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org Operand(FIRST_NONSTRING_TYPE)); 2395f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org} 2396f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 2397f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 2398c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 2399c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input_reg = EmitLoadRegister(instr->value(), at); 2400c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(at, input_reg, kSmiTagMask); 24011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, eq, at, Operand(zero_reg)); 2402c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2403c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2404c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2405c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 2406c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 2407c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register temp = ToRegister(instr->temp()); 2408c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 24091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!instr->hydrogen()->value()->IsHeapObject()) { 24101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(input, instr->FalseLabel(chunk_)); 24111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 2412c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(temp, FieldMemOperand(input, HeapObject::kMapOffset)); 2413c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lbu(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); 2414c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(at, temp, Operand(1 << Map::kIsUndetectable)); 24151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, ne, at, Operand(zero_reg)); 2416c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2417c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2418c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2419f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.orgstatic Condition ComputeCompareCondition(Token::Value op) { 2420f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org switch (op) { 2421f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org case Token::EQ_STRICT: 2422f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org case Token::EQ: 2423f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org return eq; 2424f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org case Token::LT: 2425f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org return lt; 2426f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org case Token::GT: 2427f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org return gt; 2428f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org case Token::LTE: 2429f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org return le; 2430f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org case Token::GTE: 2431f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org return ge; 2432f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org default: 2433f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org UNREACHABLE(); 2434f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org return kNoCondition; 2435f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org } 2436f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org} 2437f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 2438f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 2439f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.orgvoid LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { 2440f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org Token::Value op = instr->op(); 2441f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 24428432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 2443f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 2444f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 2445f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org Condition condition = ComputeCompareCondition(op); 2446f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 24471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, condition, v0, Operand(zero_reg)); 2448f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org} 2449f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 2450f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org 2451c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgstatic InstanceType TestType(HHasInstanceTypeAndBranch* instr) { 2452c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org InstanceType from = instr->from(); 2453c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org InstanceType to = instr->to(); 2454c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (from == FIRST_TYPE) return to; 2455c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(from == to || to == LAST_TYPE); 2456c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return from; 2457c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2458c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2459c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2460c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgstatic Condition BranchCondition(HHasInstanceTypeAndBranch* instr) { 2461c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org InstanceType from = instr->from(); 2462c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org InstanceType to = instr->to(); 2463c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (from == to) return eq; 2464c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (to == LAST_TYPE) return hs; 2465c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (from == FIRST_TYPE) return ls; 2466c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 2467c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return eq; 2468c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2469c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2471c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 2472c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 2473c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 2474c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 24751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!instr->hydrogen()->value()->IsHeapObject()) { 24761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(input, instr->FalseLabel(chunk_)); 24771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 2478c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2479c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ GetObjectType(input, scratch, scratch); 24801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, 2481c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org BranchCondition(instr->hydrogen()), 2482c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch, 2483c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Operand(TestType(instr->hydrogen()))); 2484c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2485c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2486c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2487c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 2488c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 2489c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 2490c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2491c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ AssertString(input); 2492c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2493c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(result, FieldMemOperand(input, String::kHashFieldOffset)); 2494c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ IndexFromHash(result, result); 2495c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2496c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2497c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2498c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoHasCachedArrayIndexAndBranch( 2499c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LHasCachedArrayIndexAndBranch* instr) { 2500c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 2501c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 2502c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2503c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(scratch, 2504c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FieldMemOperand(input, String::kHashFieldOffset)); 2505c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(at, scratch, Operand(String::kContainsCachedArrayIndexMask)); 25061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, eq, at, Operand(zero_reg)); 2507c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2508c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2509c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 25102efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Branches to a label or falls through with the answer in flags. Trashes 25112efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// the temp registers, but not the input. 2512c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::EmitClassOfTest(Label* is_true, 2513c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* is_false, 2514c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<String>class_name, 2515c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register input, 2516c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register temp, 2517c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register temp2) { 2518c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!input.is(temp)); 25192efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ASSERT(!input.is(temp2)); 25202efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ASSERT(!temp.is(temp2)); 25212efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 2522c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(input, is_false); 2523c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 252459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Function"))) { 2525c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Assuming the following assertions, we can use the same compares to test 2526c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // for both being a function type and being in the object type range. 2527c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 2528c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == 2529c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FIRST_SPEC_OBJECT_TYPE + 1); 2530c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == 2531c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LAST_SPEC_OBJECT_TYPE - 1); 2532c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); 2533c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2534c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ GetObjectType(input, temp, temp2); 2535c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(is_false, lt, temp2, Operand(FIRST_SPEC_OBJECT_TYPE)); 2536c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(is_true, eq, temp2, Operand(FIRST_SPEC_OBJECT_TYPE)); 2537c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(is_true, eq, temp2, Operand(LAST_SPEC_OBJECT_TYPE)); 2538c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 2539c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Faster code path to avoid two compares: subtract lower bound from the 2540c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // actual type and do a signed compare with the width of the type range. 2541c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ GetObjectType(input, temp, temp2); 2542c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Subu(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2543c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(is_false, gt, temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - 2544c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2545c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2546c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2547c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range. 2548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Check if the constructor in the map is a function. 2549c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(temp, FieldMemOperand(temp, Map::kConstructorOffset)); 2550c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2551c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Objects with a non-function constructor have class 'Object'. 2552c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ GetObjectType(temp, temp2, temp2); 255359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Object"))) { 2554c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(is_true, ne, temp2, Operand(JS_FUNCTION_TYPE)); 2555c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 2556c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(is_false, ne, temp2, Operand(JS_FUNCTION_TYPE)); 2557c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2558c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2559c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // temp now contains the constructor function. Grab the 2560c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // instance class name from there. 2561c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(temp, FieldMemOperand(temp, JSFunction::kSharedFunctionInfoOffset)); 2562c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(temp, FieldMemOperand(temp, 2563c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org SharedFunctionInfo::kInstanceClassNameOffset)); 2564750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // The class name we are testing against is internalized since it's a literal. 2565750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // The name in the constructor is internalized because of the way the context 2566750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // is booted. This routine isn't expected to work for random API-created 2567c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // classes and it doesn't have to because you can't access it with natives 2568750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // syntax. Since both sides are internalized it is sufficient to use an 2569750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // identity comparison. 2570c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2571c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // End with the address of this class_name instance in temp register. 2572c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // On MIPS, the caller must do the comparison with Handle<String>class_name. 2573c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2574c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2575c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2576c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2577c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 2578c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register temp = scratch0(); 2579c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register temp2 = ToRegister(instr->temp()); 2580c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<String> class_name = instr->hydrogen()->class_name(); 2581c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 25821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), 25831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org class_name, input, temp, temp2); 2584c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 25851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, eq, temp, Operand(class_name)); 2586c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2587c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2588c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2589c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 2590c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register reg = ToRegister(instr->value()); 2591c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register temp = ToRegister(instr->temp()); 2592c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2593c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(temp, FieldMemOperand(reg, HeapObject::kMapOffset)); 25941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, eq, temp, Operand(instr->map())); 2595c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2596c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2597c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2598c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2599c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label true_label, done; 2600c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(ToRegister(instr->left()).is(a0)); // Object is in a0. 2601c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(ToRegister(instr->right()).is(a1)); // Function is in a1. 2602c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 2603c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(result.is(v0)); 2604c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2605c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org InstanceofStub stub(InstanceofStub::kArgsInRegisters); 26068432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 2607c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2608c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&true_label, eq, result, Operand(zero_reg)); 2609c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(result, Operand(factory()->false_value())); 2610c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done); 2611c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&true_label); 2612c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(result, Operand(factory()->true_value())); 2613c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 2614c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2615c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2616c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2617c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { 2618c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org class DeferredInstanceOfKnownGlobal: public LDeferredCode { 2619c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org public: 2620c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeferredInstanceOfKnownGlobal(LCodeGen* codegen, 2621c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LInstanceOfKnownGlobal* instr) 2622c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : LDeferredCode(codegen), instr_(instr) { } 2623c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual void Generate() { 26240ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_); 2625c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2626c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual LInstruction* instr() { return instr_; } 2627c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* map_check() { return &map_check_; } 2628c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2629c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org private: 2630c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LInstanceOfKnownGlobal* instr_; 2631c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label map_check_; 2632c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org }; 2633c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2634c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeferredInstanceOfKnownGlobal* deferred; 26357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); 2636c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2637c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label done, false_result; 2638c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register object = ToRegister(instr->value()); 2639c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register temp = ToRegister(instr->temp()); 2640c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 2641c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2642c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(object.is(a0)); 2643c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(result.is(v0)); 2644c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2645c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // A Smi is not instance of anything. 2646c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(object, &false_result); 2647c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2648c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // This is the inlined call site instanceof cache. The two occurences of the 2649c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // hole value will be patched to the last map/result pair generated by the 2650c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // instanceof stub. 2651c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label cache_miss; 2652c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register map = temp; 2653c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(map, FieldMemOperand(object, HeapObject::kMapOffset)); 2654c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2655c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 2656c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(deferred->map_check()); // Label for calculating code patching. 2657c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // We use Factory::the_hole_value() on purpose instead of loading from the 2658c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // root array to force relocation to be able to later patch with 2659c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // the cached map. 2660f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org Handle<Cell> cell = factory()->NewCell(factory()->the_hole_value()); 266105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org __ li(at, Operand(Handle<Object>(cell))); 2662b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ lw(at, FieldMemOperand(at, PropertyCell::kValueOffset)); 2663c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&cache_miss, ne, map, Operand(at)); 2664c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // We use Factory::the_hole_value() on purpose instead of loading from the 2665c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // root array to force relocation to be able to later patch 2666c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // with true or false. 266788aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org __ li(result, Operand(factory()->the_hole_value()), CONSTANT_SIZE); 2668c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done); 2669c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2670c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // The inlined call site cache did not match. Check null and string before 2671c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // calling the deferred code. 2672c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&cache_miss); 2673c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Null is not instance of anything. 2674c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(temp, Heap::kNullValueRootIndex); 2675c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&false_result, eq, object, Operand(temp)); 2676c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2677c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // String values is not instance of anything. 2678c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Condition cc = __ IsObjectStringType(object, temp, temp); 2679c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&false_result, cc, temp, Operand(zero_reg)); 2680c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2681c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Go to the deferred code. 2682c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(deferred->entry()); 2683c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2684c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&false_result); 2685c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(result, Heap::kFalseValueRootIndex); 2686c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2687c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Here result has either true or false. Deferred code also produces true or 2688c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // false object. 2689c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(deferred->exit()); 2690c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 2691c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2692c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2693c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 26940ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 26950ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Label* map_check) { 2696c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 2697c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(result.is(v0)); 2698c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org InstanceofStub::Flags flags = InstanceofStub::kNoFlags; 2700c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org flags = static_cast<InstanceofStub::Flags>( 2701c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org flags | InstanceofStub::kArgsInRegisters); 2702c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org flags = static_cast<InstanceofStub::Flags>( 2703c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org flags | InstanceofStub::kCallSiteInlineCheck); 2704c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org flags = static_cast<InstanceofStub::Flags>( 2705c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org flags | InstanceofStub::kReturnTrueFalseObject); 2706c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org InstanceofStub stub(flags); 2707c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2708c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 2709c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2710c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Get the temp register reserved by the instruction. This needs to be t0 as 2711c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // its slot of the pushing of safepoint registers is used to communicate the 2712c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // offset to the location of the map check. 2713c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register temp = ToRegister(instr->temp()); 2714c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(temp.is(t0)); 271564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ LoadHeapObject(InstanceofStub::right(), instr->function()); 2716c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org static const int kAdditionalDelta = 7; 2717c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; 2718c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label before_push_delta; 2719c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&before_push_delta); 2720c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org { 2721c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 272288aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org __ li(temp, Operand(delta * kPointerSize), CONSTANT_SIZE); 2723c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ StoreToSafepointRegisterSlot(temp, temp); 2724c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 27258432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCodeGeneric(stub.GetCode(isolate()), 2726c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RelocInfo::CODE_TARGET, 2727c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org instr, 2728c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 2729e4bfb26083376408caf54512da4924003f090a61danno@chromium.org LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); 27300ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 2731c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Put the result value into the result register slot and 2732c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // restore all registers. 2733c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ StoreToSafepointRegisterSlot(result, result); 2734c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2735c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2736c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 27374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid LCodeGen::DoInstanceSize(LInstanceSize* instr) { 27384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register object = ToRegister(instr->object()); 27394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register result = ToRegister(instr->result()); 27404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ lw(result, FieldMemOperand(object, HeapObject::kMapOffset)); 27414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ lbu(result, FieldMemOperand(result, Map::kInstanceSizeOffset)); 27424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 27434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 27444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 2745c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCmpT(LCmpT* instr) { 2746c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Token::Value op = instr->op(); 2747c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 27488432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 2749c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 2750c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // On MIPS there is no need for a "no inlined smi code" marker (nop). 2751c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2752c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Condition condition = ComputeCompareCondition(op); 2753c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // A minor optimization that relies on LoadRoot always emitting one 2754c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // instruction. 2755c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm()); 2756750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Label done, check; 2757c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(USE_DELAY_SLOT, &done, condition, v0, Operand(zero_reg)); 2758750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org __ bind(&check); 2759c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); 2760750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org ASSERT_EQ(1, masm()->InstructionsGeneratedSince(&check)); 2761c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); 2762c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 2763c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2764c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2765c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2766c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoReturn(LReturn* instr) { 276759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (FLAG_trace && info()->IsOptimizing()) { 2768c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Push the return value on the stack as the parameter. 2769c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Runtime::TraceExit returns its parameter in v0. 2770c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(v0); 2771c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ CallRuntime(Runtime::kTraceExit, 1); 2772c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2773e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (info()->saves_caller_doubles()) { 27747c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org ASSERT(NeedsEagerFrame()); 27757c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org BitVector* doubles = chunk()->allocated_double_registers(); 27767c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org BitVector::Iterator save_iterator(doubles); 27777c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org int count = 0; 27787c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org while (!save_iterator.Done()) { 27797c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), 27807c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org MemOperand(sp, count * kDoubleSize)); 27817c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org save_iterator.Advance(); 27827c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org count++; 27837c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 27847c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 27854e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org int no_frame_start = -1; 278659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (NeedsEagerFrame()) { 278759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ mov(sp, fp); 27884e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org no_frame_start = masm_->pc_offset(); 2789b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ Pop(ra, fp); 2790ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 2791ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if (instr->has_constant_parameter_count()) { 2792ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org int parameter_count = ToInteger32(instr->constant_parameter_count()); 2793ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org int32_t sp_delta = (parameter_count + 1) * kPointerSize; 2794ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if (sp_delta != 0) { 2795ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ Addu(sp, sp, Operand(sp_delta)); 27967c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 2797ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else { 2798ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Register reg = ToRegister(instr->parameter_count()); 2799ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // The argument count parameter is a smi 2800ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ SmiUntag(reg); 2801ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ sll(at, reg, kPointerSizeLog2); 2802ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ Addu(sp, sp, at); 280359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 2804ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2805c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Jump(ra); 28064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 28074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org if (no_frame_start != -1) { 28084e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); 28094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 2810c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2811c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2812c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2813c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 2814c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 2815c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(at, Operand(Handle<Object>(instr->hydrogen()->cell()))); 2816f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ lw(result, FieldMemOperand(at, Cell::kValueOffset)); 2817c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 2818c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2819c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(eq, instr->environment(), result, Operand(at)); 2820c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2821c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2822c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2823c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2824c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { 2825c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->global_object()).is(a0)); 2826c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 2827c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2828c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(a2, Operand(instr->name())); 2829c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET 2830c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : RelocInfo::CODE_TARGET_CONTEXT; 2831c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2832c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallCode(ic, mode, instr); 2833c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2834c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2835c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2836c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { 2837e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org Register value = ToRegister(instr->value()); 2838e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org Register cell = scratch0(); 2839c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2840c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Load the cell. 2841e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org __ li(cell, Operand(instr->hydrogen()->cell())); 2842c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2843c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If the cell we are storing to contains the hole it could have 2844c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // been deleted from the property dictionary. In that case, we need 2845c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // to update the property details in the property dictionary to mark 2846c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // it as no longer deleted. 2847c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 2848e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org // We use a temp to check the payload. 2849c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register payload = ToRegister(instr->temp()); 2850f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ lw(payload, FieldMemOperand(cell, Cell::kValueOffset)); 2851c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2852e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org DeoptimizeIf(eq, instr->environment(), payload, Operand(at)); 2853c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2854c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2855c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Store the value. 2856f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ sw(value, FieldMemOperand(cell, Cell::kValueOffset)); 285764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Cells are always rescanned, so no write barrier here. 2858c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2859c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2860c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2861c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { 2862c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->global_object()).is(a1)); 2863c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->value()).is(a0)); 2864c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2865c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(a2, Operand(instr->name())); 28661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 2867c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ? isolate()->builtins()->StoreIC_Initialize_Strict() 2868c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : isolate()->builtins()->StoreIC_Initialize(); 2869c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); 2870c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2871c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2872c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2873c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 2874c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register context = ToRegister(instr->context()); 2875c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 28767ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 2877c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(result, ContextOperand(context, instr->slot_index())); 287864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 287964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 28807ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 28817ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org if (instr->hydrogen()->DeoptimizesOnHole()) { 28827ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org DeoptimizeIf(eq, instr->environment(), result, Operand(at)); 28837ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } else { 28847ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org Label is_not_hole; 28857ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ Branch(&is_not_hole, ne, result, Operand(at)); 28867ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ LoadRoot(result, Heap::kUndefinedValueRootIndex); 28877ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ bind(&is_not_hole); 28887ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } 288964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 2890c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2891c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2892c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2893c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { 2894c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register context = ToRegister(instr->context()); 2895c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register value = ToRegister(instr->value()); 28967ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org Register scratch = scratch0(); 2897c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MemOperand target = ContextOperand(context, instr->slot_index()); 28987ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 28997ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org Label skip_assignment; 29007ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 290164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 290264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ lw(scratch, target); 290364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 29047ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 29057ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org if (instr->hydrogen()->DeoptimizesOnHole()) { 29067ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org DeoptimizeIf(eq, instr->environment(), scratch, Operand(at)); 29077ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } else { 29087ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ Branch(&skip_assignment, ne, scratch, Operand(at)); 29097ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } 291064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 29117ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 2912c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(value, target); 2913c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->NeedsWriteBarrier()) { 2914c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org SmiCheck check_needed = 29151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->hydrogen()->value()->IsHeapObject() 29161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 2917c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ RecordWriteContextSlot(context, 2918c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org target.offset(), 2919c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org value, 2920c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch0(), 2921c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org GetRAState(), 2922c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org kSaveFPRegs, 2923c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EMIT_REMEMBERED_SET, 2924c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org check_needed); 2925c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 29267ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 29277ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ bind(&skip_assignment); 2928c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2929c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2930c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2931c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 293253ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org HObjectAccess access = instr->hydrogen()->access(); 293353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org int offset = access.offset(); 2934c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register object = ToRegister(instr->object()); 2935d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 2936d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (access.IsExternalMemory()) { 2937d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register result = ToRegister(instr->result()); 2938d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ lw(result, MemOperand(object, offset)); 2939d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return; 2940d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 2941d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 294257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (instr->hydrogen()->representation().IsDouble()) { 294357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org DoubleRegister result = ToDoubleRegister(instr->result()); 294457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ ldc1(result, FieldMemOperand(object, offset)); 294557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org return; 2946f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 294757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 294857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Register result = ToRegister(instr->result()); 294953ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (access.IsInobject()) { 295057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ lw(result, FieldMemOperand(object, offset)); 2951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 295257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 295357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ lw(result, FieldMemOperand(result, offset)); 2954c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 2955c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2956c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2957c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2958c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 2959c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->object()).is(a0)); 2960c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 2961c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2962c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Name is always in a2. 2963c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(a2, Operand(instr->name())); 2964c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2965c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 2966c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 2967c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2968c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2969c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 2970c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 2971c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register function = ToRegister(instr->function()); 2972c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 2973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2974c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Check that the function really is a function. Load map into the 2975c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // result register. 2976c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ GetObjectType(function, result, scratch); 2977c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_FUNCTION_TYPE)); 2978c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2979c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Make sure that the function has an instance prototype. 2980c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label non_instance; 2981c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lbu(scratch, FieldMemOperand(result, Map::kBitFieldOffset)); 2982c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(scratch, scratch, Operand(1 << Map::kHasNonInstancePrototype)); 2983c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&non_instance, ne, scratch, Operand(zero_reg)); 2984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2985c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Get the prototype or initial map from the function. 2986c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(result, 2987c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 2988c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2989c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Check that the function has a prototype or an initial map. 2990c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2991c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(eq, instr->environment(), result, Operand(at)); 2992c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2993c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If the function does not have an initial map, we're done. 2994c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label done; 2995c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ GetObjectType(result, scratch, scratch); 2996c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done, ne, scratch, Operand(MAP_TYPE)); 2997c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2998c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Get the prototype from the initial map. 2999c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(result, FieldMemOperand(result, Map::kPrototypeOffset)); 3000c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done); 3001c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3002c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Non-instance prototype: Fetch prototype from constructor field 3003c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // in initial map. 3004c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&non_instance); 3005c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(result, FieldMemOperand(result, Map::kConstructorOffset)); 3006c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3007c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // All done. 3008c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 3009c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3010c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3011c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3012c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadExternalArrayPointer( 3013c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LLoadExternalArrayPointer* instr) { 3014c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register to_reg = ToRegister(instr->result()); 3015c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register from_reg = ToRegister(instr->object()); 3016c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(to_reg, FieldMemOperand(from_reg, 3017c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ExternalArray::kExternalPointerOffset)); 3018c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3019c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3020c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3021c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 3022c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register arguments = ToRegister(instr->arguments()); 3023c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 302432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (instr->length()->IsConstantOperand() && 302532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->index()->IsConstantOperand()) { 302632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 302732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org int const_length = ToInteger32(LConstantOperand::cast(instr->length())); 302832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org int index = (const_length - const_index) + 1; 302932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ lw(result, MemOperand(arguments, index * kPointerSize)); 303032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org } else { 303132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Register length = ToRegister(instr->length()); 303232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Register index = ToRegister(instr->index()); 303332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org // There are two words between the frame pointer and the last argument. 303432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org // Subtracting from length accounts for one of them, add one more. 303532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ subu(length, length, index); 303632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ Addu(length, length, Operand(1)); 303732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ sll(length, length, kPointerSizeLog2); 303832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ Addu(at, arguments, Operand(length)); 303932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ lw(result, MemOperand(at, 0)); 304032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org } 3041c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3042c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3043c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3044e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 3045e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register external_pointer = ToRegister(instr->elements()); 3046e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register key = no_reg; 3047e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org ElementsKind elements_kind = instr->elements_kind(); 3048e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org bool key_is_constant = instr->key()->IsConstantOperand(); 3049e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org int constant_key = 0; 3050e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (key_is_constant) { 3051e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 3052e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (constant_key & 0xF0000000) { 3053594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kArrayIndexConstantValueTooBig); 3054471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 3055e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 3056e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org key = ToRegister(instr->key()); 3057129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org } 3058e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org int element_size_shift = ElementsKindToShiftSize(elements_kind); 305953ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) 3060e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org ? (element_size_shift - kSmiTagSize) : element_size_shift; 3061e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org int additional_offset = instr->additional_index() << element_size_shift; 3062c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3063e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3064e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3065e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org FPURegister result = ToDoubleRegister(instr->result()); 3066e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (key_is_constant) { 3067e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ Addu(scratch0(), external_pointer, constant_key << element_size_shift); 30687028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } else { 3069e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ sll(scratch0(), key, shift_size); 3070e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ Addu(scratch0(), scratch0(), external_pointer); 3071e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 3072e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3073e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ lwc1(result, MemOperand(scratch0(), additional_offset)); 3074e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cvt_d_s(result, result); 3075e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 3076e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ ldc1(result, MemOperand(scratch0(), additional_offset)); 3077e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 3078e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 3079e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register result = ToRegister(instr->result()); 3080e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org MemOperand mem_operand = PrepareKeyedOperand( 3081e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org key, external_pointer, key_is_constant, constant_key, 3082e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org element_size_shift, shift_size, 3083e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org instr->additional_index(), additional_offset); 3084e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org switch (elements_kind) { 3085e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case EXTERNAL_BYTE_ELEMENTS: 3086e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ lb(result, mem_operand); 3087e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org break; 3088e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case EXTERNAL_PIXEL_ELEMENTS: 3089e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3090e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ lbu(result, mem_operand); 3091e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org break; 3092e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case EXTERNAL_SHORT_ELEMENTS: 3093e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ lh(result, mem_operand); 3094e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org break; 3095e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3096e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ lhu(result, mem_operand); 3097e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org break; 3098e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case EXTERNAL_INT_ELEMENTS: 3099e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ lw(result, mem_operand); 3100e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org break; 3101e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3102e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ lw(result, mem_operand); 3103e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 3104e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org DeoptimizeIf(Ugreater_equal, instr->environment(), 3105e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org result, Operand(0x80000000)); 3106e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 3107e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org break; 3108e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case EXTERNAL_FLOAT_ELEMENTS: 3109e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case EXTERNAL_DOUBLE_ELEMENTS: 3110e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case FAST_DOUBLE_ELEMENTS: 3111e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case FAST_ELEMENTS: 3112e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case FAST_SMI_ELEMENTS: 3113e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case FAST_HOLEY_DOUBLE_ELEMENTS: 3114e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case FAST_HOLEY_ELEMENTS: 3115e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case FAST_HOLEY_SMI_ELEMENTS: 3116e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case DICTIONARY_ELEMENTS: 3117e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org case NON_STRICT_ARGUMENTS_ELEMENTS: 3118e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org UNREACHABLE(); 3119e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org break; 31207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 3121c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 3122c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3123c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3124c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3125e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { 3126c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register elements = ToRegister(instr->elements()); 3127c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org bool key_is_constant = instr->key()->IsConstantOperand(); 3128c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register key = no_reg; 3129c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoubleRegister result = ToDoubleRegister(instr->result()); 3130c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 3131c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3132129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); 313353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) 3134129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org ? (element_size_shift - kSmiTagSize) : element_size_shift; 3135c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int constant_key = 0; 3136c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (key_is_constant) { 3137c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 3138c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (constant_key & 0xF0000000) { 3139594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kArrayIndexConstantValueTooBig); 3140c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 3141c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 3142c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org key = ToRegister(instr->key()); 3143c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 3144c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 314559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + 314659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ((constant_key + instr->additional_index()) << element_size_shift); 314759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (!key_is_constant) { 3148c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sll(scratch, key, shift_size); 314959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ Addu(elements, elements, scratch); 315059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 3151e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Addu(elements, elements, Operand(base_offset)); 3152e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ ldc1(result, MemOperand(elements)); 3153e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 3154e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); 3155e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); 3156830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 3157c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3158c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3159c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3160e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3161e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register elements = ToRegister(instr->elements()); 3162e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register result = ToRegister(instr->result()); 3163e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register scratch = scratch0(); 3164e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register store_base = scratch; 3165e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org int offset = 0; 3166e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 3167e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (instr->key()->IsConstantOperand()) { 3168e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 3169e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + 3170e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org instr->additional_index()); 3171e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org store_base = elements; 3172e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 3173e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register key = EmitLoadRegister(instr->key(), scratch0()); 3174e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // Even though the HLoadKeyed instruction forces the input 3175e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // representation for the key to be an integer, the input gets replaced 3176e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // during bound check elimination with the index argument to the bounds 3177e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // check, which can be tagged, so that case must be handled here, too. 317853ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (instr->hydrogen()->key()->representation().IsSmi()) { 3179e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize); 3180e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ addu(scratch, elements, scratch); 3181e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 3182e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ sll(scratch, key, kPointerSizeLog2); 3183e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ addu(scratch, elements, scratch); 3184e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 3185e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org offset = FixedArray::OffsetOfElementAt(instr->additional_index()); 3186e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 3187e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ lw(result, FieldMemOperand(store_base, offset)); 3188e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 3189e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // Check for the hole value. 3190e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 3191e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { 3192e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ And(scratch, result, Operand(kSmiTagMask)); 3193e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 3194e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 3195e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 3196e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org DeoptimizeIf(eq, instr->environment(), result, Operand(scratch)); 3197e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 3198e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 3199e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 3200e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 3201e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 3202e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { 3203e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (instr->is_external()) { 3204e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org DoLoadKeyedExternalArray(instr); 3205e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else if (instr->hydrogen()->representation().IsDouble()) { 3206e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org DoLoadKeyedFixedDoubleArray(instr); 3207e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 3208e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org DoLoadKeyedFixedArray(instr); 3209e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 3210e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 3211e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 3212e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 3213129d398d682e6ca3910808c913212ce532f1e155danno@chromium.orgMemOperand LCodeGen::PrepareKeyedOperand(Register key, 3214129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org Register base, 3215129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org bool key_is_constant, 3216129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org int constant_key, 3217129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org int element_size, 3218129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org int shift_size, 3219129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org int additional_index, 3220129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org int additional_offset) { 3221129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org if (additional_index != 0 && !key_is_constant) { 3222129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org additional_index *= 1 << (element_size - shift_size); 3223129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ Addu(scratch0(), key, Operand(additional_index)); 3224129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org } 3225129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org 3226129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org if (key_is_constant) { 3227129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org return MemOperand(base, 3228129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org (constant_key << element_size) + additional_offset); 3229129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org } 3230129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org 3231129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org if (additional_index == 0) { 3232129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org if (shift_size >= 0) { 3233129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ sll(scratch0(), key, shift_size); 3234129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ Addu(scratch0(), base, scratch0()); 3235129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org return MemOperand(scratch0()); 3236129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org } else { 3237129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org ASSERT_EQ(-1, shift_size); 3238129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ srl(scratch0(), key, 1); 3239129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ Addu(scratch0(), base, scratch0()); 3240129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org return MemOperand(scratch0()); 3241129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org } 3242129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org } 3243129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org 3244129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org if (shift_size >= 0) { 3245129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ sll(scratch0(), scratch0(), shift_size); 3246129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ Addu(scratch0(), base, scratch0()); 3247129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org return MemOperand(scratch0()); 3248129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org } else { 3249129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org ASSERT_EQ(-1, shift_size); 3250129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ srl(scratch0(), scratch0(), 1); 3251129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ Addu(scratch0(), base, scratch0()); 3252129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org return MemOperand(scratch0()); 3253129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org } 3254129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org} 3255129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org 3256129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org 3257c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 3258c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->object()).is(a1)); 3259c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->key()).is(a0)); 3260c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3261c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 3262c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 3263c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3264c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3265c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3266c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 3267c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 3268c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register temp = scratch1(); 3269c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 3270c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 327128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (instr->hydrogen()->from_inlined()) { 327228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ Subu(result, sp, 2 * kPointerSize); 327328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } else { 327428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Check if the calling frame is an arguments adaptor frame. 327528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label done, adapted; 327628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ lw(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 327728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ lw(result, MemOperand(scratch, StandardFrameConstants::kContextOffset)); 327828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ Xor(temp, result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 3279c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 328028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Result is the frame pointer for the frame if not adapted and for the real 328128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // frame below the adaptor frame if adapted. 328228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ Movn(result, fp, temp); // Move only if temp is not equal to zero (ne). 328328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ Movz(result, scratch, temp); // Move only if temp is equal to zero (eq). 328428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 3285c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3286c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3287c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3288c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 3289c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register elem = ToRegister(instr->elements()); 3290c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 3291c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3292c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label done; 3293c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3294c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If no arguments adaptor frame the number of arguments is fixed. 3295c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Addu(result, zero_reg, Operand(scope()->num_parameters())); 3296c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done, eq, fp, Operand(elem)); 3297c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3298c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Arguments adaptor frame present. Get argument length from there. 3299c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(result, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 3300c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(result, 3301c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MemOperand(result, ArgumentsAdaptorFrameConstants::kLengthOffset)); 3302c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ SmiUntag(result); 3303c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3304c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Argument length is in result register. 3305c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 3306c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3307c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3308c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 33092c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.orgvoid LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 3310c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register receiver = ToRegister(instr->receiver()); 3311c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register function = ToRegister(instr->function()); 3312c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 3313c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3314c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If the receiver is null or undefined, we have to pass the global 3315c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // object as a receiver to normal functions. Values have to be 3316c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // passed unchanged to builtins and strict-mode functions. 3317c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label global_object, receiver_ok; 3318c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3319c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Do not transform the receiver to object for strict mode 3320c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // functions. 3321c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(scratch, 3322c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3323c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(scratch, 3324c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset)); 3325c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3326c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Do not transform the receiver to object for builtins. 3327c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int32_t strict_mode_function_mask = 3328c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize); 3329c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int32_t native_mask = 1 << (SharedFunctionInfo::kNative + kSmiTagSize); 3330c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(scratch, scratch, Operand(strict_mode_function_mask | native_mask)); 3331c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&receiver_ok, ne, scratch, Operand(zero_reg)); 3332c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3333c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Normal function. Replace undefined or null with global receiver. 3334c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(scratch, Heap::kNullValueRootIndex); 3335c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&global_object, eq, receiver, Operand(scratch)); 3336c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 3337c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&global_object, eq, receiver, Operand(scratch)); 3338c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3339c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Deoptimize if the receiver is not a JS object. 3340c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(scratch, receiver, Operand(kSmiTagMask)); 3341c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); 3342c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3343c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ GetObjectType(receiver, scratch, scratch); 3344c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(lt, instr->environment(), 3345c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch, Operand(FIRST_SPEC_OBJECT_TYPE)); 3346c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&receiver_ok); 3347c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3348c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&global_object); 3349c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(receiver, GlobalObjectOperand()); 3350c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(receiver, 3351c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FieldMemOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); 3352c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&receiver_ok); 33532c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org} 33542c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 3355e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 33562c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.orgvoid LCodeGen::DoApplyArguments(LApplyArguments* instr) { 33572c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org Register receiver = ToRegister(instr->receiver()); 33582c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org Register function = ToRegister(instr->function()); 33592c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org Register length = ToRegister(instr->length()); 33602c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org Register elements = ToRegister(instr->elements()); 33612c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org Register scratch = scratch0(); 33622c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org ASSERT(receiver.is(a0)); // Used for parameter count. 33632c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org ASSERT(function.is(a1)); // Required by InvokeFunction. 33642c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 3365c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3366c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Copy the arguments to this function possibly from the 3367c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // adaptor frame below it. 3368c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const uint32_t kArgumentsLimit = 1 * KB; 3369c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(hi, instr->environment(), length, Operand(kArgumentsLimit)); 3370c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3371c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Push the receiver and use the register to keep the original 3372c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // number of arguments. 3373c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(receiver); 3374c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Move(receiver, length); 3375c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // The arguments are at a one pointer size offset from elements. 3376c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Addu(elements, elements, Operand(1 * kPointerSize)); 3377c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3378c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Loop through the arguments pushing them onto the execution 3379c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // stack. 3380c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label invoke, loop; 3381c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // length is a small non-negative integer, due to the test above. 3382c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(USE_DELAY_SLOT, &invoke, eq, length, Operand(zero_reg)); 3383c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sll(scratch, length, 2); 3384c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&loop); 3385c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Addu(scratch, elements, scratch); 3386c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(scratch, MemOperand(scratch)); 3387c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(scratch); 3388c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Subu(length, length, Operand(1)); 3389c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(USE_DELAY_SLOT, &loop, ne, length, Operand(zero_reg)); 3390c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sll(scratch, length, 2); 3391c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3392c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&invoke); 3393e4bfb26083376408caf54512da4924003f090a61danno@chromium.org ASSERT(instr->HasPointerMap()); 3394c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LPointerMap* pointers = instr->pointer_map(); 3395c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RecordPosition(pointers->position()); 33960ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry SafepointGenerator safepoint_generator( 33970ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry this, pointers, Safepoint::kLazyDeopt); 3398c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // The number of arguments is stored in receiver which is a0, as expected 3399c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // by InvokeFunction. 340005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org ParameterCount actual(receiver); 3401c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ InvokeFunction(function, actual, CALL_FUNCTION, 3402c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org safepoint_generator, CALL_AS_METHOD); 3403c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3404c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3405c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3406c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3407c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoPushArgument(LPushArgument* instr) { 3408c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* argument = instr->value(); 3409c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { 3410594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kDoPushArgumentNotImplementedForDoubleType); 3411c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 3412c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register argument_reg = EmitLoadRegister(argument, at); 3413c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(argument_reg); 3414c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 3415c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3416c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3417c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 341828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.orgvoid LCodeGen::DoDrop(LDrop* instr) { 341928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ Drop(instr->count()); 342028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org} 342128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 342228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 3423c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoThisFunction(LThisFunction* instr) { 3424c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 34255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org __ lw(result, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 3426c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3427c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3428c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3429c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoContext(LContext* instr) { 34307c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // If there is a non-return use, the context must be moved to a register. 3431c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 34327c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org for (HUseIterator it(instr->hydrogen()->uses()); !it.Done(); it.Advance()) { 34337c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (!it.value()->IsReturn()) { 34347c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ mov(result, cp); 34357c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org return; 34367c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 34377c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 3438c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3439c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3440c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3441c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoOuterContext(LOuterContext* instr) { 3442c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register context = ToRegister(instr->context()); 3443c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 3444c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(result, 3445c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MemOperand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); 3446c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3447c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3448c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3449f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgvoid LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 3450f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org __ LoadHeapObject(scratch0(), instr->hydrogen()->pairs()); 3451f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org __ li(scratch1(), Operand(Smi::FromInt(instr->hydrogen()->flags()))); 3452f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // The context is the first argument. 3453f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org __ Push(cp, scratch0(), scratch1()); 3454f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org CallRuntime(Runtime::kDeclareGlobals, 3, instr); 3455f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 3456f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 3457f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 3458c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoGlobalObject(LGlobalObject* instr) { 3459c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 346046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ lw(result, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); 3461c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3462c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3463c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3464c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { 3465c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register global = ToRegister(instr->global_object()); 3466c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 3467c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); 3468c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3469c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3471c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::CallKnownFunction(Handle<JSFunction> function, 347232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org int formal_parameter_count, 3473c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int arity, 3474c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LInstruction* instr, 3475fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org CallKind call_kind, 3476fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org A1State a1_state) { 347732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org bool dont_adapt_arguments = 347832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 347932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org bool can_invoke_directly = 348032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org dont_adapt_arguments || formal_parameter_count == arity; 3481c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3482c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LPointerMap* pointers = instr->pointer_map(); 3483c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RecordPosition(pointers->position()); 3484c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 348505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org if (can_invoke_directly) { 3486fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org if (a1_state == A1_UNINITIALIZED) { 3487fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org __ LoadHeapObject(a1, function); 3488fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org } 3489fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org 3490b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org // Change context. 3491b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 3492c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 349305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org // Set r0 to arguments count if adaption is not needed. Assumes that r0 349405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org // is available to write to at this point. 349532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (dont_adapt_arguments) { 349605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org __ li(a0, Operand(arity)); 349705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org } 349805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org 349905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org // Invoke function. 350005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org __ SetCallKind(t1, call_kind); 350105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); 350205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org __ Call(at); 350305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org 350405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org // Set up deoptimization. 350505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 350605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org } else { 350705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 350805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org ParameterCount count(arity); 350932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ParameterCount expected(formal_parameter_count); 351032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ InvokeFunction( 351132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org function, expected, count, CALL_FUNCTION, generator, call_kind); 351205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org } 3513c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3514c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Restore context. 3515c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3516c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3517c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3518c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3519c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 3520c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 3521c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov(a0, v0); 352232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CallKnownFunction(instr->hydrogen()->function(), 352332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->hydrogen()->formal_parameter_count(), 3524fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr->arity(), 3525fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr, 3526fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org CALL_AS_METHOD, 3527fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org A1_UNINITIALIZED); 3528c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3529c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3530c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3531e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 3532c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 3533c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 3534c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 3535c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3536c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Deoptimize if not a heap number. 3537c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 3538c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 3539c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); 3540c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3541c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label done; 3542c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register exponent = scratch0(); 3543c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch = no_reg; 3544c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 3545c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Check the sign of the argument. If the argument is positive, just 3546c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // return it. 3547c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Move(result, input); 3548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(at, exponent, Operand(HeapNumber::kSignMask)); 3549c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done, eq, at, Operand(zero_reg)); 3550c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3551c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Input is negative. Reverse its sign. 3552c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Preserve the value of all registers. 3553c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org { 3554c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 3555c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3556c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Registers were saved at the safepoint, so we can use 3557c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // many scratch registers. 3558c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register tmp1 = input.is(a1) ? a0 : a1; 3559c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register tmp2 = input.is(a2) ? a0 : a2; 3560c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register tmp3 = input.is(a3) ? a0 : a3; 3561c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register tmp4 = input.is(t0) ? a0 : t0; 3562c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3563c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // exponent: floating point exponent value. 3564c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3565c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label allocated, slow; 3566c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(tmp4, Heap::kHeapNumberMapRootIndex); 3567c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ AllocateHeapNumber(tmp1, tmp2, tmp3, tmp4, &slow); 3568c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&allocated); 3569c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3570c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Slow case: Call the runtime system to do the number allocation. 3571c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&slow); 3572c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3573c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 3574c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Set the pointer to the new heap number in tmp. 3575c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!tmp1.is(v0)) 3576c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov(tmp1, v0); 3577c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Restore input_reg after call to runtime. 3578c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadFromSafepointRegisterSlot(input, input); 3579c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 3580c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3581c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&allocated); 3582c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // exponent: floating point exponent value. 3583c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // tmp1: allocated heap number. 3584c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(exponent, exponent, Operand(~HeapNumber::kSignMask)); 3585c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset)); 3586c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); 3587c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); 3588c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3589c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ StoreToSafepointRegisterSlot(tmp1, result); 3590c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 3591c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3592c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 3593c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3594c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3595c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3596e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { 3597c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 3598c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 3599c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 3600c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label done; 3601c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg)); 3602c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov(result, input); 36031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ subu(result, zero_reg, input); 36042efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Overflow if result is still negative, i.e. 0x80000000. 3605c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); 3606c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 3607c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3608c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3609c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3610e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathAbs(LMathAbs* instr) { 3611c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Class for deferred case. 3612c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3613c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org public: 3614e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) 3615c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : LDeferredCode(codegen), instr_(instr) { } 3616c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual void Generate() { 3617c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3618c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 3619c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual LInstruction* instr() { return instr_; } 3620c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org private: 3621e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org LMathAbs* instr_; 3622c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org }; 3623c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3624c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Representation r = instr->hydrogen()->value()->representation(); 3625c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (r.IsDouble()) { 3626c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org FPURegister input = ToDoubleRegister(instr->value()); 3627c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FPURegister result = ToDoubleRegister(instr->result()); 3628c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ abs_d(result, input); 3629594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else if (r.IsSmiOrInteger32()) { 3630c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EmitIntegerMathAbs(instr); 3631c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 3632c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Representation is tagged. 3633c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeferredMathAbsTaggedHeapNumber* deferred = 36347028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); 3635c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 3636c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Smi check. 3637c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfNotSmi(input, deferred->entry()); 3638c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If smi, handle it directly. 3639c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EmitIntegerMathAbs(instr); 3640c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(deferred->exit()); 3641c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 3642c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3643c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3644c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3645e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathFloor(LMathFloor* instr) { 3646c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org DoubleRegister input = ToDoubleRegister(instr->value()); 3647c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 3648c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch1 = scratch0(); 3649c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register except_flag = ToRegister(instr->temp()); 3650c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3651c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ EmitFPUTruncate(kRoundToMinusInf, 365283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org result, 3653c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org input, 3654c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch1, 365583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org double_scratch0(), 3656c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org except_flag); 3657c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3658c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Deopt if the operation did not succeed. 3659c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 3660c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3661c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3662c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Test for -0. 3663c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label done; 3664c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done, ne, result, Operand(zero_reg)); 3665c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mfc1(scratch1, input.high()); 3666c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 3667c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 3668c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 3669c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 3670c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3671c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3672c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3673e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathRound(LMathRound* instr) { 3674c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org DoubleRegister input = ToDoubleRegister(instr->value()); 3675c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 367683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); 3677c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 3678c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label done, check_sign_on_zero; 3679c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3680c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Extract exponent bits. 3681c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mfc1(result, input.high()); 3682c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Ext(scratch, 3683c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org result, 3684c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org HeapNumber::kExponentShift, 3685c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org HeapNumber::kExponentBits); 3686c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3687c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If the number is in ]-0.5, +0.5[, the result is +/- 0. 3688c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label skip1; 3689c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&skip1, gt, scratch, Operand(HeapNumber::kExponentBias - 2)); 3690c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov(result, zero_reg); 3691c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3692c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&check_sign_on_zero); 3693c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 3694c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done); 3695c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 3696c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&skip1); 3697c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3698c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // The following conversion will not work with numbers 3699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // outside of ]-2^32, 2^32[. 3700c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ge, instr->environment(), scratch, 3701c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Operand(HeapNumber::kExponentBias + 32)); 3702c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3703c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Save the original sign for later comparison. 3704c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(scratch, result, Operand(HeapNumber::kSignMask)); 3705c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3706c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Move(double_scratch0(), 0.5); 370764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ add_d(double_scratch0(), input, double_scratch0()); 3708c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3709c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Check sign of the result: if the sign changed, the input 3710c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // value was in ]0.5, 0[ and the result should be -0. 371164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ mfc1(result, double_scratch0().high()); 3712c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Xor(result, result, Operand(scratch)); 3713c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3714c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // ARM uses 'mi' here, which is 'lt' 3715c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(lt, instr->environment(), result, 3716c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Operand(zero_reg)); 3717c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 3718c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label skip2; 3719c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // ARM uses 'mi' here, which is 'lt' 3720c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Negating it results in 'ge' 3721c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&skip2, ge, result, Operand(zero_reg)); 3722c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov(result, zero_reg); 3723c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done); 3724c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&skip2); 3725c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 3726c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3727c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register except_flag = scratch; 3728c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ EmitFPUTruncate(kRoundToMinusInf, 3729c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org result, 373083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org double_scratch0(), 373183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org at, 373283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org double_scratch1, 3733c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org except_flag); 3734c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3735c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 3736c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3737c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3738c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Test for -0. 3739c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done, ne, result, Operand(zero_reg)); 3740c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&check_sign_on_zero); 3741c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mfc1(scratch, input.high()); 3742c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); 3743c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 3744c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 3745c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 3746c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3747c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3748c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3749e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathSqrt(LMathSqrt* instr) { 3750c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org DoubleRegister input = ToDoubleRegister(instr->value()); 3751c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoubleRegister result = ToDoubleRegister(instr->result()); 3752c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sqrt_d(result, input); 3753c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3754c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3755c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3756e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { 3757c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org DoubleRegister input = ToDoubleRegister(instr->value()); 3758c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoubleRegister result = ToDoubleRegister(instr->result()); 3759c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org DoubleRegister temp = ToDoubleRegister(instr->temp()); 376064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 376164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(!input.is(result)); 376264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 376364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Note that according to ECMA-262 15.8.2.13: 376464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Math.pow(-Infinity, 0.5) == Infinity 376564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Math.sqrt(-Infinity) == NaN 376664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label done; 376764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Move(temp, -V8_INFINITY); 376864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, temp, input); 376964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Set up Infinity in the delay slot. 377064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // result is overwritten if the branch is not taken. 377164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ neg_d(result, temp); 3772c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3773c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Add +0 to convert -0 to +0. 377464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ add_d(result, input, kDoubleRegZero); 3775c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sqrt_d(result, result); 377664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&done); 3777c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3778c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3779c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3780c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoPower(LPower* instr) { 3781c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Representation exponent_type = instr->hydrogen()->right()->representation(); 378264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Having marked this as a call, we can use any registers. 378364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Just make sure that the input/output registers are the expected ones. 3784c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(!instr->right()->IsDoubleRegister() || 3785c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ToDoubleRegister(instr->right()).is(f4)); 3786c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(!instr->right()->IsRegister() || 3787c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ToRegister(instr->right()).is(a2)); 3788c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(ToDoubleRegister(instr->left()).is(f2)); 378964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(ToDoubleRegister(instr->result()).is(f0)); 379064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 379153ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (exponent_type.IsSmi()) { 379253ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org MathPowStub stub(MathPowStub::TAGGED); 379353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org __ CallStub(&stub); 379453ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org } else if (exponent_type.IsTagged()) { 379564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label no_deopt; 379664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ JumpIfSmi(a2, &no_deopt); 379764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ lw(t3, FieldMemOperand(a2, HeapObject::kMapOffset)); 379864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org DeoptimizeIf(ne, instr->environment(), t3, Operand(at)); 379964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&no_deopt); 380064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MathPowStub stub(MathPowStub::TAGGED); 380164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CallStub(&stub); 3802c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (exponent_type.IsInteger32()) { 380364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MathPowStub stub(MathPowStub::INTEGER); 380464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CallStub(&stub); 3805c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 380664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(exponent_type.IsDouble()); 380764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MathPowStub stub(MathPowStub::DOUBLE); 380864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CallStub(&stub); 3809c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 3810c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3811c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3812c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3813f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid LCodeGen::DoRandom(LRandom* instr) { 3814bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com class DeferredDoRandom: public LDeferredCode { 3815bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com public: 3816bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com DeferredDoRandom(LCodeGen* codegen, LRandom* instr) 3817bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com : LDeferredCode(codegen), instr_(instr) { } 3818bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com virtual void Generate() { codegen()->DoDeferredRandom(instr_); } 3819bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com virtual LInstruction* instr() { return instr_; } 3820bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com private: 3821bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com LRandom* instr_; 3822bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com }; 3823bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 38247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); 3825f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Having marked this instruction as a call we can use any 3826f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // registers. 3827f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ASSERT(ToDoubleRegister(instr->result()).is(f0)); 3828c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(ToRegister(instr->global_object()).is(a0)); 3829f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 3830bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com static const int kSeedSize = sizeof(uint32_t); 3831bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com STATIC_ASSERT(kPointerSize == kSeedSize); 3832bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 383346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ lw(a0, FieldMemOperand(a0, GlobalObject::kNativeContextOffset)); 3834bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com static const int kRandomSeedOffset = 3835bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize; 3836bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ lw(a2, FieldMemOperand(a0, kRandomSeedOffset)); 383746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // a2: FixedArray of the native context's random seeds 3838bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 3839bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Load state[0]. 3840bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ lw(a1, FieldMemOperand(a2, ByteArray::kHeaderSize)); 3841bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ Branch(deferred->entry(), eq, a1, Operand(zero_reg)); 3842bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Load state[1]. 3843bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ lw(a0, FieldMemOperand(a2, ByteArray::kHeaderSize + kSeedSize)); 3844bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // a1: state[0]. 3845bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // a0: state[1]. 3846bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 3847bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16) 3848bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ And(a3, a1, Operand(0xFFFF)); 3849bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ li(t0, Operand(18273)); 3850212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org __ Mul(a3, a3, t0); 3851bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ srl(a1, a1, 16); 3852bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ Addu(a1, a3, a1); 3853bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Save state[0]. 3854bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ sw(a1, FieldMemOperand(a2, ByteArray::kHeaderSize)); 3855bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 3856bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16) 3857bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ And(a3, a0, Operand(0xFFFF)); 3858bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ li(t0, Operand(36969)); 3859212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org __ Mul(a3, a3, t0); 3860bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ srl(a0, a0, 16), 3861bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ Addu(a0, a3, a0); 3862bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Save state[1]. 3863bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ sw(a0, FieldMemOperand(a2, ByteArray::kHeaderSize + kSeedSize)); 3864bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 3865bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF) 3866bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ And(a0, a0, Operand(0x3FFFF)); 3867bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ sll(a1, a1, 14); 3868bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ Addu(v0, a0, a1); 3869bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 3870bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ bind(deferred->exit()); 3871f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 3872f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // 0x41300000 is the top half of 1.0 x 2^20 as a double. 3873f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com __ li(a2, Operand(0x41300000)); 3874f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Move 0x41300000xxxxxxxx (x = random bits in v0) to FPU. 3875f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com __ Move(f12, v0, a2); 3876f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Move 0x4130000000000000 to FPU. 3877f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com __ Move(f14, zero_reg, a2); 3878f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Subtract to get the result. 3879f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com __ sub_d(f0, f12, f14); 3880f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 3881f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 3882e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 3883bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.comvoid LCodeGen::DoDeferredRandom(LRandom* instr) { 3884bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ PrepareCallCFunction(1, scratch0()); 3885bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); 3886bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Return value is in v0. 3887bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com} 3888bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 3889f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 389083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgvoid LCodeGen::DoMathExp(LMathExp* instr) { 389183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister input = ToDoubleRegister(instr->value()); 389283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister result = ToDoubleRegister(instr->result()); 389383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); 389483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister double_scratch2 = double_scratch0(); 389583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org Register temp1 = ToRegister(instr->temp1()); 389683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org Register temp2 = ToRegister(instr->temp2()); 389783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 389883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org MathExpGenerator::EmitMathExp( 389983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org masm(), input, result, double_scratch1, double_scratch2, 390083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org temp1, temp2, scratch0()); 390183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org} 390283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 390383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 3904e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathLog(LMathLog* instr) { 3905c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToDoubleRegister(instr->result()).is(f4)); 3906c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org TranscendentalCacheStub stub(TranscendentalCache::LOG, 3907c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org TranscendentalCacheStub::UNTAGGED); 39088432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 3909c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3910c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3911c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3912e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathTan(LMathTan* instr) { 3913ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org ASSERT(ToDoubleRegister(instr->result()).is(f4)); 3914ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org TranscendentalCacheStub stub(TranscendentalCache::TAN, 3915ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org TranscendentalCacheStub::UNTAGGED); 39168432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 3917ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org} 3918ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org 3919ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org 3920e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathCos(LMathCos* instr) { 3921c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToDoubleRegister(instr->result()).is(f4)); 3922c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org TranscendentalCacheStub stub(TranscendentalCache::COS, 3923c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org TranscendentalCacheStub::UNTAGGED); 39248432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 3925c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3926c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3927c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3928e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathSin(LMathSin* instr) { 3929c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToDoubleRegister(instr->result()).is(f4)); 3930c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org TranscendentalCacheStub stub(TranscendentalCache::SIN, 3931c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org TranscendentalCacheStub::UNTAGGED); 39328432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 3933c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3934c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3935c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3936c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 3937c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->function()).is(a1)); 3938c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(instr->HasPointerMap()); 3939fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org 394032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 394132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (known_function.is_null()) { 3942fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org LPointerMap* pointers = instr->pointer_map(); 3943fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org RecordPosition(pointers->position()); 3944fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3945fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org ParameterCount count(instr->arity()); 3946fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); 3947fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3948fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org } else { 394932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CallKnownFunction(known_function, 395032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->hydrogen()->formal_parameter_count(), 3951fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr->arity(), 3952fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr, 3953fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org CALL_AS_METHOD, 3954fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org A1_CONTAINS_TARGET); 3955fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org } 3956c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3957c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3958c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3959c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallKeyed(LCallKeyed* instr) { 3960c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 3961c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3962c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int arity = instr->arity(); 3963c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Code> ic = 3964c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org isolate()->stub_cache()->ComputeKeyedCallInitialize(arity); 3965c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 3966c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3967c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3968c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3969c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3970c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallNamed(LCallNamed* instr) { 3971c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 3972c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int arity = instr->arity(); 3974c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RelocInfo::Mode mode = RelocInfo::CODE_TARGET; 3975c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Code> ic = 3976c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org isolate()->stub_cache()->ComputeCallInitialize(arity, mode); 3977c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(a2, Operand(instr->name())); 3978c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallCode(ic, mode, instr); 3979c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Restore context register. 3980c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3981c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3982c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3983c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallFunction(LCallFunction* instr) { 3985c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org ASSERT(ToRegister(instr->function()).is(a1)); 3986c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 3987c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3988c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int arity = instr->arity(); 3989c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); 39908432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 3991c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3992c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 3993c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3994c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3995c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallGlobal(LCallGlobal* instr) { 3996c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 3997c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 3998c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int arity = instr->arity(); 3999c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; 4000c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Code> ic = 4001c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org isolate()->stub_cache()->ComputeCallInitialize(arity, mode); 4002c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(a2, Operand(instr->name())); 4003c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallCode(ic, mode, instr); 4004c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 4005c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4006c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4007c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4008c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 4009c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 401032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CallKnownFunction(instr->hydrogen()->target(), 401132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->hydrogen()->formal_parameter_count(), 4012fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr->arity(), 4013fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr, 4014fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org CALL_AS_FUNCTION, 4015fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org A1_UNINITIALIZED); 4016c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4017c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4018c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4019c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallNew(LCallNew* instr) { 4020c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(ToRegister(instr->constructor()).is(a1)); 4021c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 4022c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4023c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(a0, Operand(instr->arity())); 40241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // No cell in a2 for construct type feedback in optimized code 40251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<Object> undefined_value(isolate()->factory()->undefined_value()); 40261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ li(a2, Operand(undefined_value)); 4027750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 40288432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4029c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4030c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4031c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4032750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid LCodeGen::DoCallNewArray(LCallNewArray* instr) { 4033750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org ASSERT(ToRegister(instr->constructor()).is(a1)); 4034750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 4035750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 4036750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org __ li(a0, Operand(instr->arity())); 4037750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org __ li(a2, Operand(instr->hydrogen()->property_cell())); 403857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ElementsKind kind = instr->hydrogen()->elements_kind(); 403907237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com AllocationSiteOverrideMode override_mode = 4040bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) 404107237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com ? DISABLE_ALLOCATION_SITES 404207237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com : DONT_OVERRIDE; 404307237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com ContextCheckMode context_mode = CONTEXT_CHECK_NOT_REQUIRED; 4044d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 4045ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if (instr->arity() == 0) { 404607237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com ArrayNoArgumentConstructorStub stub(kind, context_mode, override_mode); 4047ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4048ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else if (instr->arity() == 1) { 4049f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org Label done; 4050f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org if (IsFastPackedElementsKind(kind)) { 4051f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org Label packed_case; 4052f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org // We might need a change here, 4053f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org // look at the first argument. 4054f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ lw(t1, MemOperand(sp, 0)); 4055f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ Branch(&packed_case, eq, t1, Operand(zero_reg)); 4056f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org 4057f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org ElementsKind holey_kind = GetHoleyElementsKind(kind); 405807237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com ArraySingleArgumentConstructorStub stub(holey_kind, context_mode, 405907237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com override_mode); 4060f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4061f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ jmp(&done); 4062f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ bind(&packed_case); 4063f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org } 4064f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org 406507237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com ArraySingleArgumentConstructorStub stub(kind, context_mode, override_mode); 4066ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4067f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ bind(&done); 4068ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else { 406907237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode); 4070ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4071ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 4072750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 4073750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 4074750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 4075c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallRuntime(LCallRuntime* instr) { 4076c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallRuntime(instr->function(), instr->arity(), instr); 4077c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4078c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4079c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 40804c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.orgvoid LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { 40814c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org Register result = ToRegister(instr->result()); 40824c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org Register base = ToRegister(instr->base_object()); 40834c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ Addu(result, base, Operand(instr->offset())); 40844c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org} 40854c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org 40864c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org 4087c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 4088f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Representation representation = instr->representation(); 4089f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 4090c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register object = ToRegister(instr->object()); 4091c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 409253ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org HObjectAccess access = instr->hydrogen()->access(); 409353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org int offset = access.offset(); 4094c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4095d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (access.IsExternalMemory()) { 4096d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register value = ToRegister(instr->value()); 4097d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ sw(value, MemOperand(object, offset)); 4098d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return; 4099d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 4100d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 410157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Map> transition = instr->transition(); 410257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 4103a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 4104906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org Register value = ToRegister(instr->value()); 4105906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (!instr->hydrogen()->value()->type().IsHeapObject()) { 4106906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org __ And(scratch, value, Operand(kSmiTagMask)); 4107906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); 4108906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 410957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else if (FLAG_track_double_fields && representation.IsDouble()) { 411057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT(transition.is_null()); 411153ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org ASSERT(access.IsInobject()); 411257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 411357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org DoubleRegister value = ToDoubleRegister(instr->value()); 411457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ sdc1(value, FieldMemOperand(object, offset)); 411557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org return; 4116f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 4117f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 4118f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!transition.is_null()) { 4119f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ li(scratch, Operand(transition)); 4120c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); 412137141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org if (instr->hydrogen()->NeedsWriteBarrierForMap()) { 4122c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register temp = ToRegister(instr->temp()); 412337141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org // Update the write barrier for the map field. 412437141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org __ RecordWriteField(object, 412537141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org HeapObject::kMapOffset, 412637141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org scratch, 412737141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org temp, 4128c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org GetRAState(), 412937141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org kSaveFPRegs, 413037141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org OMIT_REMEMBERED_SET, 413137141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org OMIT_SMI_CHECK); 413237141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org } 4133c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4134c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4135c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Do the store. 413657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Register value = ToRegister(instr->value()); 413757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT(!object.is(value)); 4138c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org SmiCheck check_needed = 41391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->hydrogen()->value()->IsHeapObject() 41401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 414153ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (access.IsInobject()) { 4142c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(value, FieldMemOperand(object, offset)); 4143c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->NeedsWriteBarrier()) { 4144c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Update the write barrier for the object for in-object properties. 4145c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ RecordWriteField(object, 4146c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org offset, 4147c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org value, 4148c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch, 4149c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org GetRAState(), 4150c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org kSaveFPRegs, 4151c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EMIT_REMEMBERED_SET, 4152c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org check_needed); 4153c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4154c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 4155c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset)); 4156c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(value, FieldMemOperand(scratch, offset)); 4157c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->NeedsWriteBarrier()) { 4158c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Update the write barrier for the properties array. 4159c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // object is used as a scratch register. 4160c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ RecordWriteField(scratch, 4161c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org offset, 4162c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org value, 4163c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org object, 4164c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org GetRAState(), 4165c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org kSaveFPRegs, 4166c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EMIT_REMEMBERED_SET, 4167c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org check_needed); 4168c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4169c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4170c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4171c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4172c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4173c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { 4174c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->object()).is(a1)); 4175c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->value()).is(a0)); 4176c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4177c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Name is always in a2. 4178c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(a2, Operand(instr->name())); 41791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 4180c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ? isolate()->builtins()->StoreIC_Initialize_Strict() 4181c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : isolate()->builtins()->StoreIC_Initialize(); 4182c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 4183c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4184c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4185c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4186c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.comvoid LCodeGen::ApplyCheckIf(Condition condition, 4187fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org LBoundsCheck* check, 4188fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Register src1, 4189fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org const Operand& src2) { 4190fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (FLAG_debug_code && check->hydrogen()->skip_check()) { 4191fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Label done; 4192c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com __ Branch(&done, NegateCondition(condition), src1, src2); 4193fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ stop("eliminated bounds check failed"); 4194fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ bind(&done); 4195fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 4196c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com DeoptimizeIf(condition, check->environment(), src1, src2); 4197fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 4198fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org} 4199fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 4200fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 4201c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 42027c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (instr->hydrogen()->skip_check()) return; 42037c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 4204fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Condition condition = instr->hydrogen()->allow_equality() ? hi : hs; 4205471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (instr->index()->IsConstantOperand()) { 4206471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org int constant_index = 4207471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ToInteger32(LConstantOperand::cast(instr->index())); 420853ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (instr->hydrogen()->length()->representation().IsSmi()) { 4209471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ li(at, Operand(Smi::FromInt(constant_index))); 4210471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 4211471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ li(at, Operand(constant_index)); 4212471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 4213fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ApplyCheckIf(condition, 4214fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org instr, 4215471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org at, 4216471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Operand(ToRegister(instr->length()))); 4217471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 4218fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ApplyCheckIf(condition, 4219fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org instr, 4220471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ToRegister(instr->index()), 4221471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Operand(ToRegister(instr->length()))); 4222471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 4223c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4224c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4225c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4226e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4227e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register external_pointer = ToRegister(instr->elements()); 4228c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register key = no_reg; 4229c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ElementsKind elements_kind = instr->elements_kind(); 4230c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org bool key_is_constant = instr->key()->IsConstantOperand(); 4231c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int constant_key = 0; 4232c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (key_is_constant) { 4233c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 4234c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (constant_key & 0xF0000000) { 4235594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kArrayIndexConstantValueTooBig); 4236c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4237c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 4238c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org key = ToRegister(instr->key()); 4239c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4240129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org int element_size_shift = ElementsKindToShiftSize(elements_kind); 424153ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) 4242129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org ? (element_size_shift - kSmiTagSize) : element_size_shift; 4243129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org int additional_offset = instr->additional_index() << element_size_shift; 4244c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4245c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 4246c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 4247c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FPURegister value(ToDoubleRegister(instr->value())); 4248c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (key_is_constant) { 4249129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ Addu(scratch0(), external_pointer, constant_key << 4250129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org element_size_shift); 4251c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 4252c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sll(scratch0(), key, shift_size); 4253c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Addu(scratch0(), scratch0(), external_pointer); 4254c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4255c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4256c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 4257c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ cvt_s_d(double_scratch0(), value); 4258777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ swc1(double_scratch0(), MemOperand(scratch0(), additional_offset)); 4259c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 4260777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ sdc1(value, MemOperand(scratch0(), additional_offset)); 4261c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4262c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 4263c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register value(ToRegister(instr->value())); 4264129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org MemOperand mem_operand = PrepareKeyedOperand( 4265129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org key, external_pointer, key_is_constant, constant_key, 4266129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org element_size_shift, shift_size, 4267129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org instr->additional_index(), additional_offset); 4268c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org switch (elements_kind) { 4269c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case EXTERNAL_PIXEL_ELEMENTS: 4270c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case EXTERNAL_BYTE_ELEMENTS: 4271c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4272c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sb(value, mem_operand); 4273c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 4274c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case EXTERNAL_SHORT_ELEMENTS: 4275c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 4276c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sh(value, mem_operand); 4277c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 4278c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case EXTERNAL_INT_ELEMENTS: 4279c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case EXTERNAL_UNSIGNED_INT_ELEMENTS: 4280c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(value, mem_operand); 4281c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 4282c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case EXTERNAL_FLOAT_ELEMENTS: 4283c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case EXTERNAL_DOUBLE_ELEMENTS: 4284c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case FAST_DOUBLE_ELEMENTS: 4285c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case FAST_ELEMENTS: 4286830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org case FAST_SMI_ELEMENTS: 4287830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org case FAST_HOLEY_DOUBLE_ELEMENTS: 4288830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org case FAST_HOLEY_ELEMENTS: 4289830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org case FAST_HOLEY_SMI_ELEMENTS: 4290c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case DICTIONARY_ELEMENTS: 4291c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org case NON_STRICT_ARGUMENTS_ELEMENTS: 4292c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org UNREACHABLE(); 4293c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 4294c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4295c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4296c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4297c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4298e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4299e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { 4300e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org DoubleRegister value = ToDoubleRegister(instr->value()); 4301e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register elements = ToRegister(instr->elements()); 4302e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register key = no_reg; 4303e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register scratch = scratch0(); 4304e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org bool key_is_constant = instr->key()->IsConstantOperand(); 4305e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org int constant_key = 0; 4306e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Label not_nan; 4307e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4308e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // Calculate the effective address of the slot in the array to store the 4309e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // double value. 4310e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (key_is_constant) { 4311e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 4312e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (constant_key & 0xF0000000) { 4313594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kArrayIndexConstantValueTooBig); 4314e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 4315e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 4316e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org key = ToRegister(instr->key()); 4317e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 4318e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); 431953ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) 4320e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org ? (element_size_shift - kSmiTagSize) : element_size_shift; 4321e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (key_is_constant) { 4322e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ Addu(scratch, elements, Operand((constant_key << element_size_shift) + 4323e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 4324e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 4325e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ sll(scratch, key, shift_size); 4326e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ Addu(scratch, elements, Operand(scratch)); 4327e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ Addu(scratch, scratch, 4328e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 4329e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 4330e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4331e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (instr->NeedsCanonicalization()) { 4332e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Label is_nan; 4333e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // Check for NaN. All NaNs must be canonicalized. 4334e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ BranchF(NULL, &is_nan, eq, value, value); 4335e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ Branch(¬_nan); 4336e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4337e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // Only load canonical NaN if the comparison above set the overflow. 4338e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ bind(&is_nan); 4339e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double()); 4340e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 4341e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4342e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ bind(¬_nan); 4343e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ sdc1(value, MemOperand(scratch, instr->additional_index() << 4344e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org element_size_shift)); 4345e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 4346e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4347e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4348e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 4349e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register value = ToRegister(instr->value()); 4350e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register elements = ToRegister(instr->elements()); 4351e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) 4352e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org : no_reg; 4353e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register scratch = scratch0(); 4354e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Register store_base = scratch; 4355e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org int offset = 0; 4356e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4357e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // Do the store. 4358e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (instr->key()->IsConstantOperand()) { 4359e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 4360e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 4361e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + 4362e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org instr->additional_index()); 4363e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org store_base = elements; 4364e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 4365e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // Even though the HLoadKeyed instruction forces the input 4366e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // representation for the key to be an integer, the input gets replaced 4367e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // during bound check elimination with the index argument to the bounds 4368e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // check, which can be tagged, so that case must be handled here, too. 436953ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (instr->hydrogen()->key()->representation().IsSmi()) { 4370e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize); 4371e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ addu(scratch, elements, scratch); 4372e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 4373e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ sll(scratch, key, kPointerSizeLog2); 4374e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ addu(scratch, elements, scratch); 4375e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 4376e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org offset = FixedArray::OffsetOfElementAt(instr->additional_index()); 4377e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 4378e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ sw(value, FieldMemOperand(store_base, offset)); 4379e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4380e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (instr->hydrogen()->NeedsWriteBarrier()) { 4381e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org SmiCheck check_needed = 43821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->hydrogen()->value()->IsHeapObject() 43831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4384e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // Compute address of modified element and store it into key register. 4385e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ Addu(key, store_base, Operand(offset - kHeapObjectTag)); 4386e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ RecordWrite(elements, 4387e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org key, 4388e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org value, 4389c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org GetRAState(), 4390e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org kSaveFPRegs, 4391e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org EMIT_REMEMBERED_SET, 4392e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org check_needed); 4393e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 4394e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 4395e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4396e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4397e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { 4398e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // By cases: external, fast double 4399e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (instr->is_external()) { 4400e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org DoStoreKeyedExternalArray(instr); 4401e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else if (instr->hydrogen()->value()->representation().IsDouble()) { 4402e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org DoStoreKeyedFixedDoubleArray(instr); 4403e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 4404e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org DoStoreKeyedFixedArray(instr); 4405e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 4406e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 4407e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4408e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4409c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 4410c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->object()).is(a2)); 4411c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->key()).is(a1)); 4412c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->value()).is(a0)); 4413c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 44141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 4415c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 4416c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : isolate()->builtins()->KeyedStoreIC_Initialize(); 4417c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 4418c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4419c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4420c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4421c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 4422c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register object_reg = ToRegister(instr->object()); 4423c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 4424c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4425c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Map> from_map = instr->original_map(); 4426c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Map> to_map = instr->transitioned_map(); 4427003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ElementsKind from_kind = instr->from_kind(); 4428003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ElementsKind to_kind = instr->to_kind(); 4429c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4430c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label not_applicable; 4431c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 4432c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(¬_applicable, ne, scratch, Operand(from_map)); 4433c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 443446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org if (IsSimpleMapChangeTransition(from_kind, to_kind)) { 44357c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Register new_map_reg = ToRegister(instr->new_map_temp()); 44367c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ li(new_map_reg, Operand(to_map)); 4437c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 4438c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Write barrier. 4439c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 4440c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org scratch, GetRAState(), kDontSaveFPRegs); 4441d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 4442c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org PushSafepointRegistersScope scope( 4443c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org this, Safepoint::kWithRegistersAndDoubles); 44447c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ mov(a0, object_reg); 44457c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ li(a1, Operand(to_map)); 44467c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org TransitionElementsKindStub stub(from_kind, to_kind); 44477c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ CallStub(&stub); 4448c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org RecordSafepointWithRegistersAndDoubles( 44497c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 4450c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4451c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(¬_applicable); 4452c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4453c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4454c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 44557c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgvoid LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 44567c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Register object = ToRegister(instr->object()); 44577c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Register temp = ToRegister(instr->temp()); 44587c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Label fail; 4459ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ TestJSArrayForAllocationMemento(object, temp, ne, &fail); 44607c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org DeoptimizeIf(al, instr->environment()); 44617c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ bind(&fail); 44627c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org} 44637c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 44647c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 4465c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStringAdd(LStringAdd* instr) { 4466c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(ToRegister(instr->left())); 4467c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(ToRegister(instr->right())); 4468ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org StringAddStub stub(instr->hydrogen()->flags()); 44698432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4471c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4472c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4473c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { 4474c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org class DeferredStringCharCodeAt: public LDeferredCode { 4475c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org public: 4476c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 4477c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : LDeferredCode(codegen), instr_(instr) { } 4478c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } 4479c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual LInstruction* instr() { return instr_; } 4480c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org private: 4481c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LStringCharCodeAt* instr_; 4482c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org }; 4483c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4484c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeferredStringCharCodeAt* deferred = 44857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredStringCharCodeAt(this, instr); 448664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org StringCharLoadGenerator::Generate(masm(), 448764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ToRegister(instr->string()), 448864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ToRegister(instr->index()), 448964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ToRegister(instr->result()), 449064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org deferred->entry()); 4491c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(deferred->exit()); 4492c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4493c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4494c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4495c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { 4496c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register string = ToRegister(instr->string()); 4497c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 4498c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 4499c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4500c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 4501c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // result register contain a valid pointer because it is already 4502c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // contained in the register pointer map. 4503c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov(result, zero_reg); 4504c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4505c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4506c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(string); 4507c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Push the index as a smi. This is safe because of the checks in 4508c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // DoStringCharCodeAt above. 4509c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->index()->IsConstantOperand()) { 4510c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 4511c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Addu(scratch, zero_reg, Operand(Smi::FromInt(const_index))); 4512c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(scratch); 4513c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 4514c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register index = ToRegister(instr->index()); 4515c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ SmiTag(index); 4516c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(index); 4517c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4518c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr); 4519c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ AssertSmi(v0); 4520c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ SmiUntag(v0); 4521c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ StoreToSafepointRegisterSlot(v0, result); 4522c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4523c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4524c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4525c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { 4526c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org class DeferredStringCharFromCode: public LDeferredCode { 4527c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org public: 4528c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) 4529c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : LDeferredCode(codegen), instr_(instr) { } 4530c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } 4531c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual LInstruction* instr() { return instr_; } 4532c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org private: 4533c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LStringCharFromCode* instr_; 4534c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org }; 4535c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4536c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeferredStringCharFromCode* deferred = 45377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredStringCharFromCode(this, instr); 4538c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4539c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); 4540c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register char_code = ToRegister(instr->char_code()); 4541c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 4542c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 4543c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!char_code.is(result)); 4544c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4545c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(deferred->entry(), hi, 454659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org char_code, Operand(String::kMaxOneByteCharCode)); 4547c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex); 4548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sll(scratch, char_code, kPointerSizeLog2); 4549c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Addu(result, result, scratch); 4550c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(result, FieldMemOperand(result, FixedArray::kHeaderSize)); 4551c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 4552c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(deferred->entry(), eq, result, Operand(scratch)); 4553c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(deferred->exit()); 4554c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4555c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4556c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4557c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { 4558c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register char_code = ToRegister(instr->char_code()); 4559c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result = ToRegister(instr->result()); 4560c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4561c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 4562c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // result register contain a valid pointer because it is already 4563c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // contained in the register pointer map. 4564c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov(result, zero_reg); 4565c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4566c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4567c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ SmiTag(char_code); 4568c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(char_code); 4569c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr); 4570c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ StoreToSafepointRegisterSlot(v0, result); 4571c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4572c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4573c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4574c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4575c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* input = instr->value(); 4576c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(input->IsRegister() || input->IsStackSlot()); 4577c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LOperand* output = instr->result(); 4578c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(output->IsDoubleRegister()); 4579c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FPURegister single_scratch = double_scratch0().low(); 4580c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (input->IsStackSlot()) { 4581c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 4582c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(scratch, ToMemOperand(input)); 4583c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mtc1(scratch, single_scratch); 4584c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 4585c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mtc1(ToRegister(input), single_scratch); 4586c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4587c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ cvt_d_w(ToDoubleRegister(output), single_scratch); 4588c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4589c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4590c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4591a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { 4592a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org LOperand* input = instr->value(); 4593a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ASSERT(input->IsRegister()); 4594a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org LOperand* output = instr->result(); 4595a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ASSERT(output->IsRegister()); 4596a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register scratch = scratch0(); 4597a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 4598a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ SmiTagCheckOverflow(ToRegister(output), ToRegister(input), scratch); 4599a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (!instr->hydrogen()->value()->HasRange() || 4600a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org !instr->hydrogen()->value()->range()->IsInSmiRange()) { 4601a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg)); 4602a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 4603a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org} 4604a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 4605a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 460678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgvoid LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4607c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* input = instr->value(); 460878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org LOperand* output = instr->result(); 460978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 461078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org FPURegister dbl_scratch = double_scratch0(); 461178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ mtc1(ToRegister(input), dbl_scratch); 461278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22); 461378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org} 461478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 461578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 4616c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4617c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org class DeferredNumberTagI: public LDeferredCode { 4618c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org public: 4619c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 4620c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : LDeferredCode(codegen), instr_(instr) { } 462178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org virtual void Generate() { 462278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org codegen()->DoDeferredNumberTagI(instr_, 4623c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org instr_->value(), 462478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org SIGNED_INT32); 462578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } 4626c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual LInstruction* instr() { return instr_; } 4627c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org private: 4628c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LNumberTagI* instr_; 4629c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org }; 4630c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4631c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register src = ToRegister(instr->value()); 4632fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org Register dst = ToRegister(instr->result()); 4633c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register overflow = scratch0(); 4634c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 46357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); 4636fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ SmiTagCheckOverflow(dst, src, overflow); 4637c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ BranchOnOverflow(deferred->entry(), overflow); 4638c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(deferred->exit()); 4639c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4640c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4641c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 464278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgvoid LCodeGen::DoNumberTagU(LNumberTagU* instr) { 464378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org class DeferredNumberTagU: public LDeferredCode { 464478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org public: 464578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 464678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org : LDeferredCode(codegen), instr_(instr) { } 464778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org virtual void Generate() { 464878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org codegen()->DoDeferredNumberTagI(instr_, 4649c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org instr_->value(), 465078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org UNSIGNED_INT32); 465178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } 465278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org virtual LInstruction* instr() { return instr_; } 465378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org private: 465478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org LNumberTagU* instr_; 465578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org }; 465678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 4657c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* input = instr->value(); 465878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org ASSERT(input->IsRegister() && input->Equals(instr->result())); 465978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org Register reg = ToRegister(input); 466078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 466178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 466278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ Branch(deferred->entry(), hi, reg, Operand(Smi::kMaxValue)); 466378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ SmiTag(reg, reg); 466478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ bind(deferred->exit()); 466578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org} 466678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 466778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 466878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgvoid LCodeGen::DoDeferredNumberTagI(LInstruction* instr, 466978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org LOperand* value, 467078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org IntegerSignedness signedness) { 4671c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label slow; 467278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org Register src = ToRegister(value); 4673fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org Register dst = ToRegister(instr->result()); 467459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org DoubleRegister dbl_scratch = double_scratch0(); 4675c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4676c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Preserve the value of all registers. 4677c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4678c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4679c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label done; 468078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org if (signedness == SIGNED_INT32) { 468178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // There was overflow, so bits 30 and 31 of the original integer 468278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // disagree. Try to allocate a heap number in new space and store 468378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // the value in there. If that fails, call the runtime system. 468478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org if (dst.is(src)) { 468578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ SmiUntag(src, dst); 468678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ Xor(src, src, Operand(0x80000000)); 468778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } 4688e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mtc1(src, dbl_scratch); 4689e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cvt_d_w(dbl_scratch, dbl_scratch); 469078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } else { 4691e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mtc1(src, dbl_scratch); 4692e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22); 4693fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org } 469478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 4695c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (FLAG_inline_new) { 469659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); 469759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ AllocateHeapNumber(t1, a3, t0, scratch0(), &slow, DONT_TAG_RESULT); 4698fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ Move(dst, t1); 4699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done); 4700c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4701c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4702c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Slow case: Call the runtime system to do the number allocation. 4703c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&slow); 4704c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4705c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // TODO(3095996): Put a valid pointer value in the stack slot where the result 4706c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // register is stored, as this register is in the pointer map, but contains an 4707c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // integer value. 4708fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ StoreToSafepointRegisterSlot(zero_reg, dst); 4709c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 4710fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ Move(dst, v0); 471183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Subu(dst, dst, kHeapObjectTag); 4712c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4713c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Done. Put the value in dbl_scratch into the value of the allocated heap 4714c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // number. 4715c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 4716e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset)); 471783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Addu(dst, dst, kHeapObjectTag); 4718fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ StoreToSafepointRegisterSlot(dst, dst); 4719c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4720c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4721c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4722c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoNumberTagD(LNumberTagD* instr) { 4723c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org class DeferredNumberTagD: public LDeferredCode { 4724c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org public: 4725c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4726c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : LDeferredCode(codegen), instr_(instr) { } 4727c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 4728c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual LInstruction* instr() { return instr_; } 4729c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org private: 4730c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LNumberTagD* instr_; 4731c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org }; 4732c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4733c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org DoubleRegister input_reg = ToDoubleRegister(instr->value()); 4734c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 4735c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register reg = ToRegister(instr->result()); 4736c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register temp1 = ToRegister(instr->temp()); 4737c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register temp2 = ToRegister(instr->temp2()); 4738c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 47397028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4740c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (FLAG_inline_new) { 4741c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 474283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org // We want the untagged address first for performance 474383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), 474483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DONT_TAG_RESULT); 4745c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 4746c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(deferred->entry()); 4747c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4748c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(deferred->exit()); 4749e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset)); 475083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org // Now that we have finished with the object's real address tag it 475183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Addu(reg, reg, kHeapObjectTag); 4752c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4753c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4754c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4755c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 4756c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 4757c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // result register contain a valid pointer because it is already 4758c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // contained in the register pointer map. 4759c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register reg = ToRegister(instr->result()); 4760c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov(reg, zero_reg); 4761c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4762c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4763c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 476483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Subu(v0, v0, kHeapObjectTag); 4765c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ StoreToSafepointRegisterSlot(v0, reg); 4766c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4767c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4768c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4769c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoSmiTag(LSmiTag* instr) { 4770c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 4771c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ SmiTag(ToRegister(instr->result()), ToRegister(instr->value())); 4772c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4773c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4774c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4775c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoSmiUntag(LSmiUntag* instr) { 4776c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 4777c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 4778fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org Register result = ToRegister(instr->result()); 4779c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->needs_check()) { 4780c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org STATIC_ASSERT(kHeapObjectTag == 1); 4781c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If the input is a HeapObject, value of scratch won't be zero. 4782fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ And(scratch, input, Operand(kHeapObjectTag)); 4783fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ SmiUntag(result, input); 4784c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 4785c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 4786fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ SmiUntag(result, input); 4787c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4788c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4789c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4790c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4791c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::EmitNumberUntagD(Register input_reg, 4792c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoubleRegister result_reg, 4793c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com bool can_convert_undefined_to_nan, 47942efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool deoptimize_on_minus_zero, 47957c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org LEnvironment* env, 47967c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org NumberUntagDMode mode) { 4797c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 4798c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4799c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label load_smi, heap_number, done; 4800c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4801c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 48027c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // Smi check. 48037c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); 4804c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 48057c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // Heap number map check. 48067c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 48077c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 4808c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com if (!can_convert_undefined_to_nan) { 48097c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org DeoptimizeIf(ne, env, scratch, Operand(at)); 48107c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } else { 4811c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Label heap_number, convert; 48127c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ Branch(&heap_number, eq, scratch, Operand(at)); 4813c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4814c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org // Convert undefined (and hole) to NaN. 48157c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 48167c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org DeoptimizeIf(ne, env, input_reg, Operand(at)); 4817c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4818c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org __ bind(&convert); 48197c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ LoadRoot(at, Heap::kNanValueRootIndex); 48207c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ ldc1(result_reg, FieldMemOperand(at, HeapNumber::kValueOffset)); 48217c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ Branch(&done); 4822c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 48237c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ bind(&heap_number); 48247c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 48257c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // Heap number to double register conversion. 48267c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 48277c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (deoptimize_on_minus_zero) { 48287c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ mfc1(at, result_reg.low()); 48297c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ Branch(&done, ne, at, Operand(zero_reg)); 48307c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ mfc1(scratch, result_reg.high()); 48317c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org DeoptimizeIf(eq, env, scratch, Operand(HeapNumber::kSignMask)); 48327c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 48337c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ Branch(&done); 48347c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } else { 48357c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ SmiUntag(scratch, input_reg); 48367c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); 48372efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 4838c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4839c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Smi to double register conversion 4840c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&load_smi); 4841fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // scratch: untagged value of input_reg 4842fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ mtc1(scratch, result_reg); 4843c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ cvt_d_w(result_reg, result_reg); 4844c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 4845c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4846c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4847c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4848c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 4849c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input_reg = ToRegister(instr->value()); 4850c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch1 = scratch0(); 4851c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register scratch2 = ToRegister(instr->temp()); 4852c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoubleRegister double_scratch = double_scratch0(); 485383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister double_scratch2 = ToDoubleRegister(instr->temp3()); 4854c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4855c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2)); 4856c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1)); 4857c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4858c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label done; 4859c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4860c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // The input is a tagged HeapObject. 4861c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Heap number map check. 4862c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4863c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 4864c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // This 'at' value and scratch1 map value are used for tests in both clauses 4865c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // of the if. 4866c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4867c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->truncating()) { 4868c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register scratch3 = ToRegister(instr->temp2()); 486983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org FPURegister single_scratch = double_scratch.low(); 4870c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!scratch3.is(input_reg) && 4871c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org !scratch3.is(scratch1) && 4872c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org !scratch3.is(scratch2)); 4873c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Performs a truncating conversion of a floating point number as used by 4874c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // the JS bitwise operations. 4875c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label heap_number; 4876c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map? 4877c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Check for undefined. Undefined is converted to zero for truncating 4878c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // conversions. 4879c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 4880c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), input_reg, Operand(at)); 4881c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(input_reg)); 4882c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov(input_reg, zero_reg); 4883c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done); 4884c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4885c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&heap_number); 4886c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ ldc1(double_scratch2, 4887c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 4888c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ EmitECMATruncate(input_reg, 4889c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org double_scratch2, 4890c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org single_scratch, 4891c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch1, 4892c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch2, 4893c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch3); 4894c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 4895c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Deoptimize if we don't have a heap number. 4896c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), scratch1, Operand(at)); 4897c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4898c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Load the double value. 4899c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ ldc1(double_scratch, 4900c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 4901c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4902c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register except_flag = scratch2; 4903c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ EmitFPUTruncate(kRoundToZero, 490483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org input_reg, 4905c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org double_scratch, 4906c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch1, 490783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org double_scratch2, 4908c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org except_flag, 4909c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org kCheckForInexactConversion); 4910c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4911c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Deopt if the operation did not succeed. 4912c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 4913c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4914c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 4915c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done, ne, input_reg, Operand(zero_reg)); 4916c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4917c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mfc1(scratch1, double_scratch.high()); 4918c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 4919c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 4920c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4921c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4922c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 4923c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4924c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4925c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4926c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoTaggedToI(LTaggedToI* instr) { 4927c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org class DeferredTaggedToI: public LDeferredCode { 4928c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org public: 4929c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 4930c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : LDeferredCode(codegen), instr_(instr) { } 4931c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 4932c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual LInstruction* instr() { return instr_; } 4933c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org private: 4934c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LTaggedToI* instr_; 4935c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org }; 4936c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4937c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* input = instr->value(); 4938c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(input->IsRegister()); 4939c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(input->Equals(instr->result())); 4940c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4941c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register input_reg = ToRegister(input); 4942c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 49437028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); 4944c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4945c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Let the deferred code handle the HeapObject case. 4946c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfNotSmi(input_reg, deferred->entry()); 4947c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4948c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Smi to int32 conversion. 4949c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ SmiUntag(input_reg); 4950c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(deferred->exit()); 4951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4952c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4953c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4954c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 4955c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* input = instr->value(); 4956c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(input->IsRegister()); 4957c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LOperand* result = instr->result(); 4958c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(result->IsDoubleRegister()); 4959c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4960c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register input_reg = ToRegister(input); 4961c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoubleRegister result_reg = ToDoubleRegister(result); 4962c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 49637c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org HValue* value = instr->hydrogen()->value(); 4964c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com NumberUntagDMode mode = value->representation().IsSmi() 4965c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED; 49667c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 4967c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EmitNumberUntagD(input_reg, result_reg, 4968c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com instr->hydrogen()->can_convert_undefined_to_nan(), 49692efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org instr->hydrogen()->deoptimize_on_minus_zero(), 49707c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org instr->environment(), 49717c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org mode); 4972c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 4973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4974c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4975c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDoubleToI(LDoubleToI* instr) { 4976c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result_reg = ToRegister(instr->result()); 4977c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch1 = scratch0(); 4978c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register scratch2 = ToRegister(instr->temp()); 4979c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org DoubleRegister double_input = ToDoubleRegister(instr->value()); 4980c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4981c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->truncating()) { 4982c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register scratch3 = ToRegister(instr->temp2()); 498383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org FPURegister single_scratch = double_scratch0().low(); 4984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ EmitECMATruncate(result_reg, 4985c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org double_input, 4986c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org single_scratch, 4987c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch1, 4988c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch2, 4989c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch3); 4990c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 4991c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register except_flag = scratch2; 4992c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 4993c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ EmitFPUTruncate(kRoundToMinusInf, 499483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org result_reg, 4995c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org double_input, 4996c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch1, 499783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org double_scratch0(), 4998c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org except_flag, 4999c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org kCheckForInexactConversion); 5000c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5001c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Deopt if the operation did not succeed (except_flag != 0). 5002c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 5003a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5004a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5005a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Label done; 5006a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ Branch(&done, ne, result_reg, Operand(zero_reg)); 5007a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ mfc1(scratch1, double_input.high()); 5008a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 5009a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 5010a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ bind(&done); 5011a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 5012a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 5013a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org} 5014a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5015a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5016a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 5017a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register result_reg = ToRegister(instr->result()); 5018a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register scratch1 = scratch0(); 5019a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register scratch2 = ToRegister(instr->temp()); 5020a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org DoubleRegister double_input = ToDoubleRegister(instr->value()); 5021a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5022a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (instr->truncating()) { 5023a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register scratch3 = ToRegister(instr->temp2()); 5024a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org FPURegister single_scratch = double_scratch0().low(); 5025a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ EmitECMATruncate(result_reg, 5026a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org double_input, 5027a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org single_scratch, 5028a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org scratch1, 5029a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org scratch2, 5030a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org scratch3); 5031a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } else { 5032a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register except_flag = scratch2; 5033a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5034a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ EmitFPUTruncate(kRoundToMinusInf, 5035a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org result_reg, 5036a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org double_input, 5037a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org scratch1, 5038a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org double_scratch0(), 5039a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org except_flag, 5040a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org kCheckForInexactConversion); 5041a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5042a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org // Deopt if the operation did not succeed (except_flag != 0). 5043a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 5044a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5045a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5046a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Label done; 5047a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ Branch(&done, ne, result_reg, Operand(zero_reg)); 5048a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ mfc1(scratch1, double_input.high()); 5049a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 5050a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 5051a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ bind(&done); 5052a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 5053c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 5054a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ SmiTagCheckOverflow(result_reg, result_reg, scratch1); 5055a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org DeoptimizeIf(lt, instr->environment(), scratch1, Operand(zero_reg)); 5056a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org} 5057a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5058a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5059c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCheckSmi(LCheckSmi* instr) { 5060c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* input = instr->value(); 5061c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(at, ToRegister(input), Operand(kSmiTagMask)); 5062c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 5063c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5064c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5065c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5066c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 50671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!instr->hydrogen()->value()->IsHeapObject()) { 50681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org LOperand* input = instr->value(); 50691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ And(at, ToRegister(input), Operand(kSmiTagMask)); 50701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 50711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 5072c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5073c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5074c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5075c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 5076c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 5077c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 5078c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5079c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ GetObjectType(input, scratch, scratch); 5080c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5081c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->is_interval_check()) { 5082c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org InstanceType first; 5083c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org InstanceType last; 5084c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org instr->hydrogen()->GetCheckInterval(&first, &last); 5085c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5086c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If there is only one type in the interval check for equality. 5087c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (first == last) { 5088c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), scratch, Operand(first)); 5089c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 5090c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(lo, instr->environment(), scratch, Operand(first)); 5091c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Omit check for the last type. 5092c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (last != LAST_TYPE) { 5093c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(hi, instr->environment(), scratch, Operand(last)); 5094c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 5095c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 5096c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 5097c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org uint8_t mask; 5098c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org uint8_t tag; 5099c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); 5100c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5101c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (IsPowerOf2(mask)) { 5102c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(tag == 0 || IsPowerOf2(tag)); 5103c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(at, scratch, mask); 5104c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(tag == 0 ? ne : eq, instr->environment(), 5105c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org at, Operand(zero_reg)); 5106c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 5107c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(scratch, scratch, Operand(mask)); 5108c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), scratch, Operand(tag)); 5109c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 5110c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 5111c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5112c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5113c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5114c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCheckFunction(LCheckFunction* instr) { 511564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Register reg = ToRegister(instr->value()); 511664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Handle<JSFunction> target = instr->hydrogen()->target(); 511779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 511864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (isolate()->heap()->InNewSpace(*target)) { 511964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Register reg = ToRegister(instr->value()); 5120594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(target); 512164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ li(at, Operand(Handle<Object>(cell))); 5122f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ lw(at, FieldMemOperand(at, Cell::kValueOffset)); 512364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org DeoptimizeIf(ne, instr->environment(), reg, 512464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Operand(at)); 512564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 512664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org DeoptimizeIf(ne, instr->environment(), reg, 512764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Operand(target)); 512864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 5129c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5130c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5131c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5132594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 5133594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org { 5134594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 5135594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ push(object); 5136594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr); 5137594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ StoreToSafepointRegisterSlot(v0, scratch0()); 5138594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5139594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ And(at, scratch0(), Operand(kSmiTagMask)); 5140594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 514105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org} 514205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org 514305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org 51441456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid LCodeGen::DoCheckMaps(LCheckMaps* instr) { 5145594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org class DeferredCheckMaps: public LDeferredCode { 5146594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org public: 5147594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) 5148594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org : LDeferredCode(codegen), instr_(instr), object_(object) { 5149594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org SetExit(check_maps()); 5150594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5151594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org virtual void Generate() { 5152594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org codegen()->DoDeferredInstanceMigration(instr_, object_); 5153594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5154594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label* check_maps() { return &check_maps_; } 5155594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org virtual LInstruction* instr() { return instr_; } 5156594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org private: 5157594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org LCheckMaps* instr_; 5158594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label check_maps_; 5159594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Register object_; 5160594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org }; 5161594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5162c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (instr->hydrogen()->CanOmitMapChecks()) return; 516359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Register map_reg = scratch0(); 5164c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LOperand* input = instr->value(); 5165c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(input->IsRegister()); 5166c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register reg = ToRegister(input); 51671456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org SmallMapList* map_set = instr->hydrogen()->map_set(); 516859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); 5169594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5170594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeferredCheckMaps* deferred = NULL; 5171594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (instr->hydrogen()->has_migration_target()) { 5172594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org deferred = new(zone()) DeferredCheckMaps(this, instr, reg); 5173594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ bind(deferred->check_maps()); 5174594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5175594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5176594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label success; 51771456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org for (int i = 0; i < map_set->length() - 1; i++) { 51781456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Handle<Map> map = map_set->at(i); 5179a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ CompareMapAndBranch(map_reg, map, &success, eq, &success); 51801456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 51811456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Handle<Map> map = map_set->last(); 5182594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // Do the CompareMap() directly within the Branch() and DeoptimizeIf(). 5183594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (instr->hydrogen()->has_migration_target()) { 5184594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Branch(deferred->entry(), ne, map_reg, Operand(map)); 5185594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 5186594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeoptimizeIf(ne, instr->environment(), map_reg, Operand(map)); 5187594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5188594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 51891456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ bind(&success); 5190c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5191c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5192c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5193c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 5194c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); 5195c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result_reg = ToRegister(instr->result()); 5196c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); 5197c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); 5198c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5199c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5200c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5201c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 5202c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register unclamped_reg = ToRegister(instr->unclamped()); 5203c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result_reg = ToRegister(instr->result()); 5204c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ ClampUint8(result_reg, unclamped_reg); 5205c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5206c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5207c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5208c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 5209c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 5210c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register input_reg = ToRegister(instr->unclamped()); 5211c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register result_reg = ToRegister(instr->result()); 5212c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); 5213c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label is_smi, done, heap_number; 5214c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5215c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Both smi and heap number cases are handled. 5216fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi); 5217c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5218c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Check for heap number 5219c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 5220c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&heap_number, eq, scratch, Operand(factory()->heap_number_map())); 5221c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5222c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Check for undefined. Undefined is converted to zero for clamping 5223c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // conversions. 5224c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeoptimizeIf(ne, instr->environment(), input_reg, 5225c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Operand(factory()->undefined_value())); 5226c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov(result_reg, zero_reg); 5227c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ jmp(&done); 5228c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5229c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Heap number 5230c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&heap_number); 5231c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ ldc1(double_scratch0(), FieldMemOperand(input_reg, 5232c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org HeapNumber::kValueOffset)); 5233c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg); 5234c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ jmp(&done); 5235c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5236c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&is_smi); 5237c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ ClampUint8(result_reg, scratch); 5238c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5239c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 5240c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5241c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5242c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 52437c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgvoid LCodeGen::DoAllocate(LAllocate* instr) { 52447c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org class DeferredAllocate: public LDeferredCode { 52457c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org public: 52467c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org DeferredAllocate(LCodeGen* codegen, LAllocate* instr) 52477c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org : LDeferredCode(codegen), instr_(instr) { } 52487c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org virtual void Generate() { codegen()->DoDeferredAllocate(instr_); } 52497c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org virtual LInstruction* instr() { return instr_; } 52507c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org private: 52517c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org LAllocate* instr_; 52527c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org }; 52537c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 52547c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org DeferredAllocate* deferred = 52557c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org new(zone()) DeferredAllocate(this, instr); 52567c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 52577c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Register result = ToRegister(instr->result()); 52587c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Register scratch = ToRegister(instr->temp1()); 52597c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Register scratch2 = ToRegister(instr->temp2()); 52607c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 52614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Allocate memory for the object. 52624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org AllocationFlags flags = TAG_OBJECT; 52634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (instr->hydrogen()->MustAllocateDoubleAligned()) { 52644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); 52654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 5266d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { 5267d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5268d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5269e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE); 5270d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5271d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5272b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE); 5273e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 52744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (instr->size()->IsConstantOperand()) { 52754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 52764c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags); 52777c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } else { 52784a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register size = ToRegister(instr->size()); 5279f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Allocate(size, 5280f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org result, 5281f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch, 5282f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch2, 5283f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org deferred->entry(), 5284f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org flags); 52857c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 52867c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 52877c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ bind(deferred->exit()); 5288c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 5289c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (instr->hydrogen()->MustPrefillWithFiller()) { 5290c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (instr->size()->IsConstantOperand()) { 5291c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5292c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ li(scratch, Operand(size)); 5293c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } else { 5294c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org scratch = ToRegister(instr->size()); 5295c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 5296c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ Subu(scratch, scratch, Operand(kPointerSize)); 5297c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ Subu(result, result, Operand(kHeapObjectTag)); 5298c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Label loop; 5299c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ bind(&loop); 5300c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ li(scratch2, Operand(isolate()->factory()->one_pointer_filler_map())); 5301c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ Addu(at, result, Operand(scratch)); 5302c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ sw(scratch2, MemOperand(at)); 5303c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ Subu(scratch, scratch, Operand(kPointerSize)); 5304c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ Branch(&loop, ge, scratch, Operand(zero_reg)); 5305c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ Addu(result, result, Operand(kHeapObjectTag)); 5306c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 53077c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org} 53087c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 53097c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 53107c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgvoid LCodeGen::DoDeferredAllocate(LAllocate* instr) { 53117c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Register result = ToRegister(instr->result()); 53127c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 53137c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 53147c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // result register contain a valid pointer because it is already 53157c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // contained in the register pointer map. 53167c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ mov(result, zero_reg); 53177c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 53187c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 5319f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (instr->size()->IsRegister()) { 5320f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Register size = ToRegister(instr->size()); 5321f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ASSERT(!size.is(result)); 5322f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ SmiTag(size); 5323f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ push(size); 5324f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } else { 5325f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5326f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ Push(Smi::FromInt(size)); 5327f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 5328f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 5329d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { 5330d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5331d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5332b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org CallRuntimeFromDeferred(Runtime::kAllocateInOldPointerSpace, 1, instr); 5333d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5334d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5335b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org CallRuntimeFromDeferred(Runtime::kAllocateInOldDataSpace, 1, instr); 5336e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 5337b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); 5338e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 53397c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ StoreToSafepointRegisterSlot(v0, result); 53407c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org} 53417c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 53427c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 5343c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoToFastProperties(LToFastProperties* instr) { 5344c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(ToRegister(instr->value()).is(a0)); 5345c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 5346c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(a0); 5347c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallRuntime(Runtime::kToFastProperties, 1, instr); 5348c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5349c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5350c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5351c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 5352c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label materialized; 5353c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Registers will be used as follows: 5354c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // t3 = literals array. 5355c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // a1 = regexp literal. 5356c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // a0 = regexp literal clone. 5357c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // a2 and t0-t2 are used as temporaries. 53589c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org int literal_offset = 53599c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); 53609c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org __ LoadHeapObject(t3, instr->hydrogen()->literals()); 5361c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(a1, FieldMemOperand(t3, literal_offset)); 5362c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 5363c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&materialized, ne, a1, Operand(at)); 5364c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5365c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Create regexp literal using runtime function 5366c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Result will be in v0. 5367c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(t2, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); 5368c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(t1, Operand(instr->hydrogen()->pattern())); 5369c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(t0, Operand(instr->hydrogen()->flags())); 5370c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Push(t3, t2, t1, t0); 5371c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); 5372c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ mov(a1, v0); 5373c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5374c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&materialized); 5375c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 5376c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label allocated, runtime_allocate; 5377c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 53784c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ Allocate(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT); 5379c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ jmp(&allocated); 5380c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5381c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&runtime_allocate); 5382c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(a0, Operand(Smi::FromInt(size))); 5383c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Push(a1, a0); 5384c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); 5385c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ pop(a1); 5386c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5387c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&allocated); 5388c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Copy the content into the newly allocated memory. 5389c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // (Unroll copy loop once for better throughput). 5390c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { 5391c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(a3, FieldMemOperand(a1, i)); 5392c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(a2, FieldMemOperand(a1, i + kPointerSize)); 5393c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(a3, FieldMemOperand(v0, i)); 5394c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(a2, FieldMemOperand(v0, i + kPointerSize)); 5395c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 5396c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if ((size % (2 * kPointerSize)) != 0) { 5397c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(a3, FieldMemOperand(a1, size - kPointerSize)); 5398c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ sw(a3, FieldMemOperand(v0, size - kPointerSize)); 5399c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 5400c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5401c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5402c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5403c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { 5404c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Use the fast case closure allocation code that allocates in new 5405c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // space for nested functions that don't need literals cloning. 5406c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org bool pretenure = instr->hydrogen()->pretenure(); 540732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (!pretenure && instr->hydrogen()->has_no_literals()) { 540832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org FastNewClosureStub stub(instr->hydrogen()->language_mode(), 540932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->hydrogen()->is_generator()); 541032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ li(a1, Operand(instr->hydrogen()->shared_info())); 5411c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(a1); 54128432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 5413c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 541432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ li(a2, Operand(instr->hydrogen()->shared_info())); 541532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ li(a1, Operand(pretenure ? factory()->true_value() 541632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org : factory()->false_value())); 5417c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Push(cp, a2, a1); 5418c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallRuntime(Runtime::kNewClosure, 3, instr); 5419c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 5420c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5421c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5422c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5423c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoTypeof(LTypeof* instr) { 5424c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(ToRegister(instr->result()).is(v0)); 5425c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 5426c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(input); 5427c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallRuntime(Runtime::kTypeof, 1, instr); 5428c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5429c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5430c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5431c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 5432c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register input = ToRegister(instr->value()); 5433c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5434c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register cmp1 = no_reg; 5435c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Operand cmp2 = Operand(no_reg); 5436c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 54371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Condition final_branch_condition = EmitTypeofIs(instr->TrueLabel(chunk_), 54381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->FalseLabel(chunk_), 5439c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org input, 5440c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org instr->type_literal(), 5441c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp1, 5442c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp2); 5443c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5444c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(cmp1.is_valid()); 5445c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!cmp2.is_reg() || cmp2.rm().is_valid()); 5446c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5447c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (final_branch_condition != kNoCondition) { 54481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, final_branch_condition, cmp1, cmp2); 5449c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 5450c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5451c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5452c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5453c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgCondition LCodeGen::EmitTypeofIs(Label* true_label, 5454c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* false_label, 5455c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register input, 5456c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<String> type_name, 5457c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register& cmp1, 5458c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Operand& cmp2) { 5459c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // This function utilizes the delay slot heavily. This is used to load 5460c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // values that are always usable without depending on the type of the input 5461c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // register. 5462c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Condition final_branch_condition = kNoCondition; 5463c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch = scratch0(); 5464750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (type_name->Equals(heap()->number_string())) { 5465c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(input, true_label); 5466c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(input, FieldMemOperand(input, HeapObject::kMapOffset)); 5467c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 5468c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp1 = input; 5469c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp2 = Operand(at); 5470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org final_branch_condition = eq; 5471c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5472750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } else if (type_name->Equals(heap()->string_string())) { 5473c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(input, false_label); 5474c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ GetObjectType(input, input, scratch); 5475c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(USE_DELAY_SLOT, false_label, 5476c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ge, scratch, Operand(FIRST_NONSTRING_TYPE)); 5477c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // input is an object so we can load the BitFieldOffset even if we take the 5478c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // other branch. 5479c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset)); 5480c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(at, at, 1 << Map::kIsUndetectable); 5481c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp1 = at; 5482c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp2 = Operand(zero_reg); 5483c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org final_branch_condition = eq; 5484c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5485f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } else if (type_name->Equals(heap()->symbol_string())) { 5486f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ JumpIfSmi(input, false_label); 5487f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ GetObjectType(input, input, scratch); 5488f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org cmp1 = scratch; 5489f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org cmp2 = Operand(SYMBOL_TYPE); 5490f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org final_branch_condition = eq; 5491f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 5492750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } else if (type_name->Equals(heap()->boolean_string())) { 5493c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kTrueValueRootIndex); 5494c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); 5495c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kFalseValueRootIndex); 5496c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp1 = at; 5497c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp2 = Operand(input); 5498c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org final_branch_condition = eq; 5499c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5500750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { 5501c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kNullValueRootIndex); 5502c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp1 = at; 5503c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp2 = Operand(input); 5504c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org final_branch_condition = eq; 5505c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5506750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } else if (type_name->Equals(heap()->undefined_string())) { 5507c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 5508c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); 5509c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // The first instruction of JumpIfSmi is an And - it is safe in the delay 5510c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // slot. 5511c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(input, false_label); 5512c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Check for undetectable objects => true. 5513c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(input, FieldMemOperand(input, HeapObject::kMapOffset)); 5514c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset)); 5515c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(at, at, 1 << Map::kIsUndetectable); 5516c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp1 = at; 5517c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp2 = Operand(zero_reg); 5518c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org final_branch_condition = ne; 5519c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5520750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } else if (type_name->Equals(heap()->function_string())) { 5521c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 5522c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(input, false_label); 5523c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ GetObjectType(input, scratch, input); 5524c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(true_label, eq, input, Operand(JS_FUNCTION_TYPE)); 5525c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp1 = input; 5526c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp2 = Operand(JS_FUNCTION_PROXY_TYPE); 5527c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org final_branch_condition = eq; 5528c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5529750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } else if (type_name->Equals(heap()->object_string())) { 5530c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(input, false_label); 5531c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!FLAG_harmony_typeof) { 5532c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kNullValueRootIndex); 5533c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); 5534c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 5535f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register map = input; 5536f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ GetObjectType(input, map, scratch); 5537f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Branch(false_label, 5538f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 5539c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(USE_DELAY_SLOT, false_label, 5540c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org gt, scratch, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 5541f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // map is still valid, so the BitField can be loaded in delay slot. 5542c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Check for undetectable objects => false. 5543f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset)); 5544c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ And(at, at, 1 << Map::kIsUndetectable); 5545c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp1 = at; 5546c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp2 = Operand(zero_reg); 5547c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org final_branch_condition = eq; 5548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5549c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 5550c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp1 = at; 5551c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org cmp2 = Operand(zero_reg); // Set to valid regs, to avoid caller assertion. 5552c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(false_label); 5553c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 5554c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5555c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return final_branch_condition; 5556c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5557c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5558c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5559c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 5560c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Register temp1 = ToRegister(instr->temp()); 5561c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5562c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EmitIsConstructCall(temp1, scratch0()); 5563c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 55641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, eq, temp1, 5565c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 5566c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5567c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5568c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5569c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) { 5570c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!temp1.is(temp2)); 5571c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Get the frame pointer for the calling frame. 5572c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 5573c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5574c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Skip the arguments adaptor frame if it exists. 5575c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label check_frame_marker; 5576c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset)); 5577c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&check_frame_marker, ne, temp2, 5578c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 5579c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset)); 5580c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5581c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Check the marker in the calling frame. 5582c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&check_frame_marker); 5583c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset)); 5584c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5585c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5586c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 55870ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::EnsureSpaceForLazyDeopt() { 558859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (info()->IsStub()) return; 55890ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // Ensure that we have enough space after the previous lazy-bailout 55900ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // instruction for patching the code here. 55910ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry int current_pc = masm()->pc_offset(); 55920ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry int patch_size = Deoptimizer::patch_size(); 55930ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry if (current_pc < last_lazy_deopt_pc_ + patch_size) { 55940ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc; 55950ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry ASSERT_EQ(0, padding_size % Assembler::kInstrSize); 55960ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry while (padding_size > 0) { 55970ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ nop(); 55980ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry padding_size -= Assembler::kInstrSize; 55990ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry } 56000ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry } 56010ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry} 56020ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 56030ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 5604c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLazyBailout(LLazyBailout* instr) { 56050ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry EnsureSpaceForLazyDeopt(); 56066fe0fda6a144bf4a3991162c622e8745376b755aulan@chromium.org last_lazy_deopt_pc_ = masm()->pc_offset(); 56070ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry ASSERT(instr->HasEnvironment()); 56080ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry LEnvironment* env = instr->environment(); 56090ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 56100ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 5611c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5612c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5613c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5614c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDeoptimize(LDeoptimize* instr) { 5615c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Deoptimizer::BailoutType type = instr->hydrogen()->type(); 5616c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the 5617c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // needed return address), even though the implementation of LAZY and EAGER is 5618c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // now identical. When LAZY is eventually completely folded into EAGER, remove 5619c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // the special case below. 5620c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (info()->IsStub() && type == Deoptimizer::EAGER) { 5621c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org type = Deoptimizer::LAZY; 5622c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 5623594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5624594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Comment(";;; deoptimize: %s", instr->hydrogen()->reason()); 5625c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org DeoptimizeIf(al, instr->environment(), type, zero_reg, Operand(zero_reg)); 5626c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5627c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5628c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 562946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgvoid LCodeGen::DoDummyUse(LDummyUse* instr) { 563046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org // Nothing to see here, move on! 563146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org} 563246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 563346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 5634c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { 56350ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 56360ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry __ CallRuntimeSaveDoubles(Runtime::kStackGuard); 56370ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RecordSafepointWithLazyDeopt( 56380ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 56390ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry ASSERT(instr->HasEnvironment()); 56400ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry LEnvironment* env = instr->environment(); 56410ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 5642c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5643c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5644c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5645c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStackCheck(LStackCheck* instr) { 5646c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org class DeferredStackCheck: public LDeferredCode { 5647c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org public: 5648c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) 5649c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : LDeferredCode(codegen), instr_(instr) { } 5650c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } 5651c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org virtual LInstruction* instr() { return instr_; } 5652c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org private: 5653c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LStackCheck* instr_; 5654c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org }; 5655c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 56560ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry ASSERT(instr->HasEnvironment()); 56570ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry LEnvironment* env = instr->environment(); 56580ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // There is no LLazyBailout instruction for stack-checks. We have to 56590ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // prepare for lazy deoptimization explicitly here. 5660c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->hydrogen()->is_function_entry()) { 5661c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Perform stack overflow check. 5662c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label done; 5663c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kStackLimitRootIndex); 5664c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&done, hs, sp, Operand(at)); 5665c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org StackCheckStub stub; 56668432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 56670ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry EnsureSpaceForLazyDeopt(); 56686fe0fda6a144bf4a3991162c622e8745376b755aulan@chromium.org last_lazy_deopt_pc_ = masm()->pc_offset(); 5669c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 56700ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 56710ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 5672c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 5673c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(instr->hydrogen()->is_backwards_branch()); 5674c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Perform stack overflow check if this goto needs it before jumping. 5675c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org DeferredStackCheck* deferred_stack_check = 56767028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredStackCheck(this, instr); 5677c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(at, Heap::kStackLimitRootIndex); 5678c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(deferred_stack_check->entry(), lo, sp, Operand(at)); 56790ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry EnsureSpaceForLazyDeopt(); 56806fe0fda6a144bf4a3991162c622e8745376b755aulan@chromium.org last_lazy_deopt_pc_ = masm()->pc_offset(); 5681c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(instr->done_label()); 5682c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org deferred_stack_check->SetExit(instr->done_label()); 56830ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 56840ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // Don't record a deoptimization index for the safepoint here. 56850ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // This will be done explicitly when emitting call and the safepoint in 56860ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // the deferred code. 5687c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 5688c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5689c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5690c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5691c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoOsrEntry(LOsrEntry* instr) { 5692c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // This is a pseudo-instruction that ensures that the environment here is 5693c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // properly registered for deoptimization and records the assembler's PC 5694c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // offset. 5695c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LEnvironment* environment = instr->environment(); 5696c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5697c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // If the environment were already registered, we would have no way of 5698c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // backpatching it with the spill slot operands. 5699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!environment->HasBeenRegistered()); 57000ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 57011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 57021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Normally we record the first unknown OSR value as the entrypoint to the OSR 57031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // code, but if there were none, record the entrypoint here. 57041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (osr_pc_offset_ == -1) osr_pc_offset_ = masm()->pc_offset(); 5705c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 5706c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5707c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5708812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { 5709812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register result = ToRegister(instr->result()); 5710812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register object = ToRegister(instr->object()); 5711812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 5712812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org DeoptimizeIf(eq, instr->environment(), object, Operand(at)); 5713812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5714812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register null_value = t1; 5715812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ LoadRoot(null_value, Heap::kNullValueRootIndex); 5716812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org DeoptimizeIf(eq, instr->environment(), object, Operand(null_value)); 5717812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5718812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ And(at, object, kSmiTagMask); 5719812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 5720812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5721812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 5722812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ GetObjectType(object, a1, a1); 5723812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org DeoptimizeIf(le, instr->environment(), a1, Operand(LAST_JS_PROXY_TYPE)); 5724812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5725812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Label use_cache, call_runtime; 5726812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ASSERT(object.is(a0)); 5727812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ CheckEnumCache(null_value, &call_runtime); 5728812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5729812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ lw(result, FieldMemOperand(object, HeapObject::kMapOffset)); 5730812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ Branch(&use_cache); 5731812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5732812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Get the set of properties to enumerate. 5733812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ bind(&call_runtime); 5734812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ push(object); 5735812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); 5736812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5737812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); 5738812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ASSERT(result.is(v0)); 5739812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ LoadRoot(at, Heap::kMetaMapRootIndex); 5740812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org DeoptimizeIf(ne, instr->environment(), a1, Operand(at)); 5741812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ bind(&use_cache); 5742812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 5743812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5744812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5745812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { 5746812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register map = ToRegister(instr->map()); 5747812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register result = ToRegister(instr->result()); 574878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org Label load_cache, done; 574978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ EnumLength(result, map); 575078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ Branch(&load_cache, ne, result, Operand(Smi::FromInt(0))); 575178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ li(result, Operand(isolate()->factory()->empty_fixed_array())); 575278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ jmp(&done); 575378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 575478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ bind(&load_cache); 575589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org __ LoadInstanceDescriptors(map, result); 5756812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ lw(result, 5757304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FieldMemOperand(result, DescriptorArray::kEnumCacheOffset)); 5758812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ lw(result, 5759812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org FieldMemOperand(result, FixedArray::SizeFor(instr->idx()))); 5760812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); 576178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 576278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org __ bind(&done); 5763812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 5764812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5765812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5766812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { 5767812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register object = ToRegister(instr->value()); 5768812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register map = ToRegister(instr->map()); 5769812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ lw(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset)); 5770812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org DeoptimizeIf(ne, instr->environment(), map, Operand(scratch0())); 5771812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 5772812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5773812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5774812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { 5775812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register object = ToRegister(instr->object()); 5776812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register index = ToRegister(instr->index()); 5777812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register result = ToRegister(instr->result()); 5778812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register scratch = scratch0(); 5779812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5780812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Label out_of_object, done; 5781812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ Branch(USE_DELAY_SLOT, &out_of_object, lt, index, Operand(zero_reg)); 5782812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ sll(scratch, index, kPointerSizeLog2 - kSmiTagSize); // In delay slot. 5783812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5784812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org STATIC_ASSERT(kPointerSizeLog2 > kSmiTagSize); 5785812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ Addu(scratch, object, scratch); 5786812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ lw(result, FieldMemOperand(scratch, JSObject::kHeaderSize)); 5787812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5788812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ Branch(&done); 5789812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5790812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ bind(&out_of_object); 5791812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 5792812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Index is equal to negated out of object property index plus 1. 5793812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ Subu(scratch, result, scratch); 5794812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ lw(result, FieldMemOperand(scratch, 5795812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org FixedArray::kHeaderSize - kPointerSize)); 5796812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ bind(&done); 5797812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 5798812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5799812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 5800c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#undef __ 5801c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 5802c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} } // namespace v8::internal 5803