194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org// Copyright 2013 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 4c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 6c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 8c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org#include "src/base/bits.h" 106313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org#include "src/code-factory.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/code-stubs.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-osr.h" 13d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org#include "src/ic/ic.h" 14e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org#include "src/ic/stub-cache.h" 154b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/x64/lithium-codegen-x64.h" 16c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 17c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgnamespace v8 { 18c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgnamespace internal { 19c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 20c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org// When invoking builtins, we need to record the safepoint in the middle of 223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org// the invoke instruction sequence generated by the macro assembler. 23ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass SafepointGenerator FINAL : public CallWrapper { 243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org public: 253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org SafepointGenerator(LCodeGen* codegen, 263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LPointerMap* pointers, 2727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode mode) 283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org : codegen_(codegen), 293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org pointers_(pointers), 3027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org deopt_mode_(mode) { } 3132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual ~SafepointGenerator() {} 323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 33ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void BeforeCall(int call_size) const OVERRIDE {} 34eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org 35ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void AfterCall() const OVERRIDE { 3627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org codegen_->RecordSafepoint(pointers_, deopt_mode_); 373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org private: 403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LCodeGen* codegen_; 413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LPointerMap* pointers_; 4227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode deopt_mode_; 433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}; 443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 46c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#define __ masm()-> 47c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 48c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgbool LCodeGen::GenerateCode() { 491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org LPhase phase("Z_Code generation", chunk()); 50e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_unused()); 51c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org status_ = GENERATING; 52c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 53c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Open a frame scope to indicate that there is a frame on the stack. The 54c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // MANUAL indicates that the scope shouldn't actually generate code to set up 55c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the frame (that is done in GeneratePrologue). 56c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope frame_scope(masm_, StackFrame::MANUAL); 57c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 58c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return GeneratePrologue() && 59c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org GenerateBody() && 60c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org GenerateDeferredCode() && 619ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org GenerateJumpTable() && 62c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org GenerateSafepointTable(); 63c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 64c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 65c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 66c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::FinishCode(Handle<Code> code) { 67e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_done()); 68160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org code->set_stack_slots(GetStackSlotCount()); 6983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); 70f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code); 71c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org PopulateDeoptimizationData(code); 72c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 73c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 74c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 75d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#ifdef _MSC_VER 76d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid LCodeGen::MakeSureStackPagesMapped(int offset) { 77d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org const int kPageSize = 4 * KB; 78d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org for (offset -= kPageSize; offset > 0; offset -= kPageSize) { 7943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rsp, offset), rax); 80d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 81d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 82d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#endif 83d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 84d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 85f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgvoid LCodeGen::SaveCallerDoubles() { 86e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->saves_caller_doubles()); 87e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(NeedsEagerFrame()); 88f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Comment(";;; Save clobbered callee double registers"); 89f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org int count = 0; 90f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org BitVector* doubles = chunk()->allocated_double_registers(); 91f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org BitVector::Iterator save_iterator(doubles); 92f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org while (!save_iterator.Done()) { 93f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org __ movsd(MemOperand(rsp, count * kDoubleSize), 94f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org XMMRegister::FromAllocationIndex(save_iterator.Current())); 95f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org save_iterator.Advance(); 96f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org count++; 97f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } 98f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org} 99f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 100f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 101f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgvoid LCodeGen::RestoreCallerDoubles() { 102e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->saves_caller_doubles()); 103e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(NeedsEagerFrame()); 104f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Comment(";;; Restore clobbered callee double registers"); 105f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org BitVector* doubles = chunk()->allocated_double_registers(); 106f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org BitVector::Iterator save_iterator(doubles); 107f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org int count = 0; 108f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org while (!save_iterator.Done()) { 109f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org __ movsd(XMMRegister::FromAllocationIndex(save_iterator.Current()), 110f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org MemOperand(rsp, count * kDoubleSize)); 111f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org save_iterator.Advance(); 112f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org count++; 113f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } 114f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org} 115f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 116f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 117c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgbool LCodeGen::GeneratePrologue() { 118e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_generating()); 119c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 120a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (info()->IsOptimizing()) { 121a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ProfileEntryHookStub::MaybeCallEntryHook(masm_); 122753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org 123c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#ifdef DEBUG 124a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (strlen(FLAG_stop_at) > 0 && 12559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 126a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ int3(); 127a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 128c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#endif 129c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 130486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org // Sloppy mode functions need to replace the receiver with the global proxy 131e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // when called as functions (without an explicit receiver object). 132e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org if (info_->this_has_uses() && 133486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org info_->strict_mode() == SLOPPY && 134e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org !info_->is_native()) { 135a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Label ok; 136d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StackArgumentsAccessor args(rsp, scope()->num_parameters()); 13743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, args.GetReceiverOperand()); 138e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 139e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex); 140e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ j(not_equal, &ok, Label::kNear); 141e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 14243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, GlobalObjectOperand()); 14358a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ movp(rcx, FieldOperand(rcx, GlobalObject::kGlobalProxyOffset)); 144e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 14543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(args.GetReceiverOperand(), rcx); 146e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 147a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ bind(&ok); 148a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 14940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } 15040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 15183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org info()->set_prologue_offset(masm_->pc_offset()); 152a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (NeedsEagerFrame()) { 153e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!frame_is_built_); 154a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org frame_is_built_ = true; 155285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org if (info()->IsStub()) { 156285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org __ StubPrologue(); 157285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org } else { 158285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org __ Prologue(info()->IsCodePreAgingActive()); 159285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org } 1604e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org info()->AddNoFrameRange(0, masm_->pc_offset()); 161a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 162c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 163c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Reserve space for the stack slots needed by the code. 164160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org int slots = GetStackSlotCount(); 165c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (slots > 0) { 166c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (FLAG_debug_code) { 167fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rsp, Immediate(slots * kPointerSize)); 168d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#ifdef _MSC_VER 169d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org MakeSureStackPagesMapped(slots * kPointerSize); 170d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#endif 171763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 172a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org __ Set(rax, slots); 17308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org __ Set(kScratchRegister, kSlotsZapValue); 174c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Label loop; 175c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org __ bind(&loop); 17643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(MemOperand(rsp, rax, times_pointer_size, 0), 17794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org kScratchRegister); 178c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org __ decl(rax); 179c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org __ j(not_zero, &loop); 180763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rax); 181c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else { 182fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rsp, Immediate(slots * kPointerSize)); 183c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#ifdef _MSC_VER 184d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org MakeSureStackPagesMapped(slots * kPointerSize); 185c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#endif 186c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 18794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 18894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (info()->saves_caller_doubles()) { 189f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org SaveCallerDoubles(); 19094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 191c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 192c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Possibly allocate a local context. 194a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 1953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (heap_slots > 0) { 1963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Comment(";;; Allocate local context"); 1977e6132b924829c353864933f29124419916db550machenbach@chromium.org bool need_write_barrier = true; 1983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Argument to NewContext is the function, which is still in rdi. 1993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (heap_slots <= FastNewContextStub::kMaximumSlots) { 200f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org FastNewContextStub stub(isolate(), heap_slots); 2013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ CallStub(&stub); 2027e6132b924829c353864933f29124419916db550machenbach@chromium.org // Result of FastNewContextStub is always in new space. 2037e6132b924829c353864933f29124419916db550machenbach@chromium.org need_write_barrier = false; 2043a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 205763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdi); 20647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kNewFunctionContext, 1); 2073a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 20827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(Safepoint::kNoLazyDeopt); 209bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org // Context is returned in rax. It replaces the context passed to us. 210bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org // It's saved in the stack and kept live in rsi. 211bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org __ movp(rsi, rax); 212bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rax); 2133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 2143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Copy any necessary parameters into the context. 2153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int num_parameters = scope()->num_parameters(); 2163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org for (int i = 0; i < num_parameters; i++) { 217486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Variable* var = scope()->parameter(i); 218486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (var->IsContextSlot()) { 2193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int parameter_offset = StandardFrameConstants::kCallerSPOffset + 2203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org (num_parameters - 1 - i) * kPointerSize; 2213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Load parameter from stack. 22243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, Operand(rbp, parameter_offset)); 2233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Store it in the context. 224486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org int context_offset = Context::SlotOffset(var->index()); 22543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rsi, context_offset), rax); 226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Update the write barrier. This clobbers rax and rbx. 2277e6132b924829c353864933f29124419916db550machenbach@chromium.org if (need_write_barrier) { 2287e6132b924829c353864933f29124419916db550machenbach@chromium.org __ RecordWriteContextSlot(rsi, context_offset, rax, rbx, kSaveFPRegs); 2297e6132b924829c353864933f29124419916db550machenbach@chromium.org } else if (FLAG_debug_code) { 2307e6132b924829c353864933f29124419916db550machenbach@chromium.org Label done; 2317e6132b924829c353864933f29124419916db550machenbach@chromium.org __ JumpIfInNewSpace(rsi, rax, &done, Label::kNear); 2327e6132b924829c353864933f29124419916db550machenbach@chromium.org __ Abort(kExpectedNewSpaceObject); 2337e6132b924829c353864933f29124419916db550machenbach@chromium.org __ bind(&done); 2347e6132b924829c353864933f29124419916db550machenbach@chromium.org } 2353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 2363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 2373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Comment(";;; End allocate local context"); 2383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 2393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 240c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Trace the call. 241a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (FLAG_trace && info()->IsOptimizing()) { 242c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org __ CallRuntime(Runtime::kTraceEnter, 0); 243c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 244c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return !is_aborted(); 245c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 246c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 247c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 248c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid LCodeGen::GenerateOsrPrologue() { 249c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Generate the OSR entry prologue at the first unknown OSR value, or if there 250c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // are none, at the OSR entrypoint instruction. 251c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org if (osr_pc_offset_ >= 0) return; 252c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 253c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org osr_pc_offset_ = masm()->pc_offset(); 254c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 255c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Adjust the frame size, subsuming the unoptimized frame into the 256c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // optimized frame. 257c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots(); 258e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(slots >= 0); 259fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rsp, Immediate(slots * kPointerSize)); 260c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 261c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 262c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 263486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.orgvoid LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) { 264fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (instr->IsCall()) { 265fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 266fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 267486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (!instr->IsLazyBailout() && !instr->IsGap()) { 268486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org safepoints_.BumpLastLazySafepointIndex(); 269486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } 270486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org} 271486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org 272486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org 273895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgvoid LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { 2742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (FLAG_debug_code && FLAG_enable_slow_asserts && instr->HasResult() && 2752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org instr->hydrogen_value()->representation().IsInteger32() && 2762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org instr->result()->IsRegister()) { 2772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ AssertZeroExtended(ToRegister(instr->result())); 2782ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 2792ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org 280895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org if (instr->HasResult() && instr->MustSignExtendResult(chunk())) { 2811845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // We sign extend the dehoisted key at the definition point when the pointer 2821845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // size is 64-bit. For x32 port, we sign extend the dehoisted key at the use 2831845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // points and MustSignExtendResult is always false. We can't use 2841845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // STATIC_ASSERT here as the pointer size is 32-bit for x32. 285e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kPointerSize == kInt64Size); 286895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org if (instr->result()->IsRegister()) { 287895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Register result_reg = ToRegister(instr->result()); 288895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ movsxlq(result_reg, result_reg); 289895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } else { 290895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // Sign extend the 32bit result in the stack slots. 291e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->result()->IsStackSlot()); 292895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Operand src = ToOperand(instr->result()); 293895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ movsxlq(kScratchRegister, src); 294895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ movq(src, kScratchRegister); 295895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 296895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 297895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org} 298895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 299895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 3009ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.orgbool LCodeGen::GenerateJumpTable() { 301169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Label needs_frame; 30232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (jump_table_.length() > 0) { 30332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; -------------------- Jump table --------------------"); 30432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org } 3059ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org for (int i = 0; i < jump_table_.length(); i++) { 306a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Deoptimizer::JumpTableEntry* table_entry = &jump_table_[i]; 307a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ bind(&table_entry->label); 308a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Address entry = table_entry->address; 30906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptComment(table_entry->reason); 310a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org if (table_entry->needs_frame) { 311e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->saves_caller_doubles()); 312e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Move(kScratchRegister, ExternalReference::ForDeoptEntry(entry)); 313169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (needs_frame.is_bound()) { 314169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ jmp(&needs_frame); 315a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 316169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ bind(&needs_frame); 31743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, MemOperand(rbp, StandardFrameConstants::kContextOffset)); 318763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbp); 31943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbp, rsp); 320763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); 321169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // This variant of deopt can only be used with stubs. Since we don't 322169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // have a function pointer to install in the stack frame that we're 323169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // building, install a special marker there instead. 324e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->IsStub()); 325169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ Move(rsi, Smi::FromInt(StackFrame::STUB)); 326763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); 32743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, MemOperand(rsp, kPointerSize)); 328169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ call(kScratchRegister); 329a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 330a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 331f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (info()->saves_caller_doubles()) { 332e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->IsStub()); 333f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org RestoreCallerDoubles(); 334f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } 335169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ call(entry, RelocInfo::RUNTIME_ENTRY); 336a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 3379ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 3389ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org return !is_aborted(); 3399ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org} 3409ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 3419ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 342c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgbool LCodeGen::GenerateDeferredCode() { 343e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_generating()); 344ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org if (deferred_.length() > 0) { 345ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 346ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org LDeferredCode* code = deferred_[i]; 347594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 34871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org HValue* value = 34971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org instructions_->at(code->instruction_index())->hydrogen_value(); 350f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org RecordAndWritePosition( 351f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org chunk()->graph()->SourcePositionToScriptPosition(value->position())); 352594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 35332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; <@%d,#%d> " 35432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org "-------------------- Deferred %s --------------------", 35532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org code->instruction_index(), 35632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org code->instr()->hydrogen_value()->id(), 35732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org code->instr()->Mnemonic()); 358ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org __ bind(code->entry()); 359a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (NeedsDeferredFrame()) { 36032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; Build frame"); 361e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!frame_is_built_); 362e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->IsStub()); 363a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org frame_is_built_ = true; 364a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Build the frame in such a way that esi isn't trashed. 365763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbp); // Caller's frame pointer. 366763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rbp, StandardFrameConstants::kContextOffset)); 367a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ Push(Smi::FromInt(StackFrame::STUB)); 368895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rbp, Operand(rsp, 2 * kPointerSize)); 36932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; Deferred code"); 370a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 371ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org code->Generate(); 372a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (NeedsDeferredFrame()) { 373c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ bind(code->done()); 37432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; Destroy frame"); 375e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(frame_is_built_); 376a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org frame_is_built_ = false; 37743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsp, rbp); 378763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbp); 379a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 380ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org __ jmp(code->exit()); 381ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org } 382c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 383c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 384c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Deferred code is the last part of the instruction sequence. Mark 385c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // the generated code as done unless we bailed out. 386c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (!is_aborted()) status_ = DONE; 387c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return !is_aborted(); 388c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 389c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 390c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 391c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgbool LCodeGen::GenerateSafepointTable() { 392e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_done()); 393160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org safepoints_.Emit(masm(), GetStackSlotCount()); 3940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return !is_aborted(); 395c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 396c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 397c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 398c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgRegister LCodeGen::ToRegister(int index) const { 399c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return Register::FromAllocationIndex(index); 400c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 401c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 402c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 403c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgXMMRegister LCodeGen::ToDoubleRegister(int index) const { 404c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return XMMRegister::FromAllocationIndex(index); 405c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 406c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 407c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 408c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgRegister LCodeGen::ToRegister(LOperand* op) const { 409e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(op->IsRegister()); 410c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return ToRegister(op->index()); 411c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 412c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 413c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 414c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgXMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const { 415e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(op->IsDoubleRegister()); 416c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return ToDoubleRegister(op->index()); 417c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 418c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 419c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 420c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgbool LCodeGen::IsInteger32Constant(LConstantOperand* op) const { 421a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); 422c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 423c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 424c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 425895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgbool LCodeGen::IsDehoistedKeyConstant(LConstantOperand* op) const { 426895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org return op->IsConstantOperand() && 427895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org chunk_->IsDehoistedKey(chunk_->LookupConstant(op)); 428895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org} 429895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 430895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 431a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgbool LCodeGen::IsSmiConstant(LConstantOperand* op) const { 432a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org return chunk_->LookupLiteralRepresentation(op).IsSmi(); 433c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 434c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 435c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 436fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgint32_t LCodeGen::ToInteger32(LConstantOperand* op) const { 43770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org return ToRepresentation(op, Representation::Integer32()); 43870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org} 43970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org 44070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org 44170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.orgint32_t LCodeGen::ToRepresentation(LConstantOperand* op, 44270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org const Representation& r) const { 443657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org HConstant* constant = chunk_->LookupConstant(op); 44470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org int32_t value = constant->Integer32Value(); 44570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (r.IsInteger32()) return value; 446e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(SmiValuesAre31Bits() && r.IsSmiOrTagged()); 44770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org return static_cast<int32_t>(reinterpret_cast<intptr_t>(Smi::FromInt(value))); 448c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 449c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 450c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 451c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgSmi* LCodeGen::ToSmi(LConstantOperand* op) const { 452c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org HConstant* constant = chunk_->LookupConstant(op); 453c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org return Smi::FromInt(constant->Integer32Value()); 454c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org} 455c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 456c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 457394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comdouble LCodeGen::ToDouble(LConstantOperand* op) const { 458657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org HConstant* constant = chunk_->LookupConstant(op); 459e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(constant->HasDoubleValue()); 460657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org return constant->DoubleValue(); 461394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 462394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 463394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 464d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgExternalReference LCodeGen::ToExternalReference(LConstantOperand* op) const { 465d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HConstant* constant = chunk_->LookupConstant(op); 466e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(constant->HasExternalReferenceValue()); 467d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return constant->ExternalReferenceValue(); 468d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 469d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 470d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 471c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgHandle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { 472657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org HConstant* constant = chunk_->LookupConstant(op); 473e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); 474639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org return constant->handle(isolate()); 475c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 476c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 477c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 478ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgstatic int ArgumentsOffsetWithoutFrame(int index) { 479e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index < 0); 480ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org return -(index + 1) * kPointerSize + kPCOnStackSize; 481ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org} 482ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 483ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 484c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgOperand LCodeGen::ToOperand(LOperand* op) const { 485c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Does not handle registers. In X64 assembler, plain registers are not 486c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // representable as an Operand. 487e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); 488ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (NeedsEagerFrame()) { 489ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org return Operand(rbp, StackSlotOffset(op->index())); 490ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } else { 491ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // Retrieve parameter without eager stack-frame relative to the 492ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // stack-pointer. 493ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org return Operand(rsp, ArgumentsOffsetWithoutFrame(op->index())); 494ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 495c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 496c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 497c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 498c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::WriteTranslation(LEnvironment* environment, 499b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Translation* translation) { 500c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (environment == NULL) return; 501c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 502c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // The translation includes one command per value in the environment. 503b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org int translation_size = environment->translation_size(); 504c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // The output frame height does not include the parameters. 505c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int height = translation_size - environment->parameter_count(); 506c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 507b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org WriteTranslation(environment->outer(), translation); 508a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool has_closure_id = !info()->closure().is_null() && 50932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org !info()->closure().is_identical_to(environment->closure()); 510a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int closure_id = has_closure_id 5115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ? DefineDeoptimizationLiteral(environment->closure()) 5125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org : Translation::kSelfLiteralId; 5135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 514967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org switch (environment->frame_type()) { 515967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org case JS_FUNCTION: 516967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org translation->BeginJSFrame(environment->ast_id(), closure_id, height); 517967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org break; 518967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org case JS_CONSTRUCT: 519967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org translation->BeginConstructStubFrame(closure_id, translation_size); 520967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org break; 521de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org case JS_GETTER: 522e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(translation_size == 1); 523e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(height == 0); 524de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org translation->BeginGetterStubFrame(closure_id); 525de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org break; 526471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org case JS_SETTER: 527e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(translation_size == 2); 528e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(height == 0); 52946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org translation->BeginSetterStubFrame(closure_id); 530471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org break; 531967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org case ARGUMENTS_ADAPTOR: 532967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); 533967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org break; 534a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case STUB: 535a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org translation->BeginCompiledStubFrame(); 536a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org break; 537659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 53856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 539594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int object_index = 0; 540594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int dematerialized_index = 0; 541c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = 0; i < translation_size; ++i) { 542c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LOperand* value = environment->values()->at(i); 543594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org AddToTranslation(environment, 544594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation, 54546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org value, 54646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org environment->HasTaggedValueAt(i), 547594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org environment->HasUint32ValueAt(i), 548594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org &object_index, 549594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org &dematerialized_index); 550c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 551c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 552c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 553c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 554594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::AddToTranslation(LEnvironment* environment, 555594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Translation* translation, 556c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LOperand* op, 55746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org bool is_tagged, 558594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org bool is_uint32, 559594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int* object_index_pointer, 560594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int* dematerialized_index_pointer) { 561594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (op == LEnvironment::materialization_marker()) { 562594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int object_index = (*object_index_pointer)++; 563594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (environment->ObjectIsDuplicateAt(object_index)) { 564594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int dupe_of = environment->ObjectDuplicateOfAt(object_index); 565594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation->DuplicateObject(dupe_of); 566594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return; 567594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 568594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int object_length = environment->ObjectLengthAt(object_index); 569594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (environment->ObjectIsArgumentsAt(object_index)) { 570594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation->BeginArgumentsObject(object_length); 571594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 572594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation->BeginCapturedObject(object_length); 573594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 574594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int dematerialized_index = *dematerialized_index_pointer; 575594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int env_offset = environment->translation_size() + dematerialized_index; 576594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org *dematerialized_index_pointer += object_length; 577594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org for (int i = 0; i < object_length; ++i) { 578594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org LOperand* value = environment->values()->at(env_offset + i); 579594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org AddToTranslation(environment, 580594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation, 581594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org value, 582594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org environment->HasTaggedValueAt(env_offset + i), 583594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org environment->HasUint32ValueAt(env_offset + i), 584594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org object_index_pointer, 585594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org dematerialized_index_pointer); 586594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 587594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return; 588594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 589594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 590b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (op->IsStackSlot()) { 591c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (is_tagged) { 592c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreStackSlot(op->index()); 59346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } else if (is_uint32) { 59446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org translation->StoreUint32StackSlot(op->index()); 595c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else { 596c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreInt32StackSlot(op->index()); 597c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 598c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else if (op->IsDoubleStackSlot()) { 599c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreDoubleStackSlot(op->index()); 600c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else if (op->IsRegister()) { 601c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Register reg = ToRegister(op); 602c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (is_tagged) { 603c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreRegister(reg); 60446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } else if (is_uint32) { 60546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org translation->StoreUint32Register(reg); 606c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else { 607c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreInt32Register(reg); 608c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 609c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else if (op->IsDoubleRegister()) { 610c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org XMMRegister reg = ToDoubleRegister(op); 611c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreDoubleRegister(reg); 612c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else if (op->IsConstantOperand()) { 613657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op)); 614639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org int src_index = DefineDeoptimizationLiteral(constant->handle(isolate())); 615c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreLiteral(src_index); 616c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else { 617c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org UNREACHABLE(); 618c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 619c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 620c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 621c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 62244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid LCodeGen::CallCodeGeneric(Handle<Code> code, 62344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org RelocInfo::Mode mode, 62444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org LInstruction* instr, 62544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org SafepointMode safepoint_mode, 62644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org int argc) { 627e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr != NULL); 62831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org __ call(code, mode); 62927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepointWithLazyDeopt(instr, safepoint_mode, argc); 6300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 6310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Signal that we don't inline smi code before these stubs in the 6320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // optimizing code generator. 63340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org if (code->kind() == Code::BINARY_OP_IC || 6340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com code->kind() == Code::COMPARE_IC) { 6350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __ nop(); 6360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 637c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 638c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 639c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 64044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid LCodeGen::CallCode(Handle<Code> code, 64144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org RelocInfo::Mode mode, 64244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org LInstruction* instr) { 64344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, 0); 64444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org} 64544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 64644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 647ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid LCodeGen::CallRuntime(const Runtime::Function* function, 648c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int num_arguments, 649fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org LInstruction* instr, 650fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org SaveFPRegsMode save_doubles) { 651e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr != NULL); 652e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->HasPointerMap()); 65383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 654fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ CallRuntime(function, num_arguments, save_doubles); 655fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org 65627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); 657c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 658c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 659c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 660935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgvoid LCodeGen::LoadContextFromDeferred(LOperand* context) { 661935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (context->IsRegister()) { 662935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (!ToRegister(context).is(rsi)) { 66343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, ToRegister(context)); 664935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } 665935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (context->IsStackSlot()) { 66643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, ToOperand(context)); 667935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (context->IsConstantOperand()) { 668935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org HConstant* constant = 669935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org chunk_->LookupConstant(LConstantOperand::cast(context)); 670935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ Move(rsi, Handle<Object>::cast(constant->handle(isolate()))); 671935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else { 672935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org UNREACHABLE(); 673935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } 674935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org} 675935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 676935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 677935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 67844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 67944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org int argc, 680935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org LInstruction* instr, 681935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org LOperand* context) { 682935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org LoadContextFromDeferred(context); 683935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 68444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org __ CallRuntimeSaveDoubles(id); 68544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org RecordSafepointWithRegisters( 68627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org instr->pointer_map(), argc, Safepoint::kNoLazyDeopt); 687c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 688c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 689c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 69027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, 69127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode mode) { 6924edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org environment->set_has_been_used(); 6930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (!environment->HasBeenRegistered()) { 6940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Physical stack frame layout: 6950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // -x ............. -4 0 ..................................... y 6960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // [incoming arguments] [spill slots] [pushed outgoing arguments] 6970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 6980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Layout of the environment: 6990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // 0 ..................................................... size-1 7000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // [parameters] [locals] [expression stack including arguments] 7010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Layout of the translation: 7030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // 0 ........................................................ size - 1 + 4 7040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // [expression stack including arguments] [locals] [4 words] [parameters] 7050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // |>------------ translation_size ------------<| 7060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com int frame_count = 0; 708659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org int jsframe_count = 0; 7090511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com for (LEnvironment* e = environment; e != NULL; e = e->outer()) { 7100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ++frame_count; 711967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org if (e->frame_type() == JS_FUNCTION) { 712659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org ++jsframe_count; 713659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 7140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 71556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Translation translation(&translations_, frame_count, jsframe_count, zone()); 716b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org WriteTranslation(environment, &translation); 7170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com int deoptimization_index = deoptimizations_.length(); 71827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org int pc_offset = masm()->pc_offset(); 71927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org environment->Register(deoptimization_index, 72027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org translation.index(), 72127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 722400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org deoptimizations_.Add(environment, environment->zone()); 7230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 724c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 725c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 726c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 727a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgvoid LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr, 72806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail, 729aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org Deoptimizer::BailoutType bailout_type) { 730a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org LEnvironment* environment = instr->environment(); 73127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 732e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(environment->HasBeenRegistered()); 7330ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org int id = environment->deoptimization_index(); 734e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->IsOptimizing() || info()->IsStub()); 7358432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Address entry = 7368432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); 7370ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (entry == NULL) { 738594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kBailoutWasNotPrepared); 7390ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org return; 7400ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 7410ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 742935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (DeoptEveryNTimes()) { 743e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ExternalReference count = ExternalReference::stress_deopt_count(isolate()); 744e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label no_deopt; 745e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ pushfq(); 74608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org __ pushq(rax); 747e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Operand count_operand = masm()->ExternalOperand(count, kScratchRegister); 748e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movl(rax, count_operand); 749e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ subl(rax, Immediate(1)); 750e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ j(not_zero, &no_deopt, Label::kNear); 751e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (FLAG_trap_on_deopt) __ int3(); 752e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movl(rax, Immediate(FLAG_deopt_every_n_times)); 753e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movl(count_operand, rax); 75408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org __ popq(rax); 755e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ popfq(); 756e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(frame_is_built_); 757e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ call(entry, RelocInfo::RUNTIME_ENTRY); 758e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ bind(&no_deopt); 759e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movl(count_operand, rax); 76008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org __ popq(rax); 761e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ popfq(); 762e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 7637c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 764594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (info()->ShouldTrapOnDeopt()) { 7657c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Label done; 7667c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (cc != no_condition) { 7677c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ j(NegateCondition(cc), &done, Label::kNear); 7687c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 7697c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ int3(); 7707c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ bind(&done); 7717c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 7727c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 77306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Deoptimizer::Reason reason(instr->hydrogen_value()->position().raw(), 77406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org instr->Mnemonic(), detail); 775e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->IsStub() || frame_is_built_); 776f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Go through jump table if we need to handle condition, build frame, or 777f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // restore caller doubles. 778f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (cc == no_condition && frame_is_built_ && 779f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !info()->saves_caller_doubles()) { 78006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptComment(reason); 781169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ call(entry, RelocInfo::RUNTIME_ENTRY); 7820ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else { 78306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Deoptimizer::JumpTableEntry table_entry(entry, reason, bailout_type, 78406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org !frame_is_built_); 7859ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // We often have several deopts to the same entry, reuse the last 7869ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // jump entry if this is the case. 787eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org if (jump_table_.is_empty() || 78806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org !table_entry.IsEquivalentTo(jump_table_.last())) { 789a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org jump_table_.Add(table_entry, zone()); 7909ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 7917c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (cc == no_condition) { 7927c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ jmp(&jump_table_.last().label); 7937c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } else { 7947c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ j(cc, &jump_table_.last().label); 7957c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 7960ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 797c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 798c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 799c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 800a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgvoid LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr, 80106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail) { 802aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org Deoptimizer::BailoutType bailout_type = info()->IsStub() 803aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org ? Deoptimizer::LAZY 804aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org : Deoptimizer::EAGER; 80506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(cc, instr, detail, bailout_type); 806aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org} 807aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org 808aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org 809c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 810c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int length = deoptimizations_.length(); 811c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (length == 0) return; 812c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Handle<DeoptimizationInputData> data = 8136474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org DeoptimizationInputData::New(isolate(), length, TENURED); 814c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 815876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org Handle<ByteArray> translations = 816876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org translations_.CreateByteArray(isolate()->factory()); 8179ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org data->SetTranslationByteArray(*translations); 818c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); 819f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org data->SetOptimizationId(Smi::FromInt(info_->optimization_id())); 820f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (info_->IsOptimizing()) { 821f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Reference to shared function info does not change between phases. 822f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org AllowDeferredHandleDereference allow_handle_dereference; 823f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org data->SetSharedFunctionInfo(*info_->shared_info()); 824f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 825f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org data->SetSharedFunctionInfo(Smi::FromInt(0)); 826f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 827c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 828c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Handle<FixedArray> literals = 829ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); 83079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org { AllowDeferredHandleDereference copy_handles; 83132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org for (int i = 0; i < deoptimization_literals_.length(); i++) { 83232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org literals->set(i, *deoptimization_literals_[i]); 83332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org } 83432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org data->SetLiteralArray(*literals); 835c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 836c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 837471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); 838c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); 839c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 840c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Populate the deoptimization entries. 841c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = 0; i < length; i++) { 842c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LEnvironment* env = deoptimizations_[i]; 843471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org data->SetAstId(i, env->ast_id()); 844c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); 845c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data->SetArgumentsStackHeight(i, 846c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Smi::FromInt(env->arguments_stack_height())); 84727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org data->SetPc(i, Smi::FromInt(env->pc_offset())); 848c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 849c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org code->set_deoptimization_data(*data); 850c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 851c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 852c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 853c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgint LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) { 854c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int result = deoptimization_literals_.length(); 855c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = 0; i < deoptimization_literals_.length(); ++i) { 856c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (deoptimization_literals_[i].is_identical_to(literal)) return i; 857c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 8587028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org deoptimization_literals_.Add(literal, zone()); 859c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return result; 860c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 861c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 862c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 863c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() { 864e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(deoptimization_literals_.length() == 0); 865c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 866c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org const ZoneList<Handle<JSFunction> >* inlined_closures = 867c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org chunk()->inlined_closures(); 868c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 869c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = 0, length = inlined_closures->length(); 870c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org i < length; 871c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org i++) { 872c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org DefineDeoptimizationLiteral(inlined_closures->at(i)); 873c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 874c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 875c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org inlined_function_count_ = deoptimization_literals_.length(); 876c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 877c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 878c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 87927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::RecordSafepointWithLazyDeopt( 88027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org LInstruction* instr, SafepointMode safepoint_mode, int argc) { 88127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { 88227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt); 88327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } else { 884e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS); 88527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepointWithRegisters( 88627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org instr->pointer_map(), argc, Safepoint::kLazyDeopt); 88727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } 88827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org} 88927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org 89027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org 891378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid LCodeGen::RecordSafepoint( 892378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org LPointerMap* pointers, 893378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Safepoint::Kind kind, 894378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org int arguments, 89527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode deopt_mode) { 896e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kind == expected_safepoint_kind_); 89744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 898c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com const ZoneList<LOperand*>* operands = pointers->GetNormalizedOperands(); 89983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 900c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Safepoint safepoint = safepoints_.DefineSafepoint(masm(), 90127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org kind, arguments, deopt_mode); 902c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = 0; i < operands->length(); i++) { 903c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LOperand* pointer = operands->at(i); 904c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (pointer->IsStackSlot()) { 905400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org safepoint.DefinePointerSlot(pointer->index(), zone()); 906378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { 9077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org safepoint.DefinePointerRegister(ToRegister(pointer), zone()); 908c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 909c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 910378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org} 911378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 912378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 913378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid LCodeGen::RecordSafepoint(LPointerMap* pointers, 91427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode deopt_mode) { 91527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode); 916c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 917c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 918c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 91927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) { 92071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org LPointerMap empty_pointers(zone()); 92127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(&empty_pointers, deopt_mode); 9223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 9233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 9243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 925c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, 926c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int arguments, 92727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode deopt_mode) { 92827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, deopt_mode); 929c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 930c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 931c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 93271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.orgvoid LCodeGen::RecordAndWritePosition(int position) { 9336d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org if (position == RelocInfo::kNoPosition) return; 934c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org masm()->positions_recorder()->RecordPosition(position); 93571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org masm()->positions_recorder()->WriteRecordedPositions(); 936594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 937594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 938594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 93932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.orgstatic const char* LabelType(LLabel* label) { 94032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (label->is_loop_header()) return " (loop header)"; 94132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (label->is_osr_entry()) return " (OSR entry)"; 94232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org return ""; 94332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org} 94432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org 94532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org 946c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLabel(LLabel* label) { 94732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", 94832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org current_instruction_, 94932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org label->hydrogen_value()->id(), 950b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org label->block_id(), 95132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org LabelType(label)); 952c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org __ bind(label->label()); 953c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org current_block_ = label->block_id(); 9548e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org DoGap(label); 955c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 956c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 957c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 958c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoParallelMove(LParallelMove* move) { 9590ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org resolver_.Resolve(move); 960c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 961c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 962c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 963c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoGap(LGap* gap) { 964c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = LGap::FIRST_INNER_POSITION; 965c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org i <= LGap::LAST_INNER_POSITION; 966c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org i++) { 967c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LGap::InnerPosition inner_pos = static_cast<LGap::InnerPosition>(i); 968c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LParallelMove* move = gap->GetParallelMove(inner_pos); 969c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (move != NULL) DoParallelMove(move); 970c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 971c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 972c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 973c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 9748e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid LCodeGen::DoInstructionGap(LInstructionGap* instr) { 9758e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org DoGap(instr); 9768e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org} 9778e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org 9788e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org 979c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoParameter(LParameter* instr) { 980c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Nothing to do. 981c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 982c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 983c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 984c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCallStub(LCallStub* instr) { 985e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 986e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rax)); 987d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com switch (instr->hydrogen()->major_key()) { 988d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com case CodeStub::RegExpExec: { 989f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org RegExpExecStub stub(isolate()); 990f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 991d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com break; 992d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 993d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com case CodeStub::SubString: { 994f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org SubStringStub stub(isolate()); 995f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 996d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com break; 997d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 998d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com case CodeStub::StringCompare: { 999f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org StringCompareStub stub(isolate()); 1000f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1001d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com break; 1002d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1003d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com default: 1004d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com UNREACHABLE(); 1005d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1006c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1007c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1008c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1009c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 1010c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org GenerateOsrPrologue(); 1011c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1012c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1013c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1014ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) { 1015ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1016ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t divisor = instr->divisor(); 1017e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(dividend.is(ToRegister(instr->result()))); 1018ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1019ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Theoretically, a variation of the branch-free code for integer division by 1020ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // a power of 2 (calculating the remainder via an additional multiplication 1021ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // (which gets simplified to an 'and') and subtraction) should be faster, and 1022ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // this is exactly what GCC and clang emit. Nevertheless, benchmarks seem to 1023ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // indicate that positive dividends are heavily favored, so the branching 1024ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // version performs better. 1025ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org HMod* hmod = instr->hydrogen(); 1026ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1027ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Label dividend_is_not_negative, done; 1028381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) { 1029ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(dividend, dividend); 1030ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ j(not_sign, ÷nd_is_not_negative, Label::kNear); 1031ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Note that this is correct even for kMinInt operands. 1032ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ negl(dividend); 1033ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ andl(dividend, Immediate(mask)); 1034ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ negl(dividend); 1035ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 103606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "minus zero"); 1037ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1038ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ jmp(&done, Label::kNear); 1039ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1040ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1041ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(÷nd_is_not_negative); 1042ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ andl(dividend, Immediate(mask)); 1043ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(&done); 1044ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org} 1045ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1046ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1047bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgvoid LCodeGen::DoModByConstI(LModByConstI* instr) { 1048bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1049bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org int32_t divisor = instr->divisor(); 1050e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rax)); 1051bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1052bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (divisor == 0) { 105306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(no_condition, instr, "division by zero"); 1054bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org return; 1055bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 1056bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1057763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ TruncatingDiv(dividend, Abs(divisor)); 1058bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ imull(rdx, rdx, Immediate(Abs(divisor))); 1059bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ movl(rax, dividend); 1060bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ subl(rax, rdx); 1061bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1062bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // Check for negative zero. 1063bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HMod* hmod = instr->hydrogen(); 1064486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1065bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org Label remainder_not_zero; 1066bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ j(not_zero, &remainder_not_zero, Label::kNear); 1067bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ cmpl(dividend, Immediate(0)); 106806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(less, instr, "minus zero"); 1069bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ bind(&remainder_not_zero); 1070bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 1071bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org} 1072bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1073bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1074c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoModI(LModI* instr) { 10758a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org HMod* hmod = instr->hydrogen(); 10768a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org 1077ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register left_reg = ToRegister(instr->left()); 1078e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left_reg.is(rax)); 1079ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register right_reg = ToRegister(instr->right()); 1080e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!right_reg.is(rax)); 1081e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!right_reg.is(rdx)); 1082ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register result_reg = ToRegister(instr->result()); 1083e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result_reg.is(rdx)); 10843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1085ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Label done; 1086ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Check for x % 0, idiv would signal a divide error. We have to 1087ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // deopt in this case because we can't return a NaN. 1088486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { 1089ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(right_reg, right_reg); 109006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "division by zero"); 1091ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1092a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1093ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Check for kMinInt % -1, idiv would signal a divide error. We 1094ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // have to deopt if we care about -0, because we can't return that. 1095486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hmod->CheckFlag(HValue::kCanOverflow)) { 1096ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Label no_overflow_possible; 1097ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ cmpl(left_reg, Immediate(kMinInt)); 1098ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ j(not_zero, &no_overflow_possible, Label::kNear); 1099ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ cmpl(right_reg, Immediate(-1)); 1100ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 110106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(equal, instr, "minus zero"); 1102ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } else { 1103ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ j(not_equal, &no_overflow_possible, Label::kNear); 1104ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ Set(result_reg, 0); 11058a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ jmp(&done, Label::kNear); 1106b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org } 1107ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(&no_overflow_possible); 1108ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1109ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1110ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Sign extend dividend in eax into edx:eax, since we are using only the low 1111ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // 32 bits of the values. 1112ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ cdq(); 1113ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1114ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // If we care about -0, test if the dividend is <0 and the result is 0. 1115486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1116ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Label positive_left; 1117ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(left_reg, left_reg); 1118ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ j(not_sign, &positive_left, Label::kNear); 11198a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ idivl(right_reg); 1120ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(result_reg, result_reg); 112106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "minus zero"); 1122ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ jmp(&done, Label::kNear); 1123ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(&positive_left); 11243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 1125ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ idivl(right_reg); 1126ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(&done); 1127c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1128c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1129c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1130ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { 1131ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1132ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t divisor = instr->divisor(); 1133e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(dividend.is(ToRegister(instr->result()))); 1134d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1135ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // If the divisor is positive, things are easy: There can be no deopts and we 1136ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // can simply do an arithmetic right shift. 1137ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (divisor == 1) return; 1138ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t shift = WhichPowerOf2Abs(divisor); 1139ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (divisor > 1) { 1140ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ sarl(dividend, Immediate(shift)); 1141d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org return; 1142ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1143d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1144ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // If the divisor is negative, we have to negate and handle edge cases. 1145ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ negl(dividend); 1146ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 114706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "minus zero"); 1148ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 11499e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org 11508ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org // Dividing by -1 is basically negation, unless we overflow. 11518ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org if (divisor == -1) { 11528ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 115306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 11548ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org } 11559e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org return; 11569e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org } 11579e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org 11588ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org // If the negation could not overflow, simply shifting is OK. 11598ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 11608ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org __ sarl(dividend, Immediate(shift)); 11619e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org return; 1162ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 11639e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org 11649e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org Label not_kmin_int, done; 11659e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org __ j(no_overflow, ¬_kmin_int, Label::kNear); 11669e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org __ movl(dividend, Immediate(kMinInt / divisor)); 11679e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org __ jmp(&done, Label::kNear); 1168ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(¬_kmin_int); 1169ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ sarl(dividend, Immediate(shift)); 1170ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(&done); 1171ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org} 1172d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1173ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1174ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { 1175ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1176ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t divisor = instr->divisor(); 1177e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rdx)); 1178ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1179ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (divisor == 0) { 118006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(no_condition, instr, "division by zero"); 1181d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org return; 1182d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1183d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1184bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // Check for (0 / -x) that will produce negative zero. 1185bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HMathFloorOfDiv* hdiv = instr->hydrogen(); 1186486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1187bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ testl(dividend, dividend); 118806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "minus zero"); 1189d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1190ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 11917010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org // Easy case: We need no dynamic check for the dividend and the flooring 11927010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org // division is the same as the truncating division. 11937010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) || 11947010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) { 11957010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ TruncatingDiv(dividend, Abs(divisor)); 11967010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org if (divisor < 0) __ negl(rdx); 11977010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org return; 11987010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org } 11997010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org 12007010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org // In the general case we may need to adjust before and after the truncating 12017010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org // division to get a flooring division. 12027010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Register temp = ToRegister(instr->temp3()); 1203e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!temp.is(dividend) && !temp.is(rax) && !temp.is(rdx)); 12047010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Label needs_adjustment, done; 12057010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ cmpl(dividend, Immediate(0)); 12067010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ j(divisor > 0 ? less : greater, &needs_adjustment, Label::kNear); 12077010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ TruncatingDiv(dividend, Abs(divisor)); 12087010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org if (divisor < 0) __ negl(rdx); 12097010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ jmp(&done, Label::kNear); 12107010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ bind(&needs_adjustment); 12117010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ leal(temp, Operand(dividend, divisor > 0 ? 1 : -1)); 12127010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ TruncatingDiv(temp, Abs(divisor)); 12137010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org if (divisor < 0) __ negl(rdx); 12147010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ decl(rdx); 12157010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ bind(&done); 1216d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org} 1217d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1218d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1219ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI. 1220ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.orgvoid LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { 1221ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org HBinaryOperation* hdiv = instr->hydrogen(); 1222ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1223ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Register divisor = ToRegister(instr->divisor()); 1224ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Register remainder = ToRegister(instr->temp()); 1225ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Register result = ToRegister(instr->result()); 1226e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(dividend.is(rax)); 1227e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(remainder.is(rdx)); 1228e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result.is(rax)); 1229e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!divisor.is(rax)); 1230e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!divisor.is(rdx)); 1231ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1232ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org // Check for x / 0. 1233ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1234ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ testl(divisor, divisor); 123506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "division by zero"); 1236ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org } 1237ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1238ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org // Check for (0 / -x) that will produce negative zero. 1239ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1240ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Label dividend_not_zero; 1241ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ testl(dividend, dividend); 1242ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ j(not_zero, ÷nd_not_zero, Label::kNear); 1243ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ testl(divisor, divisor); 124406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(sign, instr, "minus zero"); 1245ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ bind(÷nd_not_zero); 1246ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org } 1247ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1248ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org // Check for (kMinInt / -1). 1249ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org if (hdiv->CheckFlag(HValue::kCanOverflow)) { 1250ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Label dividend_not_min_int; 1251ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ cmpl(dividend, Immediate(kMinInt)); 1252ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ j(not_zero, ÷nd_not_min_int, Label::kNear); 1253ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ cmpl(divisor, Immediate(-1)); 125406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "overflow"); 1255ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ bind(÷nd_not_min_int); 1256ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org } 1257ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1258ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org // Sign extend to rdx (= remainder). 1259ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ cdq(); 1260ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ idivl(divisor); 1261ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1262ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Label done; 1263ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ testl(remainder, remainder); 1264ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ j(zero, &done, Label::kNear); 1265ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ xorl(remainder, divisor); 1266ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ sarl(remainder, Immediate(31)); 1267ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ addl(result, remainder); 1268ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ bind(&done); 1269ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org} 1270ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1271ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1272ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { 1273ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1274ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t divisor = instr->divisor(); 1275ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register result = ToRegister(instr->result()); 127621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor))); 1277e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!result.is(dividend)); 1278052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org 1279ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Check for (0 / -x) that will produce negative zero. 1280ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org HDiv* hdiv = instr->hydrogen(); 1281486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1282ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(dividend, dividend); 128306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "minus zero"); 1284ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1285ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Check for (kMinInt / -1). 1286486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { 1287ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ cmpl(dividend, Immediate(kMinInt)); 128806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "overflow"); 1289ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1290ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Deoptimize if remainder will not be 0. 1291ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && 1292ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org divisor != 1 && divisor != -1) { 1293ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1294ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(dividend, Immediate(mask)); 129506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_zero, instr, "lost precision"); 12965323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org } 1297ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ Move(result, dividend); 1298ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t shift = WhichPowerOf2Abs(divisor); 1299ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (shift > 0) { 1300ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // The arithmetic shift is always OK, the 'if' is an optimization only. 1301ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (shift > 1) __ sarl(result, Immediate(31)); 1302ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ shrl(result, Immediate(32 - shift)); 1303ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ addl(result, dividend); 1304ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ sarl(result, Immediate(shift)); 1305ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1306ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (divisor < 0) __ negl(result); 1307ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org} 13085323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org 1309d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1310bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgvoid LCodeGen::DoDivByConstI(LDivByConstI* instr) { 1311bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1312bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org int32_t divisor = instr->divisor(); 1313e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rdx)); 1314bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1315bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (divisor == 0) { 131606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(no_condition, instr, "division by zero"); 1317bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org return; 1318bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 1319bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1320bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // Check for (0 / -x) that will produce negative zero. 1321bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HDiv* hdiv = instr->hydrogen(); 1322486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1323bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ testl(dividend, dividend); 132406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "minus zero"); 1325bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 1326bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1327763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ TruncatingDiv(dividend, Abs(divisor)); 13282ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (divisor < 0) __ negl(rdx); 1329bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1330bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { 1331bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ movl(rax, rdx); 1332bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ imull(rax, rax, Immediate(divisor)); 1333bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ subl(rax, dividend); 133406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "lost precision"); 1335bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 1336bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org} 1337bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1338bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1339ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI. 1340ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoDivI(LDivI* instr) { 1341486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org HBinaryOperation* hdiv = instr->hydrogen(); 1342ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1343ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Register divisor = ToRegister(instr->divisor()); 1344ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register remainder = ToRegister(instr->temp()); 1345e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(dividend.is(rax)); 1346e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(remainder.is(rdx)); 1347e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rax)); 1348e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!divisor.is(rax)); 1349e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!divisor.is(rdx)); 1350d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1351d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Check for x / 0. 1352ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1353ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(divisor, divisor); 135406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "division by zero"); 1355d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1356d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1357d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Check for (0 / -x) that will produce negative zero. 1358ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1359ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Label dividend_not_zero; 1360ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(dividend, dividend); 1361ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ j(not_zero, ÷nd_not_zero, Label::kNear); 1362ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(divisor, divisor); 136306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(sign, instr, "minus zero"); 1364ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(÷nd_not_zero); 1365d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1366d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 13675323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org // Check for (kMinInt / -1). 1368ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (hdiv->CheckFlag(HValue::kCanOverflow)) { 1369ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Label dividend_not_min_int; 1370ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ cmpl(dividend, Immediate(kMinInt)); 1371ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ j(not_zero, ÷nd_not_min_int, Label::kNear); 1372ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ cmpl(divisor, Immediate(-1)); 137306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "overflow"); 1374ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(÷nd_not_min_int); 1375d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1376d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1377ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Sign extend to rdx (= remainder). 1378d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ cdq(); 1379ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ idivl(divisor); 1380d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1381ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { 1382837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org // Deoptimize if remainder is not 0. 1383ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(remainder, remainder); 138406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_zero, instr, "lost precision"); 13854cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 1386d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com} 1387c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1388c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1389c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoMulI(LMulI* instr) { 139056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register left = ToRegister(instr->left()); 139156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 1392d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1393d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1394662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 139543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(kScratchRegister, left); 1396662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } else { 1397662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movl(kScratchRegister, left); 1398662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } 1399d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1400d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1401ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org bool can_overflow = 1402ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1403d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (right->IsConstantOperand()) { 1404594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int32_t right_value = ToInteger32(LConstantOperand::cast(right)); 1405ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (right_value == -1) { 1406ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ negl(left); 1407ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else if (right_value == 0) { 1408ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ xorl(left, left); 1409ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else if (right_value == 2) { 1410ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ addl(left, left); 1411ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else if (!can_overflow) { 1412ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // If the multiplication is known to not overflow, we 1413ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // can use operations that don't set the overflow flag 1414ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // correctly. 1415ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org switch (right_value) { 1416ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 1: 1417ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Do nothing. 1418ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1419ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 3: 1420ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ leal(left, Operand(left, left, times_2, 0)); 1421ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1422ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 4: 1423ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ shll(left, Immediate(2)); 1424ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1425ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 5: 1426ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ leal(left, Operand(left, left, times_4, 0)); 1427ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1428ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 8: 1429ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ shll(left, Immediate(3)); 1430ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1431ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 9: 1432ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ leal(left, Operand(left, left, times_8, 0)); 1433ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1434ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 16: 1435ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ shll(left, Immediate(4)); 1436ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1437ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org default: 1438ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ imull(left, left, Immediate(right_value)); 1439ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1440ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 1441ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else { 1442ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ imull(left, left, Immediate(right_value)); 1443ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 1444d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else if (right->IsStackSlot()) { 1445fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 1446662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ SmiToInteger64(left, left); 1447fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ imulp(left, ToOperand(right)); 1448fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1449fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ imull(left, ToOperand(right)); 1450fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 1451d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else { 1452fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 1453662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ SmiToInteger64(left, left); 1454fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ imulp(left, ToRegister(right)); 1455fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1456fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ imull(left, ToRegister(right)); 1457fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 1458d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1459d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1460ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (can_overflow) { 146106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 1462d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1463d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1464d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1465d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Bail out if the result is supposed to be negative zero. 146683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 1467662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 14687a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(left, left); 1469662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } else { 1470662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ testl(left, left); 1471662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } 147283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_zero, &done, Label::kNear); 1473d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (right->IsConstantOperand()) { 147470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Constant can't be represented as 32-bit Smi due to immediate size 147570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // limit. 1476e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(SmiValuesAre32Bits() 147770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ? !instr->hydrogen_value()->representation().IsSmi() 147870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org : SmiValuesAre31Bits()); 147933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (ToInteger32(LConstantOperand::cast(right)) < 0) { 148006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(no_condition, instr, "minus zero"); 148133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } else if (ToInteger32(LConstantOperand::cast(right)) == 0) { 148233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org __ cmpl(kScratchRegister, Immediate(0)); 148306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(less, instr, "minus zero"); 1484d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1485d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else if (right->IsStackSlot()) { 1486662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 1487895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ orp(kScratchRegister, ToOperand(right)); 1488662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } else { 1489662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ orl(kScratchRegister, ToOperand(right)); 1490662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } 149106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(sign, instr, "minus zero"); 1492d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else { 1493d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Test the non-zero operand for negative sign. 1494662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 1495895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ orp(kScratchRegister, ToRegister(right)); 1496662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } else { 1497662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ orl(kScratchRegister, ToRegister(right)); 1498662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } 149906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(sign, instr, "minus zero"); 1500d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1501d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ bind(&done); 1502d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1503d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com} 1504c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1505c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1506c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoBitI(LBitI* instr) { 150756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 150856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 1509e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left->Equals(instr->result())); 1510e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left->IsRegister()); 151183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 151283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (right->IsConstantOperand()) { 151370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org int32_t right_operand = 151470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ToRepresentation(LConstantOperand::cast(right), 151570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->right()->representation()); 151683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org switch (instr->op()) { 151783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_AND: 151883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ andl(ToRegister(left), Immediate(right_operand)); 151983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 152083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_OR: 152183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ orl(ToRegister(left), Immediate(right_operand)); 152283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 152383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_XOR: 1524594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (right_operand == int32_t(~0)) { 1525639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org __ notl(ToRegister(left)); 1526594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 1527594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ xorl(ToRegister(left), Immediate(right_operand)); 1528594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 152983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 153083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org default: 153183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org UNREACHABLE(); 153283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 153383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 153483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else if (right->IsStackSlot()) { 153583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org switch (instr->op()) { 153683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_AND: 15372ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->IsInteger32()) { 15382ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ andl(ToRegister(left), ToOperand(right)); 15392ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 15402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ andp(ToRegister(left), ToOperand(right)); 15412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 154283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 154383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_OR: 15442ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->IsInteger32()) { 15452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ orl(ToRegister(left), ToOperand(right)); 15462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 15472ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ orp(ToRegister(left), ToOperand(right)); 15482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 154983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 155083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_XOR: 15512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->IsInteger32()) { 15522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ xorl(ToRegister(left), ToOperand(right)); 15532ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 15542ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ xorp(ToRegister(left), ToOperand(right)); 15552ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 155683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 155783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org default: 155883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org UNREACHABLE(); 155983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 156083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 156183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 1562e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(right->IsRegister()); 156383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org switch (instr->op()) { 156483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_AND: 15652ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->IsInteger32()) { 15662ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ andl(ToRegister(left), ToRegister(right)); 15672ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 15682ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ andp(ToRegister(left), ToRegister(right)); 15692ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 157083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 157183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_OR: 15722ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->IsInteger32()) { 15732ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ orl(ToRegister(left), ToRegister(right)); 15742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 15752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ orp(ToRegister(left), ToRegister(right)); 15762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 157783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 157883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_XOR: 15792ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->IsInteger32()) { 15802ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ xorl(ToRegister(left), ToRegister(right)); 15812ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 15822ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ xorp(ToRegister(left), ToRegister(right)); 15832ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 158483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 158583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org default: 158683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org UNREACHABLE(); 158783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 158883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 158983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 159083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org} 1591c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1592c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1593c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoShiftI(LShiftI* instr) { 159456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 159556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 1596e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left->Equals(instr->result())); 1597e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left->IsRegister()); 159883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (right->IsRegister()) { 1599e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(right).is(rcx)); 160083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 160183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org switch (instr->op()) { 1602e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case Token::ROR: 1603e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ rorl_cl(ToRegister(left)); 1604e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 160583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::SAR: 160683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ sarl_cl(ToRegister(left)); 160783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 160883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::SHR: 160983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ shrl_cl(ToRegister(left)); 161083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (instr->can_deopt()) { 161183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ testl(ToRegister(left), ToRegister(left)); 161206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(negative, instr, "negative value"); 161383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 161483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 161583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::SHL: 161683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ shll_cl(ToRegister(left)); 161783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 161883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org default: 161983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org UNREACHABLE(); 162083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 162183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 162283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 1623594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int32_t value = ToInteger32(LConstantOperand::cast(right)); 162483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); 162583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org switch (instr->op()) { 1626e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case Token::ROR: 1627e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (shift_count != 0) { 1628e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ rorl(ToRegister(left), Immediate(shift_count)); 1629e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 1630e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 163183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::SAR: 163283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (shift_count != 0) { 163383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ sarl(ToRegister(left), Immediate(shift_count)); 163483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 163583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 163683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::SHR: 163754ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org if (shift_count != 0) { 163854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org __ shrl(ToRegister(left), Immediate(shift_count)); 163954ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org } else if (instr->can_deopt()) { 164083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ testl(ToRegister(left), ToRegister(left)); 164106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(negative, instr, "negative value"); 164283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 164383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 164483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::SHL: 164583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (shift_count != 0) { 1646d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 164770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (SmiValuesAre32Bits()) { 164870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ shlp(ToRegister(left), Immediate(shift_count)); 164970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } else { 1650e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(SmiValuesAre31Bits()); 165170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (instr->can_deopt()) { 165270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (shift_count != 1) { 165370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ shll(ToRegister(left), Immediate(shift_count - 1)); 165470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 165570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ Integer32ToSmi(ToRegister(left), ToRegister(left)); 165606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 165770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } else { 165870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ shll(ToRegister(left), Immediate(shift_count)); 165970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 166070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 1661d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 1662d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ shll(ToRegister(left), Immediate(shift_count)); 1663d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 166483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 166583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 166683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org default: 166783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org UNREACHABLE(); 166883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 166983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 167083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 1671c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1672c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1673c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1674c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoSubI(LSubI* instr) { 167556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 167656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 1677e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left->Equals(instr->result())); 16780ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 16790ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (right->IsConstantOperand()) { 168070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org int32_t right_operand = 168170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ToRepresentation(LConstantOperand::cast(right), 168270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->right()->representation()); 168370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ subl(ToRegister(left), Immediate(right_operand)); 16840ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else if (right->IsRegister()) { 1685fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 1686fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(ToRegister(left), ToRegister(right)); 1687fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1688fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ subl(ToRegister(left), ToRegister(right)); 1689fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 16900ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else { 1691fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 1692fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(ToRegister(left), ToOperand(right)); 1693fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1694fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ subl(ToRegister(left), ToOperand(right)); 1695fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 16960ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 16970ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 16980ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 169906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 17000ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 1701c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1702c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1703c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1704c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoConstantI(LConstantI* instr) { 17052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Register dst = ToRegister(instr->result()); 17062ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->value() == 0) { 17072ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ xorl(dst, dst); 17082ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 17092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ movl(dst, Immediate(instr->value())); 17102ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 1711c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1712c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1713c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1714b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgvoid LCodeGen::DoConstantS(LConstantS* instr) { 1715b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ Move(ToRegister(instr->result()), instr->value()); 1716b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org} 1717b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org 1718b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org 1719c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoConstantD(LConstantD* instr) { 1720e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->result()->IsDoubleRegister()); 17210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com XMMRegister res = ToDoubleRegister(instr->result()); 17220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com double v = instr->value(); 1723e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org uint64_t int_val = bit_cast<uint64_t, double>(v); 17240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Use xor to produce +0.0 in a fast and compact way, but avoid to 17250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // do so if the constant is -0.0. 172649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (int_val == 0) { 1727160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ xorps(res, res); 17280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } else { 172956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register tmp = ToRegister(instr->temp()); 173049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org __ Set(tmp, int_val); 173149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org __ movq(res, tmp); 17320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1733c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1734c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1735c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1736d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid LCodeGen::DoConstantE(LConstantE* instr) { 1737d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ LoadAddress(ToRegister(instr->result()), instr->value()); 1738d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 1739d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 1740d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 1741c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoConstantT(LConstantT* instr) { 174229699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org Handle<Object> object = instr->value(isolate()); 174329699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org AllowDeferredHandleDereference smi_check; 174429699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org __ Move(ToRegister(instr->result()), object); 1745c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1746c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1747c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1748355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgvoid LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1749355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Register result = ToRegister(instr->result()); 175056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register map = ToRegister(instr->value()); 1751355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ EnumLength(result, map); 1752355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org} 1753355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 1754355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 17554efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.orgvoid LCodeGen::DoDateField(LDateField* instr) { 175656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register object = ToRegister(instr->date()); 17574efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org Register result = ToRegister(instr->result()); 17584efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org Smi* index = instr->index(); 1759de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org Label runtime, done, not_date_object; 1760e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(object.is(result)); 1761e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(object.is(rax)); 17624efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 1763de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org Condition cc = masm()->CheckSmi(object); 176406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(cc, instr, "Smi"); 17654efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ CmpObjectType(object, JS_DATE_TYPE, kScratchRegister); 176606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a date object"); 17674efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 17684efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org if (index->value() == 0) { 176943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(object, JSDate::kValueOffset)); 17704efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } else { 17714efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org if (index->value() < JSDate::kFirstUncachedField) { 17724efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); 17736e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Operand stamp_operand = __ ExternalOperand(stamp); 177443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(kScratchRegister, stamp_operand); 17757a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(kScratchRegister, FieldOperand(object, 17764efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org JSDate::kCacheStampOffset)); 17774efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ j(not_equal, &runtime, Label::kNear); 177843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(object, JSDate::kValueOffset + 17794efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org kPointerSize * index->value())); 1780935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&done, Label::kNear); 17814efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 17824efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ bind(&runtime); 17834efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ PrepareCallCFunction(2); 178443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(arg_reg_1, object); 1785af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org __ Move(arg_reg_2, index, Assembler::RelocInfoNone()); 17864efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 17874efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ bind(&done); 17884efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 17894efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org} 17904efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 17914efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 1792e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgOperand LCodeGen::BuildSeqStringOperand(Register string, 1793e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org LOperand* index, 1794e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org String::Encoding encoding) { 1795e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (index->IsConstantOperand()) { 1796e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org int offset = ToInteger32(LConstantOperand::cast(index)); 1797e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (encoding == String::TWO_BYTE_ENCODING) { 1798e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org offset *= kUC16Size; 1799e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1800e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org STATIC_ASSERT(kCharSize == 1); 1801e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return FieldOperand(string, SeqString::kHeaderSize + offset); 1802e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1803e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return FieldOperand( 1804e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org string, ToRegister(index), 1805e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org encoding == String::ONE_BYTE_ENCODING ? times_1 : times_2, 1806e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org SeqString::kHeaderSize); 1807e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org} 1808e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1809e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1810e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvoid LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) { 1811e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org String::Encoding encoding = instr->hydrogen()->encoding(); 1812e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register result = ToRegister(instr->result()); 1813a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register string = ToRegister(instr->string()); 1814a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 1815a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (FLAG_debug_code) { 1816763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(string); 181743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(string, FieldOperand(string, HeapObject::kMapOffset)); 1818895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ movzxbp(string, FieldOperand(string, Map::kInstanceTypeOffset)); 1819a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 1820e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ andb(string, Immediate(kStringRepresentationMask | kStringEncodingMask)); 1821a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 1822a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 18237a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(string, Immediate(encoding == String::ONE_BYTE_ENCODING 1824e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ? one_byte_seq_type : two_byte_seq_type)); 1825594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Check(equal, kUnexpectedStringType); 1826763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(string); 1827a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 1828a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 1829e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Operand operand = BuildSeqStringOperand(string, instr->index(), encoding); 1830a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (encoding == String::ONE_BYTE_ENCODING) { 1831e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movzxbl(result, operand); 1832e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 1833e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movzxwl(result, operand); 1834e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1835e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org} 1836e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1837e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1838e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvoid LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { 1839e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org String::Encoding encoding = instr->hydrogen()->encoding(); 1840e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register string = ToRegister(instr->string()); 1841e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1842e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (FLAG_debug_code) { 18439af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register value = ToRegister(instr->value()); 18449af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register index = ToRegister(instr->index()); 1845e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 1846e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 18479af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org int encoding_mask = 18489af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING 18499af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org ? one_byte_seq_type : two_byte_seq_type; 18509af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org __ EmitSeqStringSetCharCheck(string, index, value, encoding_mask); 1851e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1852e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1853e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Operand operand = BuildSeqStringOperand(string, instr->index(), encoding); 1854e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (instr->value()->IsConstantOperand()) { 1855e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org int value = ToInteger32(LConstantOperand::cast(instr->value())); 1856e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_LE(0, value); 1857e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (encoding == String::ONE_BYTE_ENCODING) { 1858e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_LE(value, String::kMaxOneByteCharCode); 1859e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movb(operand, Immediate(value)); 1860e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 1861e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_LE(value, String::kMaxUtf16CodeUnit); 1862e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movw(operand, Immediate(value)); 1863e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1864a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } else { 1865e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register value = ToRegister(instr->value()); 1866e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (encoding == String::ONE_BYTE_ENCODING) { 1867e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movb(operand, value); 1868e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 1869e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movw(operand, value); 1870e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1871a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 187232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org} 187332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 187432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 1875c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoAddI(LAddI* instr) { 187656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 187756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 18780511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 187937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org Representation target_rep = instr->hydrogen()->representation(); 1880fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org bool is_p = target_rep.IsSmi() || target_rep.IsExternal(); 188137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 1882906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { 1883906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (right->IsConstantOperand()) { 188470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // No support for smi-immediates for 32-bit SMI. 1885e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(SmiValuesAre32Bits() ? !target_rep.IsSmi() : SmiValuesAre31Bits()); 188670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org int32_t offset = 188770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ToRepresentation(LConstantOperand::cast(right), 188870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->right()->representation()); 1889fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (is_p) { 1890895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(ToRegister(instr->result()), 1891895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org MemOperand(ToRegister(left), offset)); 189237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } else { 189337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org __ leal(ToRegister(instr->result()), 189437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org MemOperand(ToRegister(left), offset)); 189537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } 1896906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else { 1897906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org Operand address(ToRegister(left), ToRegister(right), times_1, 0); 1898fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (is_p) { 1899895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(ToRegister(instr->result()), address); 1900fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1901fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ leal(ToRegister(instr->result()), address); 1902fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 1903906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 19040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } else { 1905906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (right->IsConstantOperand()) { 190670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // No support for smi-immediates for 32-bit SMI. 1907e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(SmiValuesAre32Bits() ? !target_rep.IsSmi() : SmiValuesAre31Bits()); 190870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org int32_t right_operand = 190970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ToRepresentation(LConstantOperand::cast(right), 191070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->right()->representation()); 1911fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (is_p) { 191270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ addp(ToRegister(left), Immediate(right_operand)); 191337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } else { 191470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ addl(ToRegister(left), Immediate(right_operand)); 191537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } 1916906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else if (right->IsRegister()) { 1917fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (is_p) { 1918fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(ToRegister(left), ToRegister(right)); 1919fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1920fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ addl(ToRegister(left), ToRegister(right)); 1921fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 1922906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else { 1923fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (is_p) { 1924fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(ToRegister(left), ToOperand(right)); 1925fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1926fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ addl(ToRegister(left), ToOperand(right)); 1927fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 1928906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 1929906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 193006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 1931906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 19320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1933c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1934c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1935c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1936471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid LCodeGen::DoMathMinMax(LMathMinMax* instr) { 193756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 193856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 1939e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left->Equals(instr->result())); 1940471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1941d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen()->representation().IsSmiOrInteger32()) { 1942471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Label return_left; 1943471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Condition condition = (operation == HMathMinMax::kMathMin) 1944471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ? less_equal 1945471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org : greater_equal; 1946471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Register left_reg = ToRegister(left); 1947471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (right->IsConstantOperand()) { 194870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Immediate right_imm = Immediate( 194970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ToRepresentation(LConstantOperand::cast(right), 195070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->right()->representation())); 1951e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(SmiValuesAre32Bits() 195270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ? !instr->hydrogen()->representation().IsSmi() 195370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org : SmiValuesAre31Bits()); 19544121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org __ cmpl(left_reg, right_imm); 1955471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(condition, &return_left, Label::kNear); 195643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(left_reg, right_imm); 195767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org } else if (right->IsRegister()) { 195867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Register right_reg = ToRegister(right); 1959d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 19607a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(left_reg, right_reg); 1961d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 1962d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ cmpl(left_reg, right_reg); 1963d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 196467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org __ j(condition, &return_left, Label::kNear); 196543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(left_reg, right_reg); 1966471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 1967471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Operand right_op = ToOperand(right); 1968d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 19697a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(left_reg, right_op); 1970d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 1971d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ cmpl(left_reg, right_op); 1972d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 1973471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(condition, &return_left, Label::kNear); 197443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(left_reg, right_op); 1975471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 1976471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&return_left); 1977471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 1978e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->hydrogen()->representation().IsDouble()); 1979471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Label check_nan_left, check_zero, return_left, return_right; 1980471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; 1981471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org XMMRegister left_reg = ToDoubleRegister(left); 1982471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org XMMRegister right_reg = ToDoubleRegister(right); 1983471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ ucomisd(left_reg, right_reg); 1984471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN. 1985471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(equal, &check_zero, Label::kNear); // left == right. 1986471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(condition, &return_left, Label::kNear); 1987471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ jmp(&return_right, Label::kNear); 1988471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 1989471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&check_zero); 1990528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 1991471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ xorps(xmm_scratch, xmm_scratch); 1992471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ ucomisd(left_reg, xmm_scratch); 1993471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(not_equal, &return_left, Label::kNear); // left == right != 0. 1994471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // At this point, both left and right are either 0 or -0. 1995471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (operation == HMathMinMax::kMathMin) { 1996057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ orps(left_reg, right_reg); 1997471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 1998471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // Since we operate on +0 and/or -0, addsd and andsd have the same effect. 1999471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ addsd(left_reg, right_reg); 2000471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 2001471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ jmp(&return_left, Label::kNear); 2002471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 2003471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&check_nan_left); 2004471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ ucomisd(left_reg, left_reg); // NaN check. 2005471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(parity_even, &return_left, Label::kNear); 2006471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&return_right); 2007057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ movaps(left_reg, right_reg); 2008471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 2009471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&return_left); 2010471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 2011471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org} 2012471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 2013471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 2014c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoArithmeticD(LArithmeticD* instr) { 201556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister left = ToDoubleRegister(instr->left()); 201656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister right = ToDoubleRegister(instr->right()); 20178f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org XMMRegister result = ToDoubleRegister(instr->result()); 201849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // All operations except MOD are computed in-place. 2019e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->op() == Token::MOD || left.is(result)); 202049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org switch (instr->op()) { 202149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org case Token::ADD: 20228f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ addsd(left, right); 202349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org break; 202449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org case Token::SUB: 20258f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ subsd(left, right); 202649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org break; 202749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org case Token::MUL: 20288f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ mulsd(left, right); 202949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org break; 203049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org case Token::DIV: 20318f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ divsd(left, right); 2032e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Don't delete this mov. It may improve performance on some CPUs, 2033e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // when there is a mulsd depending on the result 20344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org __ movaps(left, left); 203549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org break; 2036528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org case Token::MOD: { 2037528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 20388f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ PrepareCallCFunction(2); 2039528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ movaps(xmm_scratch, left); 2040e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(right.is(xmm1)); 2041ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ CallCFunction( 20424f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org ExternalReference::mod_two_doubles_operation(isolate()), 2); 2043528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ movaps(result, xmm_scratch); 204449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org break; 2045528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 204649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org default: 204749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org UNREACHABLE(); 204849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org break; 204949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 2050c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2051c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2052c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2053c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoArithmeticT(LArithmeticT* instr) { 2054e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 2055e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->left()).is(rdx)); 2056e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->right()).is(rax)); 2057e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rax)); 20580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 20596313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Handle<Code> code = 20606313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code(); 20616313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org CallCode(code, RelocInfo::CODE_TARGET, instr); 2062c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2063c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2064c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 20651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<class InstrType> 20661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid LCodeGen::EmitBranch(InstrType instr, Condition cc) { 20671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org int left_block = instr->TrueDestination(chunk_); 2068e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org int right_block = instr->FalseDestination(chunk_); 20691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 207077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org int next_block = GetNextEmittedBlock(); 20710a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 2072e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (right_block == left_block || cc == no_condition) { 20730a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org EmitGoto(left_block); 20740a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else if (left_block == next_block) { 20750a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ j(NegateCondition(cc), chunk_->GetAssemblyLabel(right_block)); 20760a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else if (right_block == next_block) { 20770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ j(cc, chunk_->GetAssemblyLabel(left_block)); 20780a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 20790a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ j(cc, chunk_->GetAssemblyLabel(left_block)); 20800a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (cc != always) { 20810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ jmp(chunk_->GetAssemblyLabel(right_block)); 20820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 20830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 2084c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2085c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2086c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2087c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.orgtemplate<class InstrType> 2088c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.orgvoid LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) { 2089c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org int false_block = instr->FalseDestination(chunk_); 2090c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ j(cc, chunk_->GetAssemblyLabel(false_block)); 2091c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org} 2092c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 2093c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 20944e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid LCodeGen::DoDebugBreak(LDebugBreak* instr) { 20954e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ int3(); 20964e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org} 20974e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 20984e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 2099c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoBranch(LBranch* instr) { 21004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Representation r = instr->hydrogen()->value()->representation(); 21010a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (r.IsInteger32()) { 2102e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->IsStub()); 210356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register reg = ToRegister(instr->value()); 21040a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ testl(reg, reg); 21051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_zero); 2106a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } else if (r.IsSmi()) { 2107e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->IsStub()); 2108a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register reg = ToRegister(instr->value()); 21097a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(reg, reg); 21101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_zero); 21110a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else if (r.IsDouble()) { 2112e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->IsStub()); 211356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister reg = ToDoubleRegister(instr->value()); 2114528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 2115528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ xorps(xmm_scratch, xmm_scratch); 2116528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ ucomisd(reg, xmm_scratch); 21171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_equal); 21180a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 2119e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(r.IsTagged()); 212056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register reg = ToRegister(instr->value()); 21214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HType type = instr->hydrogen()->value()->type(); 21220a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (type.IsBoolean()) { 2123e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->IsStub()); 2124b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ CompareRoot(reg, Heap::kTrueValueRootIndex); 21251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 21260a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else if (type.IsSmi()) { 2127e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->IsStub()); 21280a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ SmiCompare(reg, Smi::FromInt(0)); 21291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_equal); 21301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (type.IsJSArray()) { 2131e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->IsStub()); 21321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, no_condition); 21331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (type.IsHeapNumber()) { 2134e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->IsStub()); 2135528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 2136528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ xorps(xmm_scratch, xmm_scratch); 2137528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); 21381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_equal); 21391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (type.IsString()) { 2140e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->IsStub()); 21417a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); 21421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_equal); 21430a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 2144d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 2145d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org // Avoid deopts in the case where we've never executed this path before. 21461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); 2147d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 2148d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (expected.Contains(ToBooleanStub::UNDEFINED)) { 2149d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org // undefined -> false. 2150d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); 21511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(equal, instr->FalseLabel(chunk_)); 2152d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 2153d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (expected.Contains(ToBooleanStub::BOOLEAN)) { 2154d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org // true -> true. 2155d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ CompareRoot(reg, Heap::kTrueValueRootIndex); 21561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(equal, instr->TrueLabel(chunk_)); 2157d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org // false -> false. 2158d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ CompareRoot(reg, Heap::kFalseValueRootIndex); 21591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(equal, instr->FalseLabel(chunk_)); 2160d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 2161d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (expected.Contains(ToBooleanStub::NULL_TYPE)) { 2162d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org // 'null' -> false. 2163d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ CompareRoot(reg, Heap::kNullValueRootIndex); 21641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(equal, instr->FalseLabel(chunk_)); 2165d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 2166d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 2167d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (expected.Contains(ToBooleanStub::SMI)) { 2168d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org // Smis: 0 -> false, all other -> true. 2169d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ Cmp(reg, Smi::FromInt(0)); 21701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(equal, instr->FalseLabel(chunk_)); 21711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); 2172d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } else if (expected.NeedsMap()) { 2173d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org // If we need a map later and have a Smi -> deopt. 2174d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ testb(reg, Immediate(kSmiTagMask)); 217506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "Smi"); 2176d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 2177d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 2178d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org const Register map = kScratchRegister; 2179d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (expected.NeedsMap()) { 218043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(map, FieldOperand(reg, HeapObject::kMapOffset)); 21814acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 21824acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (expected.CanBeUndetectable()) { 21834acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Undetectable -> false. 21844acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ testb(FieldOperand(map, Map::kBitFieldOffset), 21854acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Immediate(1 << Map::kIsUndetectable)); 21861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(not_zero, instr->FalseLabel(chunk_)); 21874acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 2188d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 2189d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 2190d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { 2191d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org // spec object -> true. 2192d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 21931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(above_equal, instr->TrueLabel(chunk_)); 2194d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 2195d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 2196d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (expected.Contains(ToBooleanStub::STRING)) { 2197d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org // String value -> false iff empty. 2198d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org Label not_string; 2199d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); 2200d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ j(above_equal, ¬_string, Label::kNear); 22017a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); 22021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(not_zero, instr->TrueLabel(chunk_)); 22031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ jmp(instr->FalseLabel(chunk_)); 2204d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ bind(¬_string); 2205d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 2206d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 2207c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org if (expected.Contains(ToBooleanStub::SYMBOL)) { 2208c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org // Symbol value -> true. 2209c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org __ CmpInstanceType(map, SYMBOL_TYPE); 2210c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org __ j(equal, instr->TrueLabel(chunk_)); 2211c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org } 2212c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org 2213d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 2214d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org // heap number -> false iff +0, -0, or NaN. 2215d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org Label not_heap_number; 2216d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); 2217d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ j(not_equal, ¬_heap_number, Label::kNear); 2218528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 2219528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ xorps(xmm_scratch, xmm_scratch); 2220528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); 22211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(zero, instr->FalseLabel(chunk_)); 22221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ jmp(instr->TrueLabel(chunk_)); 2223d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org __ bind(¬_heap_number); 2224d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 2225d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 22261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!expected.IsGeneric()) { 22271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // We've seen something for the first time -> deopt. 22281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // This can only happen if we are not generic already. 222906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(no_condition, instr, "unexpected object"); 22301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 22310a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 22320a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 2233c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2234c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2235c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 223604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgvoid LCodeGen::EmitGoto(int block) { 223732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (!IsNextEmittedBlock(block)) { 223832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ jmp(chunk_->GetAssemblyLabel(chunk_->LookupDestination(block))); 22390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 2240c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2241c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2242c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2243c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoGoto(LGoto* instr) { 224404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org EmitGoto(instr->block_id()); 2245c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2246c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2247c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 22480a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orginline Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { 2249c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Condition cond = no_condition; 2250c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org switch (op) { 2251c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org case Token::EQ: 2252c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org case Token::EQ_STRICT: 2253c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org cond = equal; 2254c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org break; 22552ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org case Token::NE: 22562ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org case Token::NE_STRICT: 22572ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org cond = not_equal; 22582ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org break; 2259c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org case Token::LT: 2260c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org cond = is_unsigned ? below : less; 2261c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org break; 2262c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org case Token::GT: 2263c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org cond = is_unsigned ? above : greater; 2264c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org break; 2265c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org case Token::LTE: 2266c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org cond = is_unsigned ? below_equal : less_equal; 2267c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org break; 2268c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org case Token::GTE: 2269c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org cond = is_unsigned ? above_equal : greater_equal; 2270c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org break; 2271c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org case Token::IN: 2272c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org case Token::INSTANCEOF: 2273c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org default: 2274c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org UNREACHABLE(); 2275c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 2276c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return cond; 2277c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2278c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2279c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2280e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgvoid LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { 228156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 228256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 228354ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org bool is_unsigned = 22848ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org instr->is_double() || 22858ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org instr->hydrogen()->left()->CheckFlag(HInstruction::kUint32) || 22868ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org instr->hydrogen()->right()->CheckFlag(HInstruction::kUint32); 228754ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org Condition cc = TokenToCondition(instr->op(), is_unsigned); 22880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 2289394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (left->IsConstantOperand() && right->IsConstantOperand()) { 2290394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // We can statically evaluate the comparison. 2291394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com double left_val = ToDouble(LConstantOperand::cast(left)); 2292394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com double right_val = ToDouble(LConstantOperand::cast(right)); 22931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org int next_block = EvalComparison(instr->op(), left_val, right_val) ? 22941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_); 2295394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EmitGoto(next_block); 22960a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 2297394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (instr->is_double()) { 2298394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Don't base result on EFLAGS when a NaN is involved. Instead 2299394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // jump to the false block. 2300394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); 23011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(parity_even, instr->FalseLabel(chunk_)); 2302394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 2303394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int32_t value; 2304394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (right->IsConstantOperand()) { 2305394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com value = ToInteger32(LConstantOperand::cast(right)); 2306c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 2307c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org __ Cmp(ToRegister(left), Smi::FromInt(value)); 2308c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } else { 2309c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org __ cmpl(ToRegister(left), Immediate(value)); 2310c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } 2311394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else if (left->IsConstantOperand()) { 2312394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com value = ToInteger32(LConstantOperand::cast(left)); 2313c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 2314c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org if (right->IsRegister()) { 2315c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org __ Cmp(ToRegister(right), Smi::FromInt(value)); 2316c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } else { 2317c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org __ Cmp(ToOperand(right), Smi::FromInt(value)); 2318c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } 2319c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } else if (right->IsRegister()) { 2320394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ cmpl(ToRegister(right), Immediate(value)); 2321394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 2322394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ cmpl(ToOperand(right), Immediate(value)); 2323394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 232438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // We commuted the operands, so commute the condition. 232538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org cc = CommuteCondition(cc); 2326c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } else if (instr->hydrogen_value()->representation().IsSmi()) { 2327c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org if (right->IsRegister()) { 23287a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(ToRegister(left), ToRegister(right)); 2329c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } else { 23307a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(ToRegister(left), ToOperand(right)); 2331c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } 2332394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 2333394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (right->IsRegister()) { 2334394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ cmpl(ToRegister(left), ToRegister(right)); 2335394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 2336394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ cmpl(ToRegister(left), ToOperand(right)); 2337394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 2338394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 2339394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 23401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, cc); 23410a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 2342c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2343c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2344c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2345ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.orgvoid LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 234656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register left = ToRegister(instr->left()); 23477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2348b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (instr->right()->IsConstantOperand()) { 2349a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); 2350c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Cmp(left, right); 2351b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } else { 2352a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register right = ToRegister(instr->right()); 23537a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(left, right); 2354b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 23551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 23567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 23577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 23587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2359c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.orgvoid LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) { 2360c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (instr->hydrogen()->representation().IsTagged()) { 2361c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org Register input_reg = ToRegister(instr->object()); 2362c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ Cmp(input_reg, factory()->the_hole_value()); 2363c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org EmitBranch(instr, equal); 2364c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org return; 2365c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org } 2366c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 2367c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->object()); 2368c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ ucomisd(input_reg, input_reg); 2369c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org EmitFalseBranch(instr, parity_odd); 2370c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 2371fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rsp, Immediate(kDoubleSize)); 2372c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ movsd(MemOperand(rsp, 0), input_reg); 2373fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rsp, Immediate(kDoubleSize)); 2374c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 2375c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org int offset = sizeof(kHoleNanUpper32); 2376c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org __ cmpl(MemOperand(rsp, -offset), Immediate(kHoleNanUpper32)); 2377c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org EmitBranch(instr, equal); 2378c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org} 2379c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 2380c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 23810cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.orgvoid LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) { 23820cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Representation rep = instr->hydrogen()->value()->representation(); 2383e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!rep.IsInteger32()); 23840cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 23850cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org if (rep.IsDouble()) { 23860cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org XMMRegister value = ToDoubleRegister(instr->value()); 23870cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 23880cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org __ xorps(xmm_scratch, xmm_scratch); 23890cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org __ ucomisd(xmm_scratch, value); 23900cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org EmitFalseBranch(instr, not_equal); 23910cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org __ movmskpd(kScratchRegister, value); 23920cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org __ testl(kScratchRegister, Immediate(1)); 23930cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org EmitBranch(instr, not_zero); 23940cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } else { 23950cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Register value = ToRegister(instr->value()); 23960cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Handle<Map> map = masm()->isolate()->factory()->heap_number_map(); 23970cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org __ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK); 23980cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org __ cmpl(FieldOperand(value, HeapNumber::kExponentOffset), 2399a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Immediate(0x1)); 2400a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org EmitFalseBranch(instr, no_overflow); 24010cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org __ cmpl(FieldOperand(value, HeapNumber::kMantissaOffset), 24020cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Immediate(0x00000000)); 24030cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org EmitBranch(instr, equal); 24040cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 24050cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org} 24060cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 24070cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 2408c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgCondition LCodeGen::EmitIsObject(Register input, 2409c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Label* is_not_object, 2410c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Label* is_object) { 2411e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!input.is(kScratchRegister)); 24120a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 24130a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ JumpIfSmi(input, is_not_object); 24140a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 24150ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ CompareRoot(input, Heap::kNullValueRootIndex); 24160a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ j(equal, is_object); 24170a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 241843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset)); 24190a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Undetectable objects behave like undefined. 24200ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ testb(FieldOperand(kScratchRegister, Map::kBitFieldOffset), 24210a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Immediate(1 << Map::kIsUndetectable)); 24220a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ j(not_zero, is_not_object); 24230a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 24240ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ movzxbl(kScratchRegister, 24250ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); 2426d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ cmpb(kScratchRegister, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 24270a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ j(below, is_not_object); 2428d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ cmpb(kScratchRegister, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2429c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return below_equal; 2430c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2431c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2432c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2433c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 243456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register reg = ToRegister(instr->value()); 24350a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 24361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Condition true_cond = EmitIsObject( 24371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org reg, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_)); 24380a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 24391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, true_cond); 2440c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2441c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2442c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 24430ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryCondition LCodeGen::EmitIsString(Register input, 24440ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Register temp1, 24451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label* is_not_string, 24461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org SmiCheck check_needed = INLINE_SMI_CHECK) { 24471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (check_needed == INLINE_SMI_CHECK) { 24481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(input, is_not_string); 24491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 24501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 24510ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Condition cond = masm_->IsObjectStringType(input, temp1, temp1); 24520ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 24530ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry return cond; 24540ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry} 24550ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 24560ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 24570ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 245856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register reg = ToRegister(instr->value()); 245956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 24600ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 24611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org SmiCheck check_needed = 2462eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org instr->hydrogen()->value()->type().IsHeapObject() 24631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 24640ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 24651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Condition true_cond = EmitIsString( 24661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org reg, temp, instr->FalseLabel(chunk_), check_needed); 24670ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 24681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, true_cond); 24690ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry} 24700ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 24710ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 2472c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 24730a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Condition is_smi; 247456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org if (instr->value()->IsRegister()) { 247556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 24760a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org is_smi = masm()->CheckSmi(input); 24770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 247856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Operand input = ToOperand(instr->value()); 24790a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org is_smi = masm()->CheckSmi(input); 24800a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 24811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, is_smi); 24820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 24830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 24840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 24857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgvoid LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 248656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 248756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 24887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2489eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org if (!instr->hydrogen()->value()->type().IsHeapObject()) { 24901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(input, instr->FalseLabel(chunk_)); 24911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 249243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(temp, FieldOperand(input, HeapObject::kMapOffset)); 24937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ testb(FieldOperand(temp, Map::kBitFieldOffset), 24947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Immediate(1 << Map::kIsUndetectable)); 24951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_zero); 24967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 24977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 24987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 24990ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { 2500e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 25010ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Token::Value op = instr->op(); 25020ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 25036313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code(); 25040ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry CallCode(ic, RelocInfo::CODE_TARGET, instr); 25050ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 25060ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Condition condition = TokenToCondition(op, false); 25077a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rax, rax); 25080ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 25091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, condition); 25100ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry} 25110ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 25120ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 25134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgstatic InstanceType TestType(HHasInstanceTypeAndBranch* instr) { 25140a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org InstanceType from = instr->from(); 25150a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org InstanceType to = instr->to(); 25160a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (from == FIRST_TYPE) return to; 2517e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(from == to || to == LAST_TYPE); 25180a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return from; 25190a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 25200a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 25210a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 25224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgstatic Condition BranchCondition(HHasInstanceTypeAndBranch* instr) { 25230a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org InstanceType from = instr->from(); 25240a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org InstanceType to = instr->to(); 25250a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (from == to) return equal; 25260a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (to == LAST_TYPE) return above_equal; 25270a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (from == FIRST_TYPE) return below_equal; 25280a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org UNREACHABLE(); 25290a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return equal; 2530c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2531c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2532c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2533c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 253456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 25350a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 2536eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org if (!instr->hydrogen()->value()->type().IsHeapObject()) { 25371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ JumpIfSmi(input, instr->FalseLabel(chunk_)); 25381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 25390a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 25400a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister); 25411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, BranchCondition(instr->hydrogen())); 2542c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2543c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2544c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 25458f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.orgvoid LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 254656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 25478f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org Register result = ToRegister(instr->result()); 25488f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 2549c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ AssertString(input); 25508f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 25518f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ movl(result, FieldOperand(input, String::kHashFieldOffset)); 2552e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(String::kHashShift >= kSmiTagSize); 25538f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ IndexFromHash(result, result); 25548f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org} 25558f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 25568f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 2557c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoHasCachedArrayIndexAndBranch( 2558c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LHasCachedArrayIndexAndBranch* instr) { 255956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 25600a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 25610a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ testl(FieldOperand(input, String::kHashFieldOffset), 25620a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Immediate(String::kContainsCachedArrayIndexMask)); 25631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 2564c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2565c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2566c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 25670a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org// Branches to a label or falls through with the answer in the z flag. 2568f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Trashes the temp register. 2569c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::EmitClassOfTest(Label* is_true, 2570c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Label* is_false, 25710a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Handle<String> class_name, 2572c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Register input, 2573c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register temp, 2574f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Register temp2) { 2575e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!input.is(temp)); 2576e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!input.is(temp2)); 2577e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!temp.is(temp2)); 2578f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 25790a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ JumpIfSmi(input, is_false); 25800a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 25815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (String::Equals(isolate()->factory()->Function_string(), class_name)) { 2582c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Assuming the following assertions, we can use the same compares to test 2583c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // for both being a function type and being in the object type range. 2584c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 2585c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == 2586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FIRST_SPEC_OBJECT_TYPE + 1); 2587c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == 2588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LAST_SPEC_OBJECT_TYPE - 1); 2589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); 2590c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, temp); 2591c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ j(below, is_false); 2592c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ j(equal, is_true); 2593c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CmpInstanceType(temp, LAST_SPEC_OBJECT_TYPE); 2594c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ j(equal, is_true); 25950a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 2596c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Faster code path to avoid two compares: subtract lower bound from the 2597c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // actual type and do a signed compare with the width of the type range. 259843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(temp, FieldOperand(input, HeapObject::kMapOffset)); 259956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ movzxbl(temp2, FieldOperand(temp, Map::kInstanceTypeOffset)); 2600fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(temp2, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 26017a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(temp2, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - 260256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2603c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ j(above, is_false); 26040a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 26050a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 2606c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range. 26070a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Check if the constructor in the map is a function. 260843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(temp, FieldOperand(temp, Map::kConstructorOffset)); 26090a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 26100a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Objects with a non-function constructor have class 'Object'. 26110a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ CmpObjectType(temp, JS_FUNCTION_TYPE, kScratchRegister); 26125e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (String::Equals(class_name, isolate()->factory()->Object_string())) { 26130a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ j(not_equal, is_true); 26140a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 26150a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ j(not_equal, is_false); 26160a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 26170a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 26180a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // temp now contains the constructor function. Grab the 26190a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // instance class name from there. 262043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(temp, FieldOperand(temp, JSFunction::kSharedFunctionInfoOffset)); 262143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(temp, FieldOperand(temp, 26220a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org SharedFunctionInfo::kInstanceClassNameOffset)); 26234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // The class name we are testing against is internalized since it's a literal. 26244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // The name in the constructor is internalized because of the way the context 26254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // is booted. This routine isn't expected to work for random API-created 26260a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // classes and it doesn't have to because you can't access it with natives 26274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // syntax. Since both sides are internalized it is sufficient to use an 26284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // identity comparison. 2629e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(class_name->IsInternalizedString()); 26300a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ Cmp(temp, class_name); 26310a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // End with the answer in the z flag. 2632c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2633c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2634c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2635c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 263656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 263756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 263856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp2 = ToRegister(instr->temp2()); 26390a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Handle<String> class_name = instr->hydrogen()->class_name(); 26400a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 26411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), 26421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org class_name, input, temp, temp2); 26430a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 26441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 2645c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2646c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2647c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2648c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 264956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register reg = ToRegister(instr->value()); 26500ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 26510ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 26521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 2653c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2654c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2655c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2656c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2657e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 2658f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org InstanceofStub stub(isolate(), InstanceofStub::kNoFlags); 2659763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(ToRegister(instr->left())); 2660763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(ToRegister(instr->right())); 2661f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 266283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label true_value, done; 26637a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rax, rax); 266483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(zero, &true_value, Label::kNear); 26653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); 266683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 26673a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&true_value); 26683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); 26693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&done); 2670c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2671c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2672c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2673c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { 2674ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredInstanceOfKnownGlobal FINAL : public LDeferredCode { 26753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org public: 26763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org DeferredInstanceOfKnownGlobal(LCodeGen* codegen, 26773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LInstanceOfKnownGlobal* instr) 26783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org : LDeferredCode(codegen), instr_(instr) { } 2679ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 268027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_); 26813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 2682ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 26834d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org Label* map_check() { return &map_check_; } 26843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org private: 26853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LInstanceOfKnownGlobal* instr_; 26864d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org Label map_check_; 26873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org }; 26883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 2689e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 26903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org DeferredInstanceOfKnownGlobal* deferred; 26917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); 26923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 26934d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org Label done, false_result; 269456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register object = ToRegister(instr->value()); 26953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 26963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // A Smi is not an instance of anything. 2697935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ JumpIfSmi(object, &false_result, Label::kNear); 26983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 26994d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // This is the inlined call site instanceof cache. The two occurences of the 27004d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // hole value will be patched to the last map/result pair generated by the 27014d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // instanceof stub. 270283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label cache_miss; 27034d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // Use a temp register to avoid memory operands with variable lengths. 270456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register map = ToRegister(instr->temp()); 270543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(map, FieldOperand(object, HeapObject::kMapOffset)); 27064d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org __ bind(deferred->map_check()); // Label for calculating code patching. 270741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cache_cell = factory()->NewCell(factory()->the_hole_value()); 27089cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org __ Move(kScratchRegister, cache_cell, RelocInfo::CELL); 27097a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(map, Operand(kScratchRegister, 0)); 271083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_equal, &cache_miss, Label::kNear); 27114d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // Patched to load either true or false. 27124d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); 27134d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org#ifdef DEBUG 27144d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // Check that the code size between patch label and patch sites is invariant. 27154d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org Label end_of_patched_code; 27164d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org __ bind(&end_of_patched_code); 2717e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(true); 27184d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org#endif 2719935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&done, Label::kNear); 27204d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org 27214d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // The inlined call site cache did not match. Check for null and string 27224d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // before calling the deferred code. 27234d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org __ bind(&cache_miss); // Null is not an instance of anything. 27243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ CompareRoot(object, Heap::kNullValueRootIndex); 272583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &false_result, Label::kNear); 27263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 27273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // String values are not instances of anything. 27283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ JumpIfNotString(object, kScratchRegister, deferred->entry()); 27293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 27303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&false_result); 27313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); 27323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 27333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(deferred->exit()); 27344d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org __ bind(&done); 2735c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2736c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2737c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 273827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 273927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Label* map_check) { 274044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org { 274144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 274244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>( 274344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck); 2744f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org InstanceofStub stub(isolate(), flags); 27453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 2746763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(ToRegister(instr->value())); 2747c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Push(instr->function()); 274844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 274908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org static const int kAdditionalDelta = kPointerSize == kInt64Size ? 10 : 16; 275044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org int delta = 275144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 2752e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(delta >= 0); 2753763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ PushImm32(delta); 275444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 275544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // We are pushing three values on the stack but recording a 275644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // safepoint with two arguments because stub is going to 275744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // remove the third argument from the stack before jumping 275844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // to instanceof builtin on the slow path. 2759f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCodeGeneric(stub.GetCode(), 276044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org RelocInfo::CODE_TARGET, 276144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org instr, 276244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org RECORD_SAFEPOINT_WITH_REGISTERS, 276344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 2); 2764e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(delta == masm_->SizeOfCodeGeneratedSince(map_check)); 27651044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); 276627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 2767a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org // Move result to a register that survives the end of the 2768a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org // PushSafepointRegisterScope. 276943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(kScratchRegister, rax); 277044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 27717a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(kScratchRegister, kScratchRegister); 27723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Label load_false; 27733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Label done; 2774935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(not_zero, &load_false, Label::kNear); 27753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ LoadRoot(rax, Heap::kTrueValueRootIndex); 2776935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&done, Label::kNear); 27773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&load_false); 27783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ LoadRoot(rax, Heap::kFalseValueRootIndex); 27793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&done); 2780c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2781c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2782c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2783c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCmpT(LCmpT* instr) { 2784e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 27850a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Token::Value op = instr->op(); 27860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 27876313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code(); 27880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 27890a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 27900a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Condition condition = TokenToCondition(op, false); 279183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label true_value, done; 27927a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rax, rax); 279383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(condition, &true_value, Label::kNear); 27940a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); 279583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 27960a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ bind(&true_value); 27970a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); 27980a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ bind(&done); 2799c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2800c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2801c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2802c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoReturn(LReturn* instr) { 2803a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (FLAG_trace && info()->IsOptimizing()) { 2804935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // Preserve the return value on the stack and rely on the runtime call 2805935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // to return the value in the same register. We're leaving the code 2806935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // managed by the register allocator and tearing down the frame, it's 2807935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // safe to write to the context register. 2808763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 280943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2810c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org __ CallRuntime(Runtime::kTraceExit, 1); 2811c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 281294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (info()->saves_caller_doubles()) { 2813f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org RestoreCallerDoubles(); 281494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 28154e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org int no_frame_start = -1; 2816a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (NeedsEagerFrame()) { 281743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsp, rbp); 2818763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbp); 28194e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org no_frame_start = masm_->pc_offset(); 2820a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 28216e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org if (instr->has_constant_parameter_count()) { 28226e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ Ret((ToInteger32(instr->constant_parameter_count()) + 1) * kPointerSize, 28236e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org rcx); 2824a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 28256e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Register reg = ToRegister(instr->parameter_count()); 2826ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // The argument count parameter is a smi 2827ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ SmiToInteger32(reg, reg); 28286e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Register return_addr_reg = reg.is(rcx) ? rbx : rcx; 2829594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ PopReturnAddressTo(return_addr_reg); 28302f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ shlp(reg, Immediate(kPointerSizeLog2)); 2831fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rsp, reg); 28326e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ jmp(return_addr_reg); 2833a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 28344e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org if (no_frame_start != -1) { 28354e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); 28364e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 2837c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2838c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2839c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2840c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgvoid LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 2841d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com Register result = ToRegister(instr->result()); 2842528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ LoadGlobalCell(result, instr->hydrogen()->cell().handle()); 2843c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (instr->hydrogen()->RequiresHoleCheck()) { 2844d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 284506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 2846d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 2847c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2848c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2849c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 28506474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgtemplate <class T> 28516474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid LCodeGen::EmitVectorLoadICRegisters(T* instr) { 28526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org DCHECK(FLAG_vector_ics); 28536474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Register vector = ToRegister(instr->temp_vector()); 28549aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister())); 28556474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ Move(vector, instr->hydrogen()->feedback_vector()); 28566474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // No need to allocate this register. 28579aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DCHECK(VectorLoadICDescriptor::SlotRegister().is(rax)); 28589aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org __ Move(VectorLoadICDescriptor::SlotRegister(), 2859fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org Smi::FromInt(instr->hydrogen()->slot())); 28606474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 28616474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 28626474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 2863c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgvoid LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { 2864e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 2865fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org DCHECK(ToRegister(instr->global_object()) 28669aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org .is(LoadDescriptor::ReceiverRegister())); 2867e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rax)); 2868c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 28699aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org __ Move(LoadDescriptor::NameRegister(), instr->name()); 28709d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org if (FLAG_vector_ics) { 28716474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); 28729d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org } 28739cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; 28746313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code(); 28759cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 2876c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org} 2877c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 2878c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 287974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { 2880e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org Register value = ToRegister(instr->value()); 2881528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Handle<Cell> cell_handle = instr->hydrogen()->cell().handle(); 2882c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 288383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // If the cell we are storing to contains the hole it could have 288483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // been deleted from the property dictionary. In that case, we need 288583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // to update the property details in the property dictionary to mark 288683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // it as no longer deleted. We deoptimize in that case. 2887c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (instr->hydrogen()->RequiresHoleCheck()) { 2888e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org // We have a temp because CompareRoot might clobber kScratchRegister. 288956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register cell = ToRegister(instr->temp()); 2890e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!value.is(cell)); 28919cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org __ Move(cell, cell_handle, RelocInfo::CELL); 2892e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org __ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex); 289306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 2894e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org // Store the value. 289543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(cell, 0), value); 2896e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org } else { 2897e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org // Store the value. 28989cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org __ Move(kScratchRegister, cell_handle, RelocInfo::CELL); 289943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(kScratchRegister, 0), value); 290083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 290164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Cells are always rescanned, so no write barrier here. 2902c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2903c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2904c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2905c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 29063a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register context = ToRegister(instr->context()); 29073a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register result = ToRegister(instr->result()); 290843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, ContextOperand(context, instr->slot_index())); 290964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 291064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 29117ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org if (instr->hydrogen()->DeoptimizesOnHole()) { 291206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 29137ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } else { 29147ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org Label is_not_hole; 29157ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ j(not_equal, &is_not_hole, Label::kNear); 29167ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ LoadRoot(result, Heap::kUndefinedValueRootIndex); 29177ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ bind(&is_not_hole); 29187ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } 291964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 29203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 29213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 29223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 29233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { 29243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register context = ToRegister(instr->context()); 29253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register value = ToRegister(instr->value()); 29267ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 292764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Operand target = ContextOperand(context, instr->slot_index()); 29287ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 29297ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org Label skip_assignment; 293064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 293164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CompareRoot(target, Heap::kTheHoleValueRootIndex); 29327ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org if (instr->hydrogen()->DeoptimizesOnHole()) { 293306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 29347ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } else { 29357ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ j(not_equal, &skip_assignment); 29367ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } 293764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 293843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(target, value); 29397ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 2940394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (instr->hydrogen()->NeedsWriteBarrier()) { 2941394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com SmiCheck check_needed = 2942eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org instr->hydrogen()->value()->type().IsHeapObject() 29431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 29443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int offset = Context::SlotOffset(instr->slot_index()); 294556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register scratch = ToRegister(instr->temp()); 2946394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteContextSlot(context, 2947394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com offset, 2948394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com value, 2949394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scratch, 2950394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kSaveFPRegs, 2951394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 2952394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com check_needed); 29533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 29547ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 29557ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ bind(&skip_assignment); 2956c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2957c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2958c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2959c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 296053ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org HObjectAccess access = instr->hydrogen()->access(); 296153ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org int offset = access.offset(); 2962d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 2963d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (access.IsExternalMemory()) { 2964d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register result = ToRegister(instr->result()); 2965d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->object()->IsConstantOperand()) { 2966e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result.is(rax)); 2967d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object()))); 2968d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 2969d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register object = ToRegister(instr->object()); 2970d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org __ Load(result, MemOperand(object, offset), access.representation()); 2971d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 2972d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return; 2973d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 2974d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 297556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register object = ToRegister(instr->object()); 297609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org if (instr->hydrogen()->representation().IsDouble()) { 297757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org XMMRegister result = ToDoubleRegister(instr->result()); 297857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movsd(result, FieldOperand(object, offset)); 297957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org return; 2980f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 298157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 298257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Register result = ToRegister(instr->result()); 2983d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (!access.IsInobject()) { 298443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(object, JSObject::kPropertiesOffset)); 2985d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org object = result; 2986378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 2987113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org 2988113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org Representation representation = access.representation(); 298904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (representation.IsSmi() && SmiValuesAre32Bits() && 2990113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org instr->hydrogen()->representation().IsInteger32()) { 29912ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (FLAG_debug_code) { 29922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Register scratch = kScratchRegister; 29932ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ Load(scratch, FieldOperand(object, offset), representation); 29942ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ AssertSmi(scratch); 29952ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 2996f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 2997113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org // Read int value directly from upper half of the smi. 2998113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org STATIC_ASSERT(kSmiTag == 0); 2999e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kSmiTagSize + kSmiShiftSize == 32); 3000113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org offset += kPointerSize / 2; 3001113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org representation = Representation::Integer32(); 3002113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org } 3003113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org __ Load(result, FieldOperand(object, offset), representation); 3004c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3005c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3006c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3007c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 3008e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 30099aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); 3010e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rax)); 3011d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 30129aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org __ Move(LoadDescriptor::NameRegister(), instr->name()); 30139d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org if (FLAG_vector_ics) { 30146474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); 30159d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org } 30166313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code(); 3017d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com CallCode(ic, RelocInfo::CODE_TARGET, instr); 3018c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3019c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3020c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3021c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 3022496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org Register function = ToRegister(instr->function()); 3023496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org Register result = ToRegister(instr->result()); 3024496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3025496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Get the prototype or initial map from the function. 302643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, 3027496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 3028496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3029496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Check that the function has a prototype or an initial map. 3030496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 303106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 3032496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3033496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // If the function does not have an initial map, we're done. 303483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 3035496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ CmpObjectType(result, MAP_TYPE, kScratchRegister); 303683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_equal, &done, Label::kNear); 3037496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3038496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Get the prototype from the initial map. 303943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(result, Map::kPrototypeOffset)); 3040496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3041496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // All done. 3042496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ bind(&done); 3043c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3044c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3045c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3046528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid LCodeGen::DoLoadRoot(LLoadRoot* instr) { 3047528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register result = ToRegister(instr->result()); 3048528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ LoadRoot(result, instr->index()); 3049528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 3050528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 3051528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 3052c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 305349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org Register arguments = ToRegister(instr->arguments()); 305449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org Register result = ToRegister(instr->result()); 305577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 305677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (instr->length()->IsConstantOperand() && 305777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org instr->index()->IsConstantOperand()) { 3058594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index())); 3059594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int32_t const_length = ToInteger32(LConstantOperand::cast(instr->length())); 30609b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org if (const_index >= 0 && const_index < const_length) { 30619b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org StackArgumentsAccessor args(arguments, const_length, 30629b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org ARGUMENTS_DONT_CONTAIN_RECEIVER); 30639b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org __ movp(result, args.GetArgumentOperand(const_index)); 30649b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org } else if (FLAG_debug_code) { 30659b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org __ int3(); 30669b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org } 306749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } else { 306877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Register length = ToRegister(instr->length()); 306977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // There are two words between the frame pointer and the last argument. 307077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // Subtracting from length accounts for one of them add one more. 307177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (instr->index()->IsRegister()) { 307277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ subl(length, ToRegister(instr->index())); 307377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 307477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ subl(length, ToOperand(instr->index())); 307577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 3076d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StackArgumentsAccessor args(arguments, length, 3077d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ARGUMENTS_DONT_CONTAIN_RECEIVER); 307843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, args.GetArgumentOperand(0)); 307949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 3080c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3081c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3082c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3083eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.orgvoid LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 3084eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org ElementsKind elements_kind = instr->elements_kind(); 3085eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org LOperand* key = instr->key(); 308670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (kPointerSize == kInt32Size && !key->IsConstantOperand()) { 308770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Register key_reg = ToRegister(key); 308870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Representation key_representation = 308970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(); 309070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (ExternalArrayOpRequiresTemp(key_representation, elements_kind)) { 309170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ SmiToInteger64(key_reg, key_reg); 309270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } else if (instr->hydrogen()->IsDehoisted()) { 309370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Sign extend key because it could be a 32 bit negative value 309470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // and the dehoisted address computation happens in 64 bits 309570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ movsxlq(key_reg, key_reg); 309670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 309770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 3098e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Operand operand(BuildFastArrayOperand( 3099e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->elements(), 3100e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org key, 310170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 3102e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org elements_kind, 3103fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org instr->base_offset())); 31040e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org 3105af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || 31065c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org elements_kind == FLOAT32_ELEMENTS) { 3107e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org XMMRegister result(ToDoubleRegister(instr->result())); 3108e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movss(result, operand); 3109e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ cvtss2sd(result, result); 3110af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || 31115c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org elements_kind == FLOAT64_ELEMENTS) { 3112e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movsd(ToDoubleRegister(instr->result()), operand); 3113e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 3114e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Register result(ToRegister(instr->result())); 3115e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org switch (elements_kind) { 3116af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_INT8_ELEMENTS: 31175c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case INT8_ELEMENTS: 31182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ movsxbl(result, operand); 3119e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3120af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT8_ELEMENTS: 3121af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT8_CLAMPED_ELEMENTS: 31225c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT8_ELEMENTS: 31235c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT8_CLAMPED_ELEMENTS: 31242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ movzxbl(result, operand); 3125e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3126af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_INT16_ELEMENTS: 31275c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case INT16_ELEMENTS: 31282ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ movsxwl(result, operand); 3129e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3130af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT16_ELEMENTS: 31315c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT16_ELEMENTS: 31322ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ movzxwl(result, operand); 3133e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3134af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_INT32_ELEMENTS: 31355c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case INT32_ELEMENTS: 31362ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ movl(result, operand); 3137e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3138af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT32_ELEMENTS: 31395c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT32_ELEMENTS: 3140e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movl(result, operand); 3141e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 3142e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ testl(result, result); 314306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(negative, instr, "negative value"); 3144e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 3145e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3146af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_FLOAT32_ELEMENTS: 3147af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_FLOAT64_ELEMENTS: 31485c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case FLOAT32_ELEMENTS: 31495c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case FLOAT64_ELEMENTS: 3150e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_ELEMENTS: 3151e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_SMI_ELEMENTS: 3152e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_DOUBLE_ELEMENTS: 3153e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_ELEMENTS: 3154e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_SMI_ELEMENTS: 3155e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_DOUBLE_ELEMENTS: 3156e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case DICTIONARY_ELEMENTS: 3157486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org case SLOPPY_ARGUMENTS_ELEMENTS: 3158e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org UNREACHABLE(); 3159e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 31607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 316183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 316283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 316383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 316483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 3165e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { 3166717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org XMMRegister result(ToDoubleRegister(instr->result())); 3167304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org LOperand* key = instr->key(); 316870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (kPointerSize == kInt32Size && !key->IsConstantOperand() && 316970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->IsDehoisted()) { 317070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Sign extend key because it could be a 32 bit negative value 317170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // and the dehoisted address computation happens in 64 bits 317270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ movsxlq(ToRegister(key), ToRegister(key)); 317370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 3174830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 3175830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Operand hole_check_operand = BuildFastArrayOperand( 3176830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org instr->elements(), 3177304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org key, 317870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 3179830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FAST_DOUBLE_ELEMENTS, 3180fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org instr->base_offset() + sizeof(kHoleNanLower32)); 3181830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); 318206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 3183830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 3184717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 3185717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org Operand double_load_operand = BuildFastArrayOperand( 31860e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org instr->elements(), 3187304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org key, 318870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 31890e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org FAST_DOUBLE_ELEMENTS, 3190fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org instr->base_offset()); 3191717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org __ movsd(result, double_load_operand); 3192717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org} 3193717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 3194717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 3195e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 319671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org HLoadKeyed* hinstr = instr->hydrogen(); 3197e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Register result = ToRegister(instr->result()); 3198e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org LOperand* key = instr->key(); 319971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org bool requires_hole_check = hinstr->RequiresHoleCheck(); 320071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org Representation representation = hinstr->representation(); 3201fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org int offset = instr->base_offset(); 320271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 320370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (kPointerSize == kInt32Size && !key->IsConstantOperand() && 320470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->IsDehoisted()) { 320570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Sign extend key because it could be a 32 bit negative value 320670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // and the dehoisted address computation happens in 64 bits 320770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ movsxlq(ToRegister(key), ToRegister(key)); 320870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 320904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (representation.IsInteger32() && SmiValuesAre32Bits() && 321071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org hinstr->elements_kind() == FAST_SMI_ELEMENTS) { 3211e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!requires_hole_check); 32122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (FLAG_debug_code) { 32132ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Register scratch = kScratchRegister; 32142ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ Load(scratch, 32152ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org BuildFastArrayOperand(instr->elements(), 32162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org key, 321770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 32182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org FAST_ELEMENTS, 3219fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org offset), 32202ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Representation::Smi()); 32212ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ AssertSmi(scratch); 32222ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 322371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org // Read int value directly from upper half of the smi. 322471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org STATIC_ASSERT(kSmiTag == 0); 3225e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kSmiTagSize + kSmiShiftSize == 32); 322671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org offset += kPointerSize / 2; 322771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } 322871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 322971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ Load(result, 3230e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org BuildFastArrayOperand(instr->elements(), key, 323170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 3232e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org FAST_ELEMENTS, offset), 323371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org representation); 3234e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3235e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org // Check for the hole value. 323671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (requires_hole_check) { 323771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (IsFastSmiElementsKind(hinstr->elements_kind())) { 3238e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Condition smi = __ CheckSmi(result); 323906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(NegateCondition(smi), instr, "not a Smi"); 3240e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 3241e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 324206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 3243e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 3244e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 3245e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 3246e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3247e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3248e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { 32495c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org if (instr->is_typed_elements()) { 3250e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoLoadKeyedExternalArray(instr); 3251e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else if (instr->hydrogen()->representation().IsDouble()) { 3252e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoLoadKeyedFixedDoubleArray(instr); 3253e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 3254e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoLoadKeyedFixedArray(instr); 3255e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 3256e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 3257e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3258e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3259717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.orgOperand LCodeGen::BuildFastArrayOperand( 3260b645116853c677aca8a316381b87441ba6004f67danno@chromium.org LOperand* elements_pointer, 32616d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org LOperand* key, 326270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Representation key_representation, 326383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ElementsKind elements_kind, 3264fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org uint32_t offset) { 3265b645116853c677aca8a316381b87441ba6004f67danno@chromium.org Register elements_pointer_reg = ToRegister(elements_pointer); 32666d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org int shift_size = ElementsKindToShiftSize(elements_kind); 326783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (key->IsConstantOperand()) { 3268594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int32_t constant_value = ToInteger32(LConstantOperand::cast(key)); 326983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (constant_value & 0xF0000000) { 3270594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kArrayIndexConstantValueTooBig); 327183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 3272b645116853c677aca8a316381b87441ba6004f67danno@chromium.org return Operand(elements_pointer_reg, 3273fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org (constant_value << shift_size) + offset); 327483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 327570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Take the tag bit into account while computing the shift size. 327670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (key_representation.IsSmi() && (shift_size >= 1)) { 3277e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(SmiValuesAre31Bits()); 327870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org shift_size -= kSmiTagSize; 327970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 328083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); 32810e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org return Operand(elements_pointer_reg, 32820e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org ToRegister(key), 32830e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org scale_factor, 3284fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org offset); 328583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 3286c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3287c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3288c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3289c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 3290e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 32919aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); 32929aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DCHECK(ToRegister(instr->key()).is(LoadDescriptor::NameRegister())); 32933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 32949d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org if (FLAG_vector_ics) { 32956474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr); 32969d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org } 32979d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org 32986313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); 32993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 3300c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3301c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3302c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3303c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 330449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org Register result = ToRegister(instr->result()); 330549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 330628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (instr->hydrogen()->from_inlined()) { 3307895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(result, Operand(rsp, -kFPOnStackSize + -kPCOnStackSize)); 330828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } else { 330928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Check for arguments adapter frame. 331028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label done, adapted; 331143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 331228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ Cmp(Operand(result, StandardFrameConstants::kContextOffset), 331328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 331428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ j(equal, &adapted, Label::kNear); 331528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 331628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // No arguments adaptor frame. 331743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, rbp); 331828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ jmp(&done, Label::kNear); 331949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 332028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Arguments adaptor frame present. 332128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ bind(&adapted); 332243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 3323b2a1c078e6f552a66c1426482a3d007b7ea7af7ddanno@chromium.org 332428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Result is the frame pointer for the frame if not adapted and for the real 332528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // frame below the adaptor frame if adapted. 332628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ bind(&done); 332728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 3328c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3329c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3330c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3331c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 333249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org Register result = ToRegister(instr->result()); 333349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 333483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 333549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 333649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // If no arguments adaptor frame the number of arguments is fixed. 333756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org if (instr->elements()->IsRegister()) { 33387a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rbp, ToRegister(instr->elements())); 333949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } else { 33407a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rbp, ToOperand(instr->elements())); 334149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 3342a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org __ movl(result, Immediate(scope()->num_parameters())); 334383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &done, Label::kNear); 334449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 334549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Arguments adaptor frame present. Get argument length from there. 334643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 3347a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org __ SmiToInteger32(result, 3348a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org Operand(result, 3349a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org ArgumentsAdaptorFrameConstants::kLengthOffset)); 335049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 335149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Argument length is in result register. 335249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org __ bind(&done); 3353c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3354c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3355c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3356154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgvoid LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 33573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register receiver = ToRegister(instr->receiver()); 33583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register function = ToRegister(instr->function()); 33593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 3360d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // If the receiver is null or undefined, we have to pass the global 3361d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // object as a receiver to normal functions. Values have to be 3362d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // passed unchanged to builtins and strict-mode functions. 336383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label global_object, receiver_ok; 3364935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 3365d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 336657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (!instr->hydrogen()->known_function()) { 336757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // Do not transform the receiver to object for strict mode 336857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // functions. 336957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ movp(kScratchRegister, 337057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 337157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ testb(FieldOperand(kScratchRegister, 337257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org SharedFunctionInfo::kStrictModeByteOffset), 337357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte)); 337457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ j(not_equal, &receiver_ok, dist); 337557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 337657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // Do not transform the receiver to object for builtins. 337757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ testb(FieldOperand(kScratchRegister, 337857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org SharedFunctionInfo::kNativeByteOffset), 337957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte)); 338057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ j(not_equal, &receiver_ok, dist); 338157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 3382d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 3383d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // Normal function. Replace undefined or null with global receiver. 33843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ CompareRoot(receiver, Heap::kNullValueRootIndex); 338583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &global_object, Label::kNear); 33863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ CompareRoot(receiver, Heap::kUndefinedValueRootIndex); 338783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &global_object, Label::kNear); 33883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 33893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // The receiver should be a JS object. 33903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Condition is_smi = __ CheckSmi(receiver); 339106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(is_smi, instr, "Smi"); 3392d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, kScratchRegister); 339306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(below, instr, "not a JavaScript object"); 33943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 339557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ jmp(&receiver_ok, Label::kNear); 33963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&global_object); 339743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(receiver, FieldOperand(function, JSFunction::kContextOffset)); 339843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(receiver, 339957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Operand(receiver, 340057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 340158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ movp(receiver, FieldOperand(receiver, GlobalObject::kGlobalProxyOffset)); 340257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 34033a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&receiver_ok); 3404154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org} 3405154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 3406154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 3407154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgvoid LCodeGen::DoApplyArguments(LApplyArguments* instr) { 3408154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Register receiver = ToRegister(instr->receiver()); 3409154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Register function = ToRegister(instr->function()); 3410154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Register length = ToRegister(instr->length()); 3411154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Register elements = ToRegister(instr->elements()); 3412e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(receiver.is(rax)); // Used for parameter count. 3413e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(function.is(rdi)); // Required by InvokeFunction. 3414e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rax)); 34153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 34163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Copy the arguments to this function possibly from the 34173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // adaptor frame below it. 34183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org const uint32_t kArgumentsLimit = 1 * KB; 34197a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(length, Immediate(kArgumentsLimit)); 342006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(above, instr, "too many arguments"); 34213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 3422763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(receiver); 342343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(receiver, length); 34243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 34253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Loop through the arguments pushing them onto the execution 34263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // stack. 342783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label invoke, loop; 34283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // length is a small non-negative integer, due to the test above. 34293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ testl(length, length); 343083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(zero, &invoke, Label::kNear); 34313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&loop); 3432d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StackArgumentsAccessor args(elements, length, 3433d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ARGUMENTS_DONT_CONTAIN_RECEIVER); 3434763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(args.GetArgumentOperand(0)); 34353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ decl(length); 34363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ j(not_zero, &loop); 34373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 34383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Invoke the function. 34393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&invoke); 3440e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->HasPointerMap()); 34413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LPointerMap* pointers = instr->pointer_map(); 344227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org SafepointGenerator safepoint_generator( 344327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org this, pointers, Safepoint::kLazyDeopt); 34442efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ParameterCount actual(rax); 3445e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator); 3446c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3447c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3448c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3449c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoPushArgument(LPushArgument* instr) { 345056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* argument = instr->value(); 3451160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org EmitPushTaggedOperand(argument); 3452c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3453c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3454c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 345528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.orgvoid LCodeGen::DoDrop(LDrop* instr) { 345628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ Drop(instr->count()); 345728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org} 345828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 345928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 3460d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.orgvoid LCodeGen::DoThisFunction(LThisFunction* instr) { 3461d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org Register result = ToRegister(instr->result()); 346243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 3463d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org} 3464d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 3465d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 3466496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgvoid LCodeGen::DoContext(LContext* instr) { 3467496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org Register result = ToRegister(instr->result()); 3468935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (info()->IsOptimizing()) { 346943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, Operand(rbp, StandardFrameConstants::kContextOffset)); 3470935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else { 3471935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // If there is no frame, the context must be in rsi. 3472e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result.is(rsi)); 3473935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } 3474496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org} 3475496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3476496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 347756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.orgvoid LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 3478e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 3479763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); // The context is the first argument. 3480c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Push(instr->hydrogen()->pairs()); 348156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ Push(Smi::FromInt(instr->hydrogen()->flags())); 348247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntime(Runtime::kDeclareGlobals, 3, instr); 348356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org} 348456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org 348556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org 3486c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::CallKnownFunction(Handle<JSFunction> function, 348732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org int formal_parameter_count, 3488c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int arity, 348940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org LInstruction* instr, 3490fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org RDIState rdi_state) { 349132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org bool dont_adapt_arguments = 349232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 349332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org bool can_invoke_directly = 349432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org dont_adapt_arguments || formal_parameter_count == arity; 349583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 349683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org LPointerMap* pointers = instr->pointer_map(); 349783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 34982efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (can_invoke_directly) { 3499fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org if (rdi_state == RDI_UNINITIALIZED) { 3500c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Move(rdi, function); 3501fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org } 35022efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 3503b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org // Change context. 350443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 35052efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 35062efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Set rax to arguments count if adaption is not needed. Assumes that rax 35072efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // is available to write to at this point. 350832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (dont_adapt_arguments) { 35092efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ Set(rax, arity); 35102efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 35112efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 35122efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Invoke function. 351332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (function.is_identical_to(info()->closure())) { 35142efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ CallSelf(); 35152efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 3516f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ Call(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 35172efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 35182efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 35192efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Set up deoptimization. 35202efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); 352183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 35222efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // We need to adapt arguments. 35232efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org SafepointGenerator generator( 35242efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org this, pointers, Safepoint::kLazyDeopt); 35252efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ParameterCount count(arity); 352632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ParameterCount expected(formal_parameter_count); 3527e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ InvokeFunction(function, expected, count, CALL_FUNCTION, generator); 352883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 3529c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3530c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3531c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3532e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.orgvoid LCodeGen::DoTailCallThroughMegamorphicCache( 3533e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org LTailCallThroughMegamorphicCache* instr) { 3534e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org Register receiver = ToRegister(instr->receiver()); 3535e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org Register name = ToRegister(instr->name()); 3536e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); 3537e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org DCHECK(name.is(LoadDescriptor::NameRegister())); 3538e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org 3539e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org Register scratch = rbx; 3540e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org DCHECK(!scratch.is(receiver) && !scratch.is(name)); 3541e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org 3542e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org // Important for the tail-call. 3543e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org bool must_teardown_frame = NeedsEagerFrame(); 3544e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org 3545e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org // The probe will tail call to a handler if found. 3546e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(), 3547e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org must_teardown_frame, receiver, name, 3548e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org scratch, no_reg); 3549e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org 3550e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org // Tail call to miss if we ended up here. 3551e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org if (must_teardown_frame) __ leave(); 3552e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org LoadIC::GenerateMiss(masm()); 3553e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org} 3554e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org 3555e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org 355626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgvoid LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { 3557e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rax)); 355826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 355926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org LPointerMap* pointers = instr->pointer_map(); 356026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 356126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 356226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org if (instr->target()->IsConstantOperand()) { 356326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org LConstantOperand* target = LConstantOperand::cast(instr->target()); 356426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org Handle<Code> code = Handle<Code>::cast(ToHandle(target)); 356526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org generator.BeforeCall(__ CallSize(code)); 356626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ call(code, RelocInfo::CODE_TARGET); 356726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } else { 3568e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->target()->IsRegister()); 356926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org Register target = ToRegister(instr->target()); 357026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org generator.BeforeCall(__ CallSize(target)); 3571fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); 357226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ call(target); 357326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } 357426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org generator.AfterCall(); 357526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org} 357626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 357726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 357826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgvoid LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { 3579e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->function()).is(rdi)); 3580e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rax)); 358126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 358226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org if (instr->hydrogen()->pass_argument_count()) { 358326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ Set(rax, instr->arity()); 358426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } 358526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 358626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org // Change context. 358743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 358826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 358926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org LPointerMap* pointers = instr->pointer_map(); 359026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 359126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 359226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org bool is_self_call = false; 359326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org if (instr->hydrogen()->function()->IsConstant()) { 359426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org Handle<JSFunction> jsfun = Handle<JSFunction>::null(); 359526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org HConstant* fun_const = HConstant::cast(instr->hydrogen()->function()); 359626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org jsfun = Handle<JSFunction>::cast(fun_const->handle(isolate())); 359726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org is_self_call = jsfun.is_identical_to(info()->closure()); 359826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } 359926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 360026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org if (is_self_call) { 360126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ CallSelf(); 360226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } else { 360326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org Operand target = FieldOperand(rdi, JSFunction::kCodeEntryOffset); 360426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org generator.BeforeCall(__ CallSize(target)); 3605f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ Call(target); 360626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } 360726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org generator.AfterCall(); 3608c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3609c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3610c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3611e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 361256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input_reg = ToRegister(instr->value()); 36135d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 36145d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org Heap::kHeapNumberMapRootIndex); 361506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number"); 36165d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 3617fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Label slow, allocated, done; 36185d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org Register tmp = input_reg.is(rax) ? rcx : rax; 36195d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx; 36205d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36215d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Preserve the value of all registers. 362244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 36235d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36245d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ movl(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 36255d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Check the sign of the argument. If the argument is positive, just 36265d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // return it. We do not need to patch the stack since |input| and 36275d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // |result| are the same register and |input| will be restored 36285d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // unchanged by popping safepoint registers. 36295d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ testl(tmp, Immediate(HeapNumber::kSignMask)); 3630fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ j(zero, &done); 36315d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36325d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ AllocateHeapNumber(tmp, tmp2, &slow); 3633fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ jmp(&allocated, Label::kNear); 36345d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36355d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Slow case: Call the runtime system to do the number allocation. 36365d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ bind(&slow); 3637935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org CallRuntimeFromDeferred( 363847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org Runtime::kAllocateHeapNumber, 0, instr, instr->context()); 36395d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Set the pointer to the new heap number in tmp. 364043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org if (!tmp.is(rax)) __ movp(tmp, rax); 36415d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Restore input_reg after call to runtime. 36425d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ LoadFromSafepointRegisterSlot(input_reg, input_reg); 36435d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36445d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ bind(&allocated); 3645bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset)); 36462f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ shlq(tmp2, Immediate(1)); 36472f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ shrq(tmp2, Immediate(1)); 3648bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); 36495d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ StoreToSafepointRegisterSlot(input_reg, tmp); 36505d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36515d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ bind(&done); 36525d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org} 36535d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36545d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 3655e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { 365656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input_reg = ToRegister(instr->value()); 36575d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ testl(input_reg, input_reg); 36585d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org Label is_positive; 3659fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ j(not_sign, &is_positive, Label::kNear); 36605d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ negl(input_reg); // Sets flags. 366106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(negative, instr, "overflow"); 36625d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ bind(&is_positive); 3663c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3664c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3665c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3666594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::EmitSmiMathAbs(LMathAbs* instr) { 3667594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Register input_reg = ToRegister(instr->value()); 36687a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(input_reg, input_reg); 3669594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label is_positive; 3670594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ j(not_sign, &is_positive, Label::kNear); 36717a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ negp(input_reg); // Sets flags. 367206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(negative, instr, "overflow"); 3673594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ bind(&is_positive); 3674594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 3675594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 3676594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 3677e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathAbs(LMathAbs* instr) { 36785d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Class for deferred case. 3679ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredMathAbsTaggedHeapNumber FINAL : public LDeferredCode { 36805d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org public: 3681e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) 36825d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org : LDeferredCode(codegen), instr_(instr) { } 3683ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 36845d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 36855d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } 3686ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 36875d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org private: 3688e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org LMathAbs* instr_; 36895d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org }; 36905d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 3691e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->value()->Equals(instr->result())); 36925d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org Representation r = instr->hydrogen()->value()->representation(); 36935d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36945d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org if (r.IsDouble()) { 3695528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister scratch = double_scratch0(); 369656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 3697160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ xorps(scratch, scratch); 36985d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ subsd(scratch, input_reg); 3699ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org __ andps(input_reg, scratch); 37005d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } else if (r.IsInteger32()) { 37015d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org EmitIntegerMathAbs(instr); 3702594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else if (r.IsSmi()) { 3703594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org EmitSmiMathAbs(instr); 37045d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } else { // Tagged case. 37055d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org DeferredMathAbsTaggedHeapNumber* deferred = 37067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); 370756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input_reg = ToRegister(instr->value()); 37085d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Smi check. 37095d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ JumpIfNotSmi(input_reg, deferred->entry()); 3710594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org EmitSmiMathAbs(instr); 37115d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ bind(deferred->exit()); 37125d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } 3713c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3714c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3715c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3716e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathFloor(LMathFloor* instr) { 3717528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 37183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register output_reg = ToRegister(instr->result()); 371956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 37203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 3721160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (CpuFeatures::IsSupported(SSE4_1)) { 3722750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE4_1); 3723160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3724160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // Deoptimize if minus zero. 3725160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ movq(output_reg, input_reg); 3726160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ subq(output_reg, Immediate(1)); 372706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(overflow, instr, "minus zero"); 3728160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 3729160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown); 3730160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ cvttsd2si(output_reg, xmm_scratch); 3731a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ cmpl(output_reg, Immediate(0x1)); 373206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 37333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 37347a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org Label negative_sign, done; 37358432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // Deoptimize on unordered. 3736160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ xorps(xmm_scratch, xmm_scratch); // Zero the register. 3737160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ ucomisd(input_reg, xmm_scratch); 373806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(parity_even, instr, "NaN"); 37397a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ j(below, &negative_sign, Label::kNear); 37407a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 3741160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 37424acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Check for negative zero. 37434acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Label positive_sign; 37444acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ j(above, &positive_sign, Label::kNear); 37454acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ movmskpd(output_reg, input_reg); 37464acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ testq(output_reg, Immediate(1)); 374706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_zero, instr, "minus zero"); 37484acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ Set(output_reg, 0); 37495924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org __ jmp(&done); 37504acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ bind(&positive_sign); 3751160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 37523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 3753160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // Use truncating instruction (OK because input is positive). 3754160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ cvttsd2si(output_reg, input_reg); 3755160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // Overflow is signalled with minint. 3756a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ cmpl(output_reg, Immediate(0x1)); 375706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 37587a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ jmp(&done, Label::kNear); 37597a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 37607a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org // Non-zero negative reaches here. 37617a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ bind(&negative_sign); 37627a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org // Truncate, then compare and compensate. 37637a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ cvttsd2si(output_reg, input_reg); 3764528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Cvtlsi2sd(xmm_scratch, output_reg); 37657a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ ucomisd(input_reg, xmm_scratch); 37667a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ j(equal, &done, Label::kNear); 37677a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ subl(output_reg, Immediate(1)); 376806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 37697a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 37707a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ bind(&done); 3771160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 3772c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3773c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3774c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3775e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathRound(LMathRound* instr) { 3776528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org const XMMRegister xmm_scratch = double_scratch0(); 37773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register output_reg = ToRegister(instr->result()); 377856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 3779381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org XMMRegister input_temp = ToDoubleRegister(instr->temp()); 37808432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org static int64_t one_half = V8_INT64_C(0x3FE0000000000000); // 0.5 37818432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org static int64_t minus_one_half = V8_INT64_C(0xBFE0000000000000); // -0.5 37823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 3783381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org Label done, round_to_zero, below_one_half; 3784935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 3785e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movq(kScratchRegister, one_half); 37863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ movq(xmm_scratch, kScratchRegister); 37874a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ ucomisd(xmm_scratch, input_reg); 3788935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(above, &below_one_half, Label::kNear); 37894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 37904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x). 37914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ addsd(xmm_scratch, input_reg); 37924a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ cvttsd2si(output_reg, xmm_scratch); 37934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Overflow is signalled with minint. 3794a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ cmpl(output_reg, Immediate(0x1)); 379506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 3796935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&done, dist); 37973a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 37984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ bind(&below_one_half); 3799e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movq(kScratchRegister, minus_one_half); 38004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ movq(xmm_scratch, kScratchRegister); 38014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ ucomisd(xmm_scratch, input_reg); 3802935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(below_equal, &round_to_zero, Label::kNear); 38038432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 38044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then 38054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // compare and compensate. 3806381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org __ movq(input_temp, input_reg); // Do not alter input_reg. 3807381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org __ subsd(input_temp, xmm_scratch); 3808381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org __ cvttsd2si(output_reg, input_temp); 38094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Catch minint due to overflow, and to prevent overflow when compensating. 3810a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ cmpl(output_reg, Immediate(0x1)); 381106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 38128432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 3813528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Cvtlsi2sd(xmm_scratch, output_reg); 3814381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org __ ucomisd(xmm_scratch, input_temp); 3815381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org __ j(equal, &done, dist); 38164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ subl(output_reg, Immediate(1)); 38174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // No overflow because we already ruled out minint. 3818935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&done, dist); 38193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 38204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ bind(&round_to_zero); 38214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if 38224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // we can ignore the difference between a result of -0 and +0. 38234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 38244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ movq(output_reg, input_reg); 38254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ testq(output_reg, output_reg); 382606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(negative, instr, "minus zero"); 38278432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org } 38284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Set(output_reg, 0); 38294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ bind(&done); 3830c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3831c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3832c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3833dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid LCodeGen::DoMathFround(LMathFround* instr) { 3834dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 3835dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org XMMRegister output_reg = ToDoubleRegister(instr->result()); 3836dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org __ cvtsd2ss(output_reg, input_reg); 3837dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org __ cvtss2sd(output_reg, output_reg); 3838dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org} 3839dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org 3840dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org 3841e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathSqrt(LMathSqrt* instr) { 38427e6132b924829c353864933f29124419916db550machenbach@chromium.org XMMRegister output = ToDoubleRegister(instr->result()); 38437e6132b924829c353864933f29124419916db550machenbach@chromium.org if (instr->value()->IsDoubleRegister()) { 38447e6132b924829c353864933f29124419916db550machenbach@chromium.org XMMRegister input = ToDoubleRegister(instr->value()); 38457e6132b924829c353864933f29124419916db550machenbach@chromium.org __ sqrtsd(output, input); 38467e6132b924829c353864933f29124419916db550machenbach@chromium.org } else { 38477e6132b924829c353864933f29124419916db550machenbach@chromium.org Operand input = ToOperand(instr->value()); 38487e6132b924829c353864933f29124419916db550machenbach@chromium.org __ sqrtsd(output, input); 38497e6132b924829c353864933f29124419916db550machenbach@chromium.org } 3850c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3851c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3852c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3853e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { 3854528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 385556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 3856e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToDoubleRegister(instr->result()).is(input_reg)); 385764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 385864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Note that according to ECMA-262 15.8.2.13: 385964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Math.pow(-Infinity, 0.5) == Infinity 386064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Math.sqrt(-Infinity) == NaN 386164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label done, sqrt; 386264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Check base for -Infinity. According to IEEE-754, double-precision 386364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // -Infinity has the highest 12 bits set and the lowest 52 bits cleared. 3864e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movq(kScratchRegister, V8_INT64_C(0xFFF0000000000000)); 386564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ movq(xmm_scratch, kScratchRegister); 386664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ ucomisd(xmm_scratch, input_reg); 386764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Comparing -Infinity with NaN results in "unordered", which sets the 386864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // zero flag as if both were equal. However, it also sets the carry flag. 386964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ j(not_equal, &sqrt, Label::kNear); 387064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ j(carry, &sqrt, Label::kNear); 387164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // If input is -Infinity, return Infinity. 387264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ xorps(input_reg, input_reg); 387364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ subsd(input_reg, xmm_scratch); 387464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ jmp(&done, Label::kNear); 387564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 387664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Square root. 387764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&sqrt); 3878160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ xorps(xmm_scratch, xmm_scratch); 38793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ addsd(input_reg, xmm_scratch); // Convert -0 to +0. 38803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ sqrtsd(input_reg, input_reg); 388164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&done); 3882c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3883c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3884c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3885c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoPower(LPower* instr) { 38869ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org Representation exponent_type = instr->hydrogen()->right()->representation(); 388764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Having marked this as a call, we can use any registers. 388864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Just make sure that the input/output registers are the expected ones. 388964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 38906313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Register tagged_exponent = MathPowTaggedDescriptor::exponent(); 3891e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->right()->IsRegister() || 38926313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org ToRegister(instr->right()).is(tagged_exponent)); 3893e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->right()->IsDoubleRegister() || 389456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ToDoubleRegister(instr->right()).is(xmm1)); 3895e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToDoubleRegister(instr->left()).is(xmm2)); 3896e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToDoubleRegister(instr->result()).is(xmm3)); 389764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 389853ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (exponent_type.IsSmi()) { 3899f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org MathPowStub stub(isolate(), MathPowStub::TAGGED); 390053ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org __ CallStub(&stub); 390153ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org } else if (exponent_type.IsTagged()) { 390264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label no_deopt; 39036313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org __ JumpIfSmi(tagged_exponent, &no_deopt, Label::kNear); 39046313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org __ CmpObjectType(tagged_exponent, HEAP_NUMBER_TYPE, rcx); 390506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number"); 390664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&no_deopt); 3907f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org MathPowStub stub(isolate(), MathPowStub::TAGGED); 390864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CallStub(&stub); 390964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (exponent_type.IsInteger32()) { 3910f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org MathPowStub stub(isolate(), MathPowStub::INTEGER); 391164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CallStub(&stub); 391264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 3913e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(exponent_type.IsDouble()); 3914f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org MathPowStub stub(isolate(), MathPowStub::DOUBLE); 391564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CallStub(&stub); 39169ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 3917c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3918c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3919c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 39201f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgvoid LCodeGen::DoMathExp(LMathExp* instr) { 39211f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister input = ToDoubleRegister(instr->value()); 39221f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister result = ToDoubleRegister(instr->result()); 3923528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister temp0 = double_scratch0(); 39241f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org Register temp1 = ToRegister(instr->temp1()); 39251f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org Register temp2 = ToRegister(instr->temp2()); 39261f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 3927528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org MathExpGenerator::EmitMathExp(masm(), input, result, temp0, temp1, temp2); 39281f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org} 39291f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 39301f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 3931e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathLog(LMathLog* instr) { 3932e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->value()->Equals(instr->result())); 39330fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 39340fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org XMMRegister xmm_scratch = double_scratch0(); 39350fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org Label positive, done, zero; 39360fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ xorps(xmm_scratch, xmm_scratch); 39370fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ ucomisd(input_reg, xmm_scratch); 39380fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ j(above, &positive, Label::kNear); 39394f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org __ j(not_carry, &zero, Label::kNear); 39400fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org ExternalReference nan = 39410fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org ExternalReference::address_of_canonical_non_hole_nan(); 39420fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org Operand nan_operand = masm()->ExternalOperand(nan); 39430fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(input_reg, nan_operand); 39440fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ jmp(&done, Label::kNear); 39450fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ bind(&zero); 39460fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org ExternalReference ninf = 39470fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org ExternalReference::address_of_negative_infinity(); 39480fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org Operand ninf_operand = masm()->ExternalOperand(ninf); 39490fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(input_reg, ninf_operand); 39500fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ jmp(&done, Label::kNear); 39510fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ bind(&positive); 39520fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ fldln2(); 3953fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rsp, Immediate(kDoubleSize)); 39540fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(Operand(rsp, 0), input_reg); 39550fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ fld_d(Operand(rsp, 0)); 39560fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ fyl2x(); 39570fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ fstp_d(Operand(rsp, 0)); 39580fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(input_reg, Operand(rsp, 0)); 3959fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rsp, Immediate(kDoubleSize)); 39600fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ bind(&done); 3961c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3962c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3963c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3964f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid LCodeGen::DoMathClz32(LMathClz32* instr) { 3965f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register input = ToRegister(instr->value()); 3966f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register result = ToRegister(instr->result()); 3967f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Label not_zero_input; 3968f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ bsrl(result, input); 3969f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3970f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ j(not_zero, ¬_zero_input); 3971f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ Set(result, 63); // 63^31 == 32 3972f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3973f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ bind(¬_zero_input); 3974f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ xorl(result, Immediate(31)); // for x in [0..31], 31^x == 31-x. 3975f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 3976f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3977f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3978160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgvoid LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 3979e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 3980e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->function()).is(rdi)); 3981e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->HasPointerMap()); 3982fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org 398332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 398432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (known_function.is_null()) { 3985fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org LPointerMap* pointers = instr->pointer_map(); 3986fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3987fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org ParameterCount count(instr->arity()); 3988e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ InvokeFunction(rdi, count, CALL_FUNCTION, generator); 3989fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org } else { 399032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CallKnownFunction(known_function, 399132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->hydrogen()->formal_parameter_count(), 3992fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr->arity(), 3993fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr, 3994fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org RDI_CONTAINS_TARGET); 3995fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org } 3996160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org} 3997160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 3998160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 3999c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCallFunction(LCallFunction* instr) { 4000e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 4001e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->function()).is(rdi)); 4002e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rax)); 40033a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 40043a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int arity = instr->arity(); 4005f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags()); 4006f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 4007c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4008c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4009c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4010c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCallNew(LCallNew* instr) { 4011e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 4012e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->constructor()).is(rdi)); 4013e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rax)); 4014378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 4015378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org __ Set(rax, instr->arity()); 40161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // No cell in ebx for construct type feedback in optimized code 40175697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); 4018a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS); 4019f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 4020c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4021c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4022c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 40234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid LCodeGen::DoCallNewArray(LCallNewArray* instr) { 4024e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 4025e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->constructor()).is(rdi)); 4026e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(rax)); 40274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 40284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Set(rax, instr->arity()); 40295697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); 403057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ElementsKind kind = instr->hydrogen()->elements_kind(); 40311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org AllocationSiteOverrideMode override_mode = 4032bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) 40331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? DISABLE_ALLOCATION_SITES 40341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org : DONT_OVERRIDE; 4035d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 4036ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if (instr->arity() == 0) { 4037f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode); 4038f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 4039ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else if (instr->arity() == 1) { 404041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Label done; 404141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (IsFastPackedElementsKind(kind)) { 404241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Label packed_case; 404341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // We might need a change here 404441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // look at the first argument 404543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, Operand(rsp, 0)); 40467a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rcx, rcx); 4047935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(zero, &packed_case, Label::kNear); 404841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 404941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ElementsKind holey_kind = GetHoleyElementsKind(kind); 4050f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org ArraySingleArgumentConstructorStub stub(isolate(), 4051f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org holey_kind, 4052f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org override_mode); 4053f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 4054935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&done, Label::kNear); 405541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ bind(&packed_case); 405641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } 405741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 4058f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); 4059f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 406041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ bind(&done); 4061ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else { 4062f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); 4063f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 4064ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 40654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 40664a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 40674a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 4068c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCallRuntime(LCallRuntime* instr) { 4069e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 4070fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles()); 4071c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4072c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4073c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4074662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgvoid LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) { 4075662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org Register function = ToRegister(instr->function()); 4076662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org Register code_object = ToRegister(instr->code_object()); 4077895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(code_object, FieldOperand(code_object, Code::kHeaderSize)); 407843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(function, JSFunction::kCodeEntryOffset), code_object); 4079662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org} 4080662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 4081662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 40822bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { 40832bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result = ToRegister(instr->result()); 40842bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register base = ToRegister(instr->base_object()); 4085ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (instr->offset()->IsConstantOperand()) { 4086ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org LConstantOperand* offset = LConstantOperand::cast(instr->offset()); 4087895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(result, Operand(base, ToInteger32(offset))); 4088ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else { 4089ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Register offset = ToRegister(instr->offset()); 4090895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(result, Operand(base, offset, times_1, 0)); 4091ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 40922bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org} 40932bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 40942bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 4095c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 409671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org HStoreNamedField* hinstr = instr->hydrogen(); 4097f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Representation representation = instr->representation(); 4098f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 409971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org HObjectAccess access = hinstr->access(); 410053ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org int offset = access.offset(); 4101378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 4102d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (access.IsExternalMemory()) { 4103e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!hinstr->NeedsWriteBarrier()); 4104d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register value = ToRegister(instr->value()); 4105d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->object()->IsConstantOperand()) { 4106e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value.is(rax)); 4107d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org LConstantOperand* object = LConstantOperand::cast(instr->object()); 4108d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ store_rax(ToExternalReference(object)); 4109d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 4110d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register object = ToRegister(instr->object()); 4111d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org __ Store(MemOperand(object, offset), value, representation); 4112d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 4113d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return; 4114d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 4115d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 4116d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register object = ToRegister(instr->object()); 4117d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org __ AssertNotSmi(object); 4118f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 4119e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!representation.IsSmi() || 4120d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org !instr->value()->IsConstantOperand() || 4121d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org IsInteger32Constant(LConstantOperand::cast(instr->value()))); 4122d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org if (representation.IsDouble()) { 4123e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(access.IsInobject()); 4124e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!hinstr->has_transition()); 4125e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!hinstr->NeedsWriteBarrier()); 412657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org XMMRegister value = ToDoubleRegister(instr->value()); 412757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movsd(FieldOperand(object, offset), value); 412857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org return; 4129f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 4130f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 4131c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org if (hinstr->has_transition()) { 4132c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org Handle<Map> transition = hinstr->transition_map(); 4133c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org AddDeprecationDependency(transition); 413471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (!hinstr->NeedsWriteBarrierForMap()) { 4135f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ Move(FieldOperand(object, HeapObject::kMapOffset), transition); 413637141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org } else { 413756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 4138f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ Move(kScratchRegister, transition); 413943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister); 414037141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org // Update the write barrier for the map field. 4141196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org __ RecordWriteForMap(object, 4142196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kScratchRegister, 4143196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org temp, 4144196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kSaveFPRegs); 414537141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org } 4146378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 4147378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 4148378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Do the store. 414977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Register write_register = object; 415053ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (!access.IsInobject()) { 415177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org write_register = ToRegister(instr->temp()); 415243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); 415377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 415477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 415504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (representation.IsSmi() && SmiValuesAre32Bits() && 415671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org hinstr->value()->representation().IsInteger32()) { 4157e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); 41582ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (FLAG_debug_code) { 41592ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Register scratch = kScratchRegister; 41602ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ Load(scratch, FieldOperand(write_register, offset), representation); 41612ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ AssertSmi(scratch); 41622ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 416371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org // Store int value directly to upper half of the smi. 416471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org STATIC_ASSERT(kSmiTag == 0); 4165e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kSmiTagSize + kSmiShiftSize == 32); 416671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org offset += kPointerSize / 2; 416771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org representation = Representation::Integer32(); 416871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } 416971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 417071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org Operand operand = FieldOperand(write_register, offset); 417171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 417271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (instr->value()->IsRegister()) { 417371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org Register value = ToRegister(instr->value()); 417471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ Store(operand, value, representation); 417571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } else { 417677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 417771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (IsInteger32Constant(operand_value)) { 4178e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!hinstr->NeedsWriteBarrier()); 41790cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org int32_t value = ToInteger32(operand_value); 418071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (representation.IsSmi()) { 418171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ Move(operand, Smi::FromInt(value)); 418271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 418371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } else { 418471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ movl(operand, Immediate(value)); 418571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } 418671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 418777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 418832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Handle<Object> handle_value = ToHandle(operand_value); 4189e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!hinstr->NeedsWriteBarrier()); 419071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ Move(operand, handle_value); 4191378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 419277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 419377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 419471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (hinstr->NeedsWriteBarrier()) { 419577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Register value = ToRegister(instr->value()); 419653ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object; 419777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // Update the write barrier for the object for in-object properties. 419877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ RecordWriteField(write_register, 419977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org offset, 420077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org value, 420177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org temp, 420277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org kSaveFPRegs, 420377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org EMIT_REMEMBERED_SET, 4204196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org hinstr->SmiCheckForWriteBarrier(), 4205196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org hinstr->PointersToHereCheckForValue()); 4206378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 4207c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4208c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4209c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4210c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { 4211e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 42129aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister())); 42139aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); 42143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 42159aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org __ Move(StoreDescriptor::NameRegister(), instr->hydrogen()->name()); 4216486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode()); 42173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 42183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 42193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 42203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 4221c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 4222a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Representation representation = instr->hydrogen()->length()->representation(); 4223e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(representation.Equals(instr->hydrogen()->index()->representation())); 4224e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(representation.IsSmiOrInteger32()); 42257c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 4226a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Condition cc = instr->hydrogen()->allow_equality() ? below : below_equal; 4227a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org if (instr->length()->IsConstantOperand()) { 4228a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org int32_t length = ToInteger32(LConstantOperand::cast(instr->length())); 4229a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Register index = ToRegister(instr->index()); 4230a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org if (representation.IsSmi()) { 4231a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ Cmp(index, Smi::FromInt(length)); 4232a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org } else { 4233a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpl(index, Immediate(length)); 4234a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org } 423538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org cc = CommuteCondition(cc); 4236a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org } else if (instr->index()->IsConstantOperand()) { 4237a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org int32_t index = ToInteger32(LConstantOperand::cast(instr->index())); 4238a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org if (instr->length()->IsRegister()) { 4239a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Register length = ToRegister(instr->length()); 424050bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org if (representation.IsSmi()) { 4241a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ Cmp(length, Smi::FromInt(index)); 4242000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org } else { 4243a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpl(length, Immediate(index)); 4244000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org } 4245b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } else { 4246a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Operand length = ToOperand(instr->length()); 424750bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org if (representation.IsSmi()) { 4248a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ Cmp(length, Smi::FromInt(index)); 424950bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org } else { 4250a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpl(length, Immediate(index)); 4251f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 4252b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } 425383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 4254a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Register index = ToRegister(instr->index()); 4255a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org if (instr->length()->IsRegister()) { 4256a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Register length = ToRegister(instr->length()); 425750bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org if (representation.IsSmi()) { 4258a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpp(length, index); 425933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } else { 4260a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpl(length, index); 426133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 4262b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } else { 4263a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Operand length = ToOperand(instr->length()); 426450bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org if (representation.IsSmi()) { 4265a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpp(length, index); 426650bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org } else { 4267a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpl(length, index); 426850bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org } 4269b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } 427083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 4271a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org if (FLAG_debug_code && instr->hydrogen()->skip_check()) { 4272a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Label done; 4273a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ j(NegateCondition(cc), &done, Label::kNear); 4274a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ int3(); 4275a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ bind(&done); 4276a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org } else { 427706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(cc, instr, "out of bounds"); 4278a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org } 4279c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4280c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4281c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4282e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4283e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org ElementsKind elements_kind = instr->elements_kind(); 4284304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org LOperand* key = instr->key(); 428570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (kPointerSize == kInt32Size && !key->IsConstantOperand()) { 428670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Register key_reg = ToRegister(key); 428770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Representation key_representation = 428870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(); 428970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (ExternalArrayOpRequiresTemp(key_representation, elements_kind)) { 429070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ SmiToInteger64(key_reg, key_reg); 429170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } else if (instr->hydrogen()->IsDehoisted()) { 429270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Sign extend key because it could be a 32 bit negative value 429370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // and the dehoisted address computation happens in 64 bits 429470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ movsxlq(key_reg, key_reg); 429570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 429670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 4297e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Operand operand(BuildFastArrayOperand( 4298e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->elements(), 4299e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org key, 430070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 4301e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org elements_kind, 4302fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org instr->base_offset())); 4303d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 4304af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || 43055c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org elements_kind == FLOAT32_ELEMENTS) { 4306e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org XMMRegister value(ToDoubleRegister(instr->value())); 4307e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ cvtsd2ss(value, value); 4308e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movss(operand, value); 4309af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || 43105c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org elements_kind == FLOAT64_ELEMENTS) { 4311e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movsd(operand, ToDoubleRegister(instr->value())); 4312304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } else { 4313e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Register value(ToRegister(instr->value())); 4314e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org switch (elements_kind) { 4315af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT8_CLAMPED_ELEMENTS: 4316af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_INT8_ELEMENTS: 4317af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT8_ELEMENTS: 43185c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case INT8_ELEMENTS: 43195c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT8_ELEMENTS: 43205c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT8_CLAMPED_ELEMENTS: 4321e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movb(operand, value); 4322e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 4323af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_INT16_ELEMENTS: 4324af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT16_ELEMENTS: 43255c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case INT16_ELEMENTS: 43265c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT16_ELEMENTS: 4327e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movw(operand, value); 4328e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 4329af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_INT32_ELEMENTS: 4330af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT32_ELEMENTS: 43315c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case INT32_ELEMENTS: 43325c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT32_ELEMENTS: 4333e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movl(operand, value); 4334e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 4335af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_FLOAT32_ELEMENTS: 4336af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_FLOAT64_ELEMENTS: 43375c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case FLOAT32_ELEMENTS: 43385c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case FLOAT64_ELEMENTS: 4339e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_ELEMENTS: 4340e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_SMI_ELEMENTS: 4341e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_DOUBLE_ELEMENTS: 4342e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_ELEMENTS: 4343e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_SMI_ELEMENTS: 4344e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_DOUBLE_ELEMENTS: 4345e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case DICTIONARY_ELEMENTS: 4346486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org case SLOPPY_ARGUMENTS_ELEMENTS: 4347e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org UNREACHABLE(); 4348e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 4349e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 4350d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 4351c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4352c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4353c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4354e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { 4355717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org XMMRegister value = ToDoubleRegister(instr->value()); 4356304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org LOperand* key = instr->key(); 435770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (kPointerSize == kInt32Size && !key->IsConstantOperand() && 435870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->IsDehoisted()) { 435970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Sign extend key because it could be a 32 bit negative value 436070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // and the dehoisted address computation happens in 64 bits 436170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ movsxlq(ToRegister(key), ToRegister(key)); 436270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 436328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (instr->NeedsCanonicalization()) { 436428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label have_value; 4365717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 436628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ ucomisd(value, value); 4367935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(parity_odd, &have_value, Label::kNear); // NaN. 436828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 4369e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org __ Set(kScratchRegister, 4370e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org bit_cast<uint64_t>( 4371e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org FixedDoubleArray::canonical_not_the_hole_nan_as_double())); 437228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ movq(value, kScratchRegister); 437328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 437428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ bind(&have_value); 437528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 4376717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 4377717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org Operand double_store_operand = BuildFastArrayOperand( 43780e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org instr->elements(), 4379304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org key, 438070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 43810e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org FAST_DOUBLE_ELEMENTS, 4382fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org instr->base_offset()); 43830e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org 4384717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org __ movsd(double_store_operand, value); 4385717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org} 4386717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 4387e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 4388e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 438971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org HStoreKeyed* hinstr = instr->hydrogen(); 4390e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org LOperand* key = instr->key(); 4391fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org int offset = instr->base_offset(); 439271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org Representation representation = hinstr->value()->representation(); 439371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 439470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (kPointerSize == kInt32Size && !key->IsConstantOperand() && 439570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->IsDehoisted()) { 439670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Sign extend key because it could be a 32 bit negative value 439770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // and the dehoisted address computation happens in 64 bits 439870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ movsxlq(ToRegister(key), ToRegister(key)); 439970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 440004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (representation.IsInteger32() && SmiValuesAre32Bits()) { 4401e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); 4402e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(hinstr->elements_kind() == FAST_SMI_ELEMENTS); 44032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (FLAG_debug_code) { 44042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Register scratch = kScratchRegister; 44052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ Load(scratch, 44062ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org BuildFastArrayOperand(instr->elements(), 44072ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org key, 440870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 44092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org FAST_ELEMENTS, 4410fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org offset), 44112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Representation::Smi()); 44122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ AssertSmi(scratch); 44132ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 441471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org // Store int value directly to upper half of the smi. 441571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org STATIC_ASSERT(kSmiTag == 0); 4416e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kSmiTagSize + kSmiShiftSize == 32); 441771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org offset += kPointerSize / 2; 441871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } 441971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 4420e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Operand operand = 4421e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org BuildFastArrayOperand(instr->elements(), 4422e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org key, 442370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 4424e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org FAST_ELEMENTS, 4425fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org offset); 442677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (instr->value()->IsRegister()) { 442771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ Store(operand, ToRegister(instr->value()), representation); 442877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 442977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 443077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (IsInteger32Constant(operand_value)) { 443171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org int32_t value = ToInteger32(operand_value); 443271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (representation.IsSmi()) { 443371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ Move(operand, Smi::FromInt(value)); 443471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 443571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } else { 443671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ movl(operand, Immediate(value)); 443771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } 443877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 443977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Handle<Object> handle_value = ToHandle(operand_value); 444077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ Move(operand, handle_value); 444177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 444277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 4443e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 444471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (hinstr->NeedsWriteBarrier()) { 444571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org Register elements = ToRegister(instr->elements()); 4446e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->value()->IsRegister()); 444777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Register value = ToRegister(instr->value()); 4448e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!key->IsConstantOperand()); 4449eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org SmiCheck check_needed = hinstr->value()->type().IsHeapObject() 44501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4451e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org // Compute address of modified element and store it into key register. 4452e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Register key_reg(ToRegister(key)); 4453895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(key_reg, operand); 4454e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ RecordWrite(elements, 4455e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org key_reg, 4456e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org value, 4457e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org kSaveFPRegs, 4458e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org EMIT_REMEMBERED_SET, 4459196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org check_needed, 4460196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org hinstr->PointersToHereCheckForValue()); 4461e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 4462e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 4463e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 4464e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 4465e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { 44665c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org if (instr->is_typed_elements()) { 4467e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoStoreKeyedExternalArray(instr); 4468e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else if (instr->hydrogen()->value()->representation().IsDouble()) { 4469e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoStoreKeyedFixedDoubleArray(instr); 4470e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 4471e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoStoreKeyedFixedArray(instr); 4472e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 4473e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 4474e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 4475e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 4476c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 4477e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 44789aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister())); 44799aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister())); 44809aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); 44813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 44826313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org Handle<Code> ic = 44836313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org CodeFactory::KeyedStoreIC(isolate(), instr->strict_mode()).code(); 44843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 44853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 44863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 44873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 4488394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 4489394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register object_reg = ToRegister(instr->object()); 4490394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 4491394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Map> from_map = instr->original_map(); 4492394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Map> to_map = instr->transitioned_map(); 4493003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ElementsKind from_kind = instr->from_kind(); 4494003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ElementsKind to_kind = instr->to_kind(); 4495394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 4496394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label not_applicable; 4497394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); 4498394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ j(not_equal, ¬_applicable); 4499830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (IsSimpleMapChangeTransition(from_kind, to_kind)) { 450094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register new_map_reg = ToRegister(instr->new_map_temp()); 45019cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org __ Move(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); 450243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); 4503394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Write barrier. 4504196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org __ RecordWriteForMap(object_reg, new_map_reg, ToRegister(instr->temp()), 4505196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kDontSaveFPRegs); 4506d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 4507e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(object_reg.is(rax)); 4508e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 450994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org PushSafepointRegistersScope scope(this); 451094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ Move(rbx, to_map); 45119801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE; 4512f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org TransitionElementsKindStub stub(isolate(), from_kind, to_kind, is_js_array); 451394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ CallStub(&stub); 45142f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0); 4515394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 4516394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(¬_applicable); 4517394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 4518394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 4519394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 452094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 452194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register object = ToRegister(instr->object()); 452294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register temp = ToRegister(instr->temp()); 4523b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Label no_memento_found; 4524b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found); 452506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(equal, instr, "memento found"); 4526b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org __ bind(&no_memento_found); 452794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 452894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 452994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 4530160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgvoid LCodeGen::DoStringAdd(LStringAdd* instr) { 4531e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 4532e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->left()).is(rdx)); 4533e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->right()).is(rax)); 4534f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org StringAddStub stub(isolate(), 4535f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org instr->hydrogen()->flags(), 453605150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org instr->hydrogen()->pretenure_flag()); 4537f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 4538160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org} 4539160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 4540160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 45413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { 4542ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredStringCharCodeAt FINAL : public LDeferredCode { 45433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org public: 45443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 45453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org : LDeferredCode(codegen), instr_(instr) { } 4546ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 454732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org codegen()->DoDeferredStringCharCodeAt(instr_); 454832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org } 4549ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 45503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org private: 45513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LStringCharCodeAt* instr_; 45523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org }; 45533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org DeferredStringCharCodeAt* deferred = 45557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredStringCharCodeAt(this, instr); 45563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org StringCharLoadGenerator::Generate(masm(), 45581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ToRegister(instr->string()), 45591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ToRegister(instr->index()), 45601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ToRegister(instr->result()), 45611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org deferred->entry()); 45623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(deferred->exit()); 45633a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 45643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { 45673a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register string = ToRegister(instr->string()); 45683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register result = ToRegister(instr->result()); 45693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 45713a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // result register contain a valid pointer because it is already 45723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // contained in the register pointer map. 45733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Set(result, 0); 45743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 457544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 4576763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(string); 45773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Push the index as a smi. This is safe because of the checks in 45783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // DoStringCharCodeAt above. 45793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); 45803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (instr->index()->IsConstantOperand()) { 4581594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index())); 45823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Push(Smi::FromInt(const_index)); 45833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 45843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register index = ToRegister(instr->index()); 45853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Integer32ToSmi(index, index); 4586763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(index); 45873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 4588935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org CallRuntimeFromDeferred( 458947390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org Runtime::kStringCharCodeAtRT, 2, instr, instr->context()); 4590c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ AssertSmi(rax); 45913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ SmiToInteger32(rax, rax); 45923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ StoreToSafepointRegisterSlot(result, rax); 4593c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4594c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4595c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4596b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.orgvoid LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { 4597ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredStringCharFromCode FINAL : public LDeferredCode { 4598b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org public: 4599b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) 4600b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org : LDeferredCode(codegen), instr_(instr) { } 4601ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 460232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org codegen()->DoDeferredStringCharFromCode(instr_); 460332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org } 4604ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 4605b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org private: 4606b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org LStringCharFromCode* instr_; 4607b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org }; 4608b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4609b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org DeferredStringCharFromCode* deferred = 46107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredStringCharFromCode(this, instr); 4611b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4612e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->hydrogen()->value()->representation().IsInteger32()); 4613b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register char_code = ToRegister(instr->char_code()); 4614b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register result = ToRegister(instr->result()); 4615e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!char_code.is(result)); 4616b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 461759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmpl(char_code, Immediate(String::kMaxOneByteCharCode)); 4618b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ j(above, deferred->entry()); 4619f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ movsxlq(char_code, char_code); 4620b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex); 462143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(result, 4622b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org char_code, times_pointer_size, 4623b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org FixedArray::kHeaderSize)); 4624b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ CompareRoot(result, Heap::kUndefinedValueRootIndex); 4625b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ j(equal, deferred->entry()); 4626b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ bind(deferred->exit()); 4627b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org} 4628b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4629b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4630b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.orgvoid LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { 4631b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register char_code = ToRegister(instr->char_code()); 4632b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register result = ToRegister(instr->result()); 4633b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4634b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 4635b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // result register contain a valid pointer because it is already 4636b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // contained in the register pointer map. 4637b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ Set(result, 0); 4638b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 463944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 4640b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ Integer32ToSmi(char_code, char_code); 4641763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(char_code); 4642935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context()); 4643b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ StoreToSafepointRegisterSlot(result, rax); 4644b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org} 4645b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4646b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4647c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 464856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 4649e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsRegister() || input->IsStackSlot()); 46500ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org LOperand* output = instr->result(); 4651e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(output->IsDoubleRegister()); 465249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (input->IsRegister()) { 4653528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Cvtlsi2sd(ToDoubleRegister(output), ToRegister(input)); 465449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } else { 4655528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Cvtlsi2sd(ToDoubleRegister(output), ToOperand(input)); 465649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 4657c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4658c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4659c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 466046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 466156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 466246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org LOperand* output = instr->result(); 466346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 46647e6132b924829c353864933f29124419916db550machenbach@chromium.org __ LoadUint32(ToDoubleRegister(output), ToRegister(input)); 466546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 466646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 466746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4668c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4669ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredNumberTagI FINAL : public LDeferredCode { 4670e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org public: 4671e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 4672e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org : LDeferredCode(codegen), instr_(instr) { } 4673ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 4674e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(), 4675e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org instr_->temp2(), SIGNED_INT32); 4676e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 4677ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 4678e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org private: 4679e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org LNumberTagI* instr_; 4680e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org }; 4681e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 468256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 4683e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsRegister() && input->Equals(instr->result())); 46840ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org Register reg = ToRegister(input); 4685c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4686e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (SmiValuesAre32Bits()) { 4687e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ Integer32ToSmi(reg, reg); 4688e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } else { 4689e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(SmiValuesAre31Bits()); 4690e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); 4691e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ Integer32ToSmi(reg, reg); 4692e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ j(overflow, deferred->entry()); 4693e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ bind(deferred->exit()); 4694e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 4695c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4696c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4697c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 469846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid LCodeGen::DoNumberTagU(LNumberTagU* instr) { 4699ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredNumberTagU FINAL : public LDeferredCode { 470046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org public: 470146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 470246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org : LDeferredCode(codegen), instr_(instr) { } 4703ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 4704e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(), 4705e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org instr_->temp2(), UNSIGNED_INT32); 470646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } 4707ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 470846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org private: 470946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org LNumberTagU* instr_; 471046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org }; 471146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 471256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 4713e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsRegister() && input->Equals(instr->result())); 471446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Register reg = ToRegister(input); 471546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 471646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 471746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ cmpl(reg, Immediate(Smi::kMaxValue)); 471846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ j(above, deferred->entry()); 471946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ Integer32ToSmi(reg, reg); 472046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ bind(deferred->exit()); 472146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 472246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 472346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4724e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.orgvoid LCodeGen::DoDeferredNumberTagIU(LInstruction* instr, 4725e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org LOperand* value, 4726e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org LOperand* temp1, 4727e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org LOperand* temp2, 4728e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org IntegerSignedness signedness) { 4729bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org Label done, slow; 4730e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Register reg = ToRegister(value); 4731e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Register tmp = ToRegister(temp1); 4732e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org XMMRegister temp_xmm = ToDoubleRegister(temp2); 473346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4734c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org // Load value into temp_xmm which will be preserved across potential call to 473546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // runtime (MacroAssembler::EnterExitFrameEpilogue preserves only allocatable 473646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // XMM registers on x64). 4737e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (signedness == SIGNED_INT32) { 4738e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(SmiValuesAre31Bits()); 4739e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // There was overflow, so bits 30 and 31 of the original integer 4740e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // disagree. Try to allocate a heap number in new space and store 4741e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // the value in there. If that fails, call the runtime system. 4742e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ SmiToInteger32(reg, reg); 4743e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ xorl(reg, Immediate(0x80000000)); 4744e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ cvtlsi2sd(temp_xmm, reg); 4745e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } else { 4746e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(signedness == UNSIGNED_INT32); 4747e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ LoadUint32(temp_xmm, reg); 4748e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 474946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 475046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if (FLAG_inline_new) { 475146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ AllocateHeapNumber(reg, tmp, &slow); 475208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org __ jmp(&done, kPointerSize == kInt64Size ? Label::kNear : Label::kFar); 475346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } 475446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 475546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Slow case: Call the runtime system to do the number allocation. 475646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ bind(&slow); 4757bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org { 4758bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // Put a valid pointer value in the stack slot where the result 4759bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // register is stored, as this register is in the pointer map, but contains 4760bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // an integer value. 4761bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org __ Set(reg, 0); 476246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4763bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // Preserve the value of all registers. 4764bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org PushSafepointRegistersScope scope(this); 4765935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 4766e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // NumberTagIU uses the context from the frame, rather than 4767bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // the environment's HContext or HInlinedContext value. 476847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org // They only call Runtime::kAllocateHeapNumber. 4769bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // The corresponding HChange instructions are added in a phase that does 4770bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // not have easy access to the local context. 4771bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 477247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 4773bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org RecordSafepointWithRegisters( 4774bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 4775bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org __ StoreToSafepointRegisterSlot(reg, rax); 4776bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org } 477746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4778c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org // Done. Put the value in temp_xmm into the value of the allocated heap 477946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // number. 478046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ bind(&done); 4781c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), temp_xmm); 478246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 478346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 478446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4785c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoNumberTagD(LNumberTagD* instr) { 4786ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredNumberTagD FINAL : public LDeferredCode { 47870ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org public: 47880ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 47890ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org : LDeferredCode(codegen), instr_(instr) { } 4790ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 479132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org codegen()->DoDeferredNumberTagD(instr_); 479232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org } 4793ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 47940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org private: 47950ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org LNumberTagD* instr_; 47960ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org }; 47970ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 479856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 47990ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org Register reg = ToRegister(instr->result()); 480056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register tmp = ToRegister(instr->temp()); 48010ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 48027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 48030ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (FLAG_inline_new) { 48040ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ AllocateHeapNumber(reg, tmp, deferred->entry()); 48050ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else { 48060ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ jmp(deferred->entry()); 48070ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 48080ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ bind(deferred->exit()); 48090ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 4810c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4811c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4812c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4813c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 48140ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 48150ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // result register contain a valid pointer because it is already 48160ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // contained in the register pointer map. 48170ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org Register reg = ToRegister(instr->result()); 48180ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ Move(reg, Smi::FromInt(0)); 48190ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 482044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org { 482144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 4822935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // NumberTagD uses the context from the frame, rather than 4823935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // the environment's HContext or HInlinedContext value. 482447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org // They only call Runtime::kAllocateHeapNumber. 4825935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // The corresponding HChange instructions are added in a phase that does 4826935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // not have easy access to the local context. 482743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 482847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 4829935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org RecordSafepointWithRegisters( 4830935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 483143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(kScratchRegister, rax); 483244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 483343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(reg, kScratchRegister); 4834c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4835c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4836c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4837c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoSmiTag(LSmiTag* instr) { 4838381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org HChange* hchange = instr->hydrogen(); 483956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 4840381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org Register output = ToRegister(instr->result()); 4841381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org if (hchange->CheckFlag(HValue::kCanOverflow) && 4842381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org hchange->value()->CheckFlag(HValue::kUint32)) { 484370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Condition is_smi = __ CheckUInteger32ValidSmiValue(input); 484406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(NegateCondition(is_smi), instr, "overflow"); 4845381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org } 4846381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org __ Integer32ToSmi(output, input); 4847381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org if (hchange->CheckFlag(HValue::kCanOverflow) && 4848381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org !hchange->value()->CheckFlag(HValue::kUint32)) { 484906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 4850381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org } 4851c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4852c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4853c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4854c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoSmiUntag(LSmiUntag* instr) { 4855e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->value()->Equals(instr->result())); 485656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 4857d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (instr->needs_check()) { 4858d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com Condition is_smi = __ CheckSmi(input); 485906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(NegateCondition(is_smi), instr, "not a Smi"); 48607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } else { 4861c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ AssertSmi(input); 4862d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 4863d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ SmiToInteger32(input, input); 4864c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4865c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4866c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4867a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgvoid LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, 4868a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org XMMRegister result_reg, NumberUntagDMode mode) { 4869a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org bool can_convert_undefined_to_nan = 4870a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org instr->hydrogen()->can_convert_undefined_to_nan(); 4871a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero(); 4872a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 4873528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label convert, load_smi, done; 48740ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4875c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 487694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // Smi check. 487794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ JumpIfSmi(input_reg, &load_smi, Label::kNear); 48780ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 487994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // Heap number map check. 488094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 488194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Heap::kHeapNumberMapRootIndex); 48822f877ace3ac6432b1ce44abd553cd3ff97321680hpayer@chromium.org 4883528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // On x64 it is safe to load at heap number offset before evaluating the map 4884528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // check, since all heap objects are at least two words long. 4885528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); 48862f877ace3ac6432b1ce44abd553cd3ff97321680hpayer@chromium.org 4887528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (can_convert_undefined_to_nan) { 4888935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(not_equal, &convert, Label::kNear); 4889528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } else { 489006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number"); 48912f877ace3ac6432b1ce44abd553cd3ff97321680hpayer@chromium.org } 4892528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 489394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (deoptimize_on_minus_zero) { 4894528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 489594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ xorps(xmm_scratch, xmm_scratch); 489694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ ucomisd(xmm_scratch, result_reg); 489794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ j(not_equal, &done, Label::kNear); 489894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ movmskpd(kScratchRegister, result_reg); 489994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ testq(kScratchRegister, Immediate(1)); 490006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_zero, instr, "minus zero"); 490194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 490294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ jmp(&done, Label::kNear); 4903528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4904528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (can_convert_undefined_to_nan) { 4905528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ bind(&convert); 4906528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4907528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Convert undefined (and hole) to NaN. Compute NaN as 0/0. 4908528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex); 490906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number/undefined"); 4910528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4911528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ xorps(result_reg, result_reg); 4912528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ divsd(result_reg, result_reg); 4913528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ jmp(&done, Label::kNear); 4914528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 491594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } else { 4916e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(mode == NUMBER_CANDIDATE_IS_SMI); 4917f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } 49180ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 49190ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Smi to XMM conversion 49200ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ bind(&load_smi); 492149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org __ SmiToInteger32(kScratchRegister, input_reg); 4922528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Cvtlsi2sd(result_reg, kScratchRegister); 49230ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ bind(&done); 4924c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4925c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4926c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4927c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) { 492856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input_reg = ToRegister(instr->value()); 492983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 493083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (instr->truncating()) { 49312efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label no_heap_number, check_bools, check_false; 49322efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 4933c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Heap number map check. 4934c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 4935c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Heap::kHeapNumberMapRootIndex); 49362efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ j(not_equal, &no_heap_number, Label::kNear); 49372efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ TruncateHeapNumberToI(input_reg, input_reg); 49382efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ jmp(done); 49392efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 49402efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ bind(&no_heap_number); 49412efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org // Check for Oddballs. Undefined/False is converted to zero and True to one 49422efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org // for truncating conversions. 494383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex); 49442efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ j(not_equal, &check_bools, Label::kNear); 4945a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org __ Set(input_reg, 0); 4946c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ jmp(done); 494783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 49482efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ bind(&check_bools); 49492efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ CompareRoot(input_reg, Heap::kTrueValueRootIndex); 49502efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ j(not_equal, &check_false, Label::kNear); 49512efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ Set(input_reg, 1); 49522efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ jmp(done); 49532efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 49542efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ bind(&check_false); 49552efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ CompareRoot(input_reg, Heap::kFalseValueRootIndex); 495606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number/undefined/true/false"); 49572efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ Set(input_reg, 0); 495883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 4959a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org XMMRegister scratch = ToDoubleRegister(instr->temp()); 4960a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DCHECK(!scratch.is(xmm0)); 4961a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 4962a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Heap::kHeapNumberMapRootIndex); 496306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number"); 4964a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 4965a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ cvttsd2si(input_reg, xmm0); 4966a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ Cvtlsi2sd(scratch, input_reg); 4967a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ ucomisd(xmm0, scratch); 496806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "lost precision"); 496906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(parity_even, instr, "NaN"); 4970a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) { 4971a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ testl(input_reg, input_reg); 4972a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ j(not_zero, done); 4973a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ movmskpd(input_reg, xmm0); 4974a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ andl(input_reg, Immediate(1)); 497506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_zero, instr, "minus zero"); 4976a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } 497783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 4978c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4979c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4980c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4981c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoTaggedToI(LTaggedToI* instr) { 4982ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredTaggedToI FINAL : public LDeferredCode { 4983c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 4984c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 4985c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : LDeferredCode(codegen), instr_(instr) { } 4986ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 4987c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org codegen()->DoDeferredTaggedToI(instr_, done()); 498832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org } 4989ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 4990c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 4991c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LTaggedToI* instr_; 4992c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 4993c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 499456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 4995e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsRegister()); 4996e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->Equals(instr->result())); 49972f877ace3ac6432b1ce44abd553cd3ff97321680hpayer@chromium.org Register input_reg = ToRegister(input); 4998528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4999528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (instr->hydrogen()->value()->representation().IsSmi()) { 5000528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ SmiToInteger32(input_reg, input_reg); 5001528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } else { 5002528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); 5003528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ JumpIfNotSmi(input_reg, deferred->entry()); 5004528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ SmiToInteger32(input_reg, input_reg); 5005528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ bind(deferred->exit()); 5006528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 5007c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5008c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5009c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5010c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 501156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5012e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsRegister()); 501349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org LOperand* result = instr->result(); 5014e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result->IsDoubleRegister()); 501549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 501649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org Register input_reg = ToRegister(input); 501749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org XMMRegister result_reg = ToDoubleRegister(result); 501849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 501994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org HValue* value = instr->hydrogen()->value(); 5020c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org NumberUntagDMode mode = value->representation().IsSmi() 5021c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED; 502294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 5023a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EmitNumberUntagD(instr, input_reg, result_reg, mode); 5024c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5025c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5026c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5027c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoDoubleToI(LDoubleToI* instr) { 502856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5029e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsDoubleRegister()); 50303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LOperand* result = instr->result(); 5031e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result->IsRegister()); 50323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 50333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org XMMRegister input_reg = ToDoubleRegister(input); 50343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register result_reg = ToRegister(result); 50353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 50363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (instr->truncating()) { 5037c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ TruncateDoubleToI(result_reg, input_reg); 50383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 503906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label lost_precision, is_nan, minus_zero, done; 5040528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 504106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 5042528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ DoubleToI(result_reg, input_reg, xmm_scratch, 504306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org instr->hydrogen()->GetMinusZeroMode(), &lost_precision, 504406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org &is_nan, &minus_zero, dist); 504506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ jmp(&done, dist); 504606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&lost_precision); 504706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(no_condition, instr, "lost precision"); 504806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&is_nan); 504906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(no_condition, instr, "NaN"); 505006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&minus_zero); 505106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(no_condition, instr, "minus zero"); 5052c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ bind(&done); 50533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 5054c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5055c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5056c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5057a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 5058a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org LOperand* input = instr->value(); 5059e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsDoubleRegister()); 5060a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org LOperand* result = instr->result(); 5061e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result->IsRegister()); 5062a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5063a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org XMMRegister input_reg = ToDoubleRegister(input); 5064a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register result_reg = ToRegister(result); 5065a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 506606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label lost_precision, is_nan, minus_zero, done; 5067528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 506806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 5069528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ DoubleToI(result_reg, input_reg, xmm_scratch, 507006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org instr->hydrogen()->GetMinusZeroMode(), &lost_precision, &is_nan, 507106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org &minus_zero, dist); 507206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ jmp(&done, dist); 507306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&lost_precision); 507406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(no_condition, instr, "lost precision"); 507506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&is_nan); 507606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(no_condition, instr, "NaN"); 507706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&minus_zero); 507806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(no_condition, instr, "minus zero"); 5079c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ bind(&done); 5080a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ Integer32ToSmi(result_reg, result_reg); 508106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 5082a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org} 5083a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5084a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5085c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCheckSmi(LCheckSmi* instr) { 508656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5087378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Condition cc = masm()->CheckSmi(ToRegister(input)); 508806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(NegateCondition(cc), instr, "not a Smi"); 5089badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org} 5090badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 5091badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 5092badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 5093eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org if (!instr->hydrogen()->value()->type().IsHeapObject()) { 50941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org LOperand* input = instr->value(); 50951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Condition cc = masm()->CheckSmi(ToRegister(input)); 509606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(cc, instr, "Smi"); 50971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 5098c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5099c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5100c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5101c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 510256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 510383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 510443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset)); 510583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 510683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (instr->hydrogen()->is_interval_check()) { 510783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org InstanceType first; 510883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org InstanceType last; 510983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org instr->hydrogen()->GetCheckInterval(&first, &last); 511083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 511183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), 511283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Immediate(static_cast<int8_t>(first))); 511383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 511483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // If there is only one type in the interval check for equality. 511583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (first == last) { 511606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "wrong instance type"); 511783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 511806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(below, instr, "wrong instance type"); 511983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Omit check for the last type. 512083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (last != LAST_TYPE) { 512183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), 512283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Immediate(static_cast<int8_t>(last))); 512306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(above, instr, "wrong instance type"); 512483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 512583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 512683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 512783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org uint8_t mask; 512883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org uint8_t tag; 512983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); 513083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 513121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org if (base::bits::IsPowerOfTwo32(mask)) { 513221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag)); 513383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ testb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), 513483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Immediate(mask)); 513506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(tag == 0 ? not_zero : zero, instr, "wrong instance type"); 513683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 513783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ movzxbl(kScratchRegister, 513883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); 513983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ andb(kScratchRegister, Immediate(mask)); 514083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ cmpb(kScratchRegister, Immediate(tag)); 514106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "wrong instance type"); 514283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 514383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 5144c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5145c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5146c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 51471f410f9a9c4fbd4270749af64b477df87b753158mstarzinger@chromium.orgvoid LCodeGen::DoCheckValue(LCheckValue* instr) { 514864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Register reg = ToRegister(instr->value()); 5149c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Cmp(reg, instr->hydrogen()->object().handle()); 515006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "value mismatch"); 5151c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5152c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5153c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5154594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 5155594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org { 5156594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org PushSafepointRegistersScope scope(this); 5157763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(object); 5158935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ Set(rsi, 0); 5159e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance); 5160935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org RecordSafepointWithRegisters( 5161935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org instr->pointer_map(), 1, Safepoint::kNoLazyDeopt); 5162935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 51637a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rax, Immediate(kSmiTagMask)); 5164594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 516506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(zero, instr, "instance migration failed"); 5166f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 5167f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 5168f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 51691456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid LCodeGen::DoCheckMaps(LCheckMaps* instr) { 5170ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredCheckMaps FINAL : public LDeferredCode { 5171594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org public: 5172594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) 5173594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org : LDeferredCode(codegen), instr_(instr), object_(object) { 5174594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org SetExit(check_maps()); 5175594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5176ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 5177594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org codegen()->DoDeferredInstanceMigration(instr_, object_); 5178594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5179594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label* check_maps() { return &check_maps_; } 5180ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 5181594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org private: 5182594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org LCheckMaps* instr_; 5183594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label check_maps_; 5184594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Register object_; 5185594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org }; 5186594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5187af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org if (instr->hydrogen()->IsStabilityCheck()) { 5188af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org const UniqueSet<Map>* maps = instr->hydrogen()->maps(); 5189af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org for (int i = 0; i < maps->size(); ++i) { 5190af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org AddStabilityDependency(maps->at(i).handle()); 5191af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org } 5192af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org return; 5193af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org } 5194594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 519556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5196e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsRegister()); 5197378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Register reg = ToRegister(input); 51981456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 5199594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeferredCheckMaps* deferred = NULL; 5200af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org if (instr->hydrogen()->HasMigrationTarget()) { 5201594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org deferred = new(zone()) DeferredCheckMaps(this, instr, reg); 5202594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ bind(deferred->check_maps()); 5203594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5204594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5205af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org const UniqueSet<Map>* maps = instr->hydrogen()->maps(); 5206594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label success; 5207af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org for (int i = 0; i < maps->size() - 1; i++) { 5208af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org Handle<Map> map = maps->at(i).handle(); 5209935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ CompareMap(reg, map); 5210935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(equal, &success, Label::kNear); 52111456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 5212594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5213af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org Handle<Map> map = maps->at(maps->size() - 1).handle(); 5214935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ CompareMap(reg, map); 5215af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org if (instr->hydrogen()->HasMigrationTarget()) { 5216594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ j(not_equal, deferred->entry()); 5217594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 521806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "wrong map"); 5219594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5220594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 52211456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ bind(&success); 5222c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5223c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5224c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5225c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 5226c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org XMMRegister value_reg = ToDoubleRegister(instr->unclamped()); 5227528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 5228c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register result_reg = ToRegister(instr->result()); 5229528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ ClampDoubleToUint8(value_reg, xmm_scratch, result_reg); 5230c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 5231c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5232c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5233c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 5234e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->unclamped()->Equals(instr->result())); 5235c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register value_reg = ToRegister(instr->result()); 5236c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ ClampUint8(value_reg); 5237c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 5238c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5239c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5240c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 5241e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->unclamped()->Equals(instr->result())); 5242c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register input_reg = ToRegister(instr->unclamped()); 524389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org XMMRegister temp_xmm_reg = ToDoubleRegister(instr->temp_xmm()); 5244528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 5245c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label is_smi, done, heap_number; 5246935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 5247935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ JumpIfSmi(input_reg, &is_smi, dist); 5248c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5249c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check for heap number 5250c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5251c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org factory()->heap_number_map()); 5252c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ j(equal, &heap_number, Label::kNear); 5253c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5254c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check for undefined. Undefined is converted to zero for clamping 5255c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // conversions. 5256c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Cmp(input_reg, factory()->undefined_value()); 525706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number/undefined"); 5258a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ xorl(input_reg, input_reg); 5259c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ jmp(&done, Label::kNear); 5260c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5261c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Heap number 5262c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&heap_number); 5263528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ movsd(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5264528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg); 5265c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ jmp(&done, Label::kNear); 5266c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5267c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // smi 5268c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&is_smi); 5269c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ SmiToInteger32(input_reg, input_reg); 5270c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ ClampUint8(input_reg); 5271c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5272c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&done); 5273c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 5274c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5275c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5276ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoDoubleBits(LDoubleBits* instr) { 5277ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org XMMRegister value_reg = ToDoubleRegister(instr->value()); 5278ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register result_reg = ToRegister(instr->result()); 5279ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (instr->hydrogen()->bits() == HDoubleBits::HIGH) { 5280ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ movq(result_reg, value_reg); 52812f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ shrq(result_reg, Immediate(32)); 5282ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } else { 5283ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ movd(result_reg, value_reg); 5284ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 5285ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org} 5286ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 5287ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 5288ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoConstructDouble(LConstructDouble* instr) { 5289ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register hi_reg = ToRegister(instr->hi()); 5290ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register lo_reg = ToRegister(instr->lo()); 5291ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org XMMRegister result_reg = ToDoubleRegister(instr->result()); 5292ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 5293ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ movd(result_reg, hi_reg); 5294ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ psllq(result_reg, 32); 5295ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ movd(xmm_scratch, lo_reg); 5296ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ orps(result_reg, xmm_scratch); 5297ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org} 5298ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 5299ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 530094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::DoAllocate(LAllocate* instr) { 5301ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredAllocate FINAL : public LDeferredCode { 530294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org public: 530394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org DeferredAllocate(LCodeGen* codegen, LAllocate* instr) 530494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org : LDeferredCode(codegen), instr_(instr) { } 5305ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 530632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org codegen()->DoDeferredAllocate(instr_); 530732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org } 5308ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 530994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org private: 531094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org LAllocate* instr_; 531194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org }; 531294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 531394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org DeferredAllocate* deferred = 531494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org new(zone()) DeferredAllocate(this, instr); 531594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 531694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register result = ToRegister(instr->result()); 531794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register temp = ToRegister(instr->temp()); 531894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 531971fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org // Allocate memory for the object. 532071fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org AllocationFlags flags = TAG_OBJECT; 532171fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org if (instr->hydrogen()->MustAllocateDoubleAligned()) { 532271fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); 532371fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org } 5324d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { 5325e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5326e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); 5327e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE); 5328d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5329e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); 5330c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE); 5331e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5332c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 533371fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org if (instr->size()->IsConstantOperand()) { 533471fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 53356b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org if (size <= Page::kMaxRegularHeapObjectSize) { 53366b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); 53376b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org } else { 53386b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org __ jmp(deferred->entry()); 53396b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org } 534094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } else { 534171fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org Register size = ToRegister(instr->size()); 5342f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); 534394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 534494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 534594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ bind(deferred->exit()); 5346c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 5347c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (instr->hydrogen()->MustPrefillWithFiller()) { 5348c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (instr->size()->IsConstantOperand()) { 5349c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5350c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ movl(temp, Immediate((size / kPointerSize) - 1)); 5351c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } else { 5352c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org temp = ToRegister(instr->size()); 53532f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ sarp(temp, Immediate(kPointerSizeLog2)); 5354c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ decl(temp); 5355c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 5356c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Label loop; 5357c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ bind(&loop); 5358c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ Move(FieldOperand(result, temp, times_pointer_size, 0), 5359c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org isolate()->factory()->one_pointer_filler_map()); 5360c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ decl(temp); 5361c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ j(not_zero, &loop); 5362c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 536394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 536494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 536594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 536694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::DoDeferredAllocate(LAllocate* instr) { 536794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register result = ToRegister(instr->result()); 536894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 536994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 537094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // result register contain a valid pointer because it is already 537194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // contained in the register pointer map. 5372f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ Move(result, Smi::FromInt(0)); 537394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 537494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org PushSafepointRegistersScope scope(this); 5375f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (instr->size()->IsRegister()) { 5376f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Register size = ToRegister(instr->size()); 5377e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!size.is(result)); 5378f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ Integer32ToSmi(size, size); 5379763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(size); 5380f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } else { 5381f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5382f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ Push(Smi::FromInt(size)); 5383f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 5384f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 5385ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org int flags = 0; 5386d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { 5387e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5388e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); 5389ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org flags = AllocateTargetSpace::update(flags, OLD_POINTER_SPACE); 5390d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5391e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); 5392ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org flags = AllocateTargetSpace::update(flags, OLD_DATA_SPACE); 5393e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 5394ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org flags = AllocateTargetSpace::update(flags, NEW_SPACE); 5395e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5396ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org __ Push(Smi::FromInt(flags)); 5397ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 5398ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org CallRuntimeFromDeferred( 539947390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org Runtime::kAllocateInTargetSpace, 2, instr, instr->context()); 540094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ StoreToSafepointRegisterSlot(result, rax); 540194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 540294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 540394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 5404ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid LCodeGen::DoToFastProperties(LToFastProperties* instr) { 5405e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->value()).is(rax)); 5406763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 5407ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org CallRuntime(Runtime::kToFastProperties, 1, instr); 5408ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 5409ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 5410ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 5411c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 5412e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 541383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label materialized; 54143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Registers will be used as follows: 54153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // rcx = literals array. 54163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // rbx = regexp literal. 54173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // rax = regexp literal clone. 54189c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org int literal_offset = 54199c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); 5420c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Move(rcx, instr->hydrogen()->literals()); 542143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, FieldOperand(rcx, literal_offset)); 54223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex); 542383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_equal, &materialized, Label::kNear); 54243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 54253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Create regexp literal using runtime function 54263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Result will be in rax. 5427763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rcx); 54283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Push(Smi::FromInt(instr->hydrogen()->literal_index())); 54293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Push(instr->hydrogen()->pattern()); 54303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Push(instr->hydrogen()->flags()); 543147390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); 543243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, rax); 54333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 54343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&materialized); 54353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 54363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Label allocated, runtime_allocate; 54372bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ Allocate(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT); 5438935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&allocated, Label::kNear); 54393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 54403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&runtime_allocate); 5441763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rbx); 54423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Push(Smi::FromInt(size)); 544347390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); 5444763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rbx); 54453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 54463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&allocated); 54473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Copy the content into the newly allocated memory. 54483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // (Unroll copy loop once for better throughput). 54493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { 545043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rbx, i)); 545143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, FieldOperand(rbx, i + kPointerSize)); 545243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, i), rdx); 545343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, i + kPointerSize), rcx); 54543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 54553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if ((size % (2 * kPointerSize)) != 0) { 545643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rbx, size - kPointerSize)); 545743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, size - kPointerSize), rdx); 54583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 5459c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5460c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5461c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5462c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { 5463e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 546483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // Use the fast case closure allocation code that allocates in new 546583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // space for nested functions that don't need literals cloning. 546683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org bool pretenure = instr->hydrogen()->pretenure(); 546732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (!pretenure && instr->hydrogen()->has_no_literals()) { 54682c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org FastNewClosureStub stub(isolate(), instr->hydrogen()->strict_mode(), 54692c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org instr->hydrogen()->kind()); 5470662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ Move(rbx, instr->hydrogen()->shared_info()); 5471f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 547283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 5473763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); 547432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ Push(instr->hydrogen()->shared_info()); 547532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ PushRoot(pretenure ? Heap::kTrueValueRootIndex : 547632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Heap::kFalseValueRootIndex); 547747390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntime(Runtime::kNewClosure, 3, instr); 547883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 5479c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5480c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5481c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5482c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoTypeof(LTypeof* instr) { 5483e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 548456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5485160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org EmitPushTaggedOperand(input); 54863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org CallRuntime(Runtime::kTypeof, 1, instr); 5487c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5488c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5489c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5490160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgvoid LCodeGen::EmitPushTaggedOperand(LOperand* operand) { 5491e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!operand->IsDoubleRegister()); 5492160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (operand->IsConstantOperand()) { 5493c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Push(ToHandle(LConstantOperand::cast(operand))); 5494160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else if (operand->IsRegister()) { 5495763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(ToRegister(operand)); 54963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 5497763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(ToOperand(operand)); 54983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 5499d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com} 5500d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 5501d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 5502c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 550356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 5504af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Condition final_branch_condition = EmitTypeofIs(instr, input); 5505394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (final_branch_condition != no_condition) { 55061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, final_branch_condition); 5507394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 5508c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5509c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5510c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5511af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgCondition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) { 5512af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label* true_label = instr->TrueLabel(chunk_); 5513af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label* false_label = instr->FalseLabel(chunk_); 5514af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Handle<String> type_name = instr->type_literal(); 5515af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org int left_block = instr->TrueDestination(chunk_); 5516af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org int right_block = instr->FalseDestination(chunk_); 5517af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org int next_block = GetNextEmittedBlock(); 5518af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 5519af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label::Distance true_distance = left_block == next_block ? Label::kNear 5520af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org : Label::kFar; 5521af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label::Distance false_distance = right_block == next_block ? Label::kNear 5522af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org : Label::kFar; 55230a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Condition final_branch_condition = no_condition; 55242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Factory* factory = isolate()->factory(); 55252ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (String::Equals(type_name, factory->number_string())) { 5526af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfSmi(input, true_label, true_distance); 5527b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ CompareRoot(FieldOperand(input, HeapObject::kMapOffset), 5528b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Heap::kHeapNumberMapRootIndex); 5529b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 55300a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org final_branch_condition = equal; 55310a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 55322ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(type_name, factory->string_string())) { 5533af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 55348f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); 5535af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ j(above_equal, false_label, false_distance); 55360a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ testb(FieldOperand(input, Map::kBitFieldOffset), 55370a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Immediate(1 << Map::kIsUndetectable)); 55388f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org final_branch_condition = zero; 55390a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 55402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(type_name, factory->symbol_string())) { 5541af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 5542f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ CmpObjectType(input, SYMBOL_TYPE, input); 5543f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org final_branch_condition = equal; 5544f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 55452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(type_name, factory->boolean_string())) { 55460a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ CompareRoot(input, Heap::kTrueValueRootIndex); 5547af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ j(equal, true_label, true_distance); 55480a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ CompareRoot(input, Heap::kFalseValueRootIndex); 55490a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org final_branch_condition = equal; 55500a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 55512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(type_name, factory->undefined_string())) { 55520a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ CompareRoot(input, Heap::kUndefinedValueRootIndex); 5553af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ j(equal, true_label, true_distance); 5554af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 55550a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Check for undetectable objects => true. 555643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(input, FieldOperand(input, HeapObject::kMapOffset)); 55570a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ testb(FieldOperand(input, Map::kBitFieldOffset), 55580a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Immediate(1 << Map::kIsUndetectable)); 55590a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org final_branch_condition = not_zero; 55600a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 55612ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(type_name, factory->function_string())) { 5562c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 5563af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 5564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CmpObjectType(input, JS_FUNCTION_TYPE, input); 5565af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ j(equal, true_label, true_distance); 5566c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); 5567c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com final_branch_condition = equal; 55680a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 55692ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(type_name, factory->object_string())) { 5570af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 55719d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org __ CompareRoot(input, Heap::kNullValueRootIndex); 55729d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org __ j(equal, true_label, true_distance); 5573f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); 5574af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ j(below, false_label, false_distance); 5575d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 5576af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ j(above, false_label, false_distance); 55770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Check for undetectable objects => false. 55780a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ testb(FieldOperand(input, Map::kBitFieldOffset), 55790a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Immediate(1 << Map::kIsUndetectable)); 55808f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org final_branch_condition = zero; 55810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 55820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 5583af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ jmp(false_label, false_distance); 55840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 55850a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 55860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return final_branch_condition; 5587c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5588c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5589c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 55903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 559156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 55923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 55933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org EmitIsConstructCall(temp); 55941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 55953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 55963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 55973a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 55983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid LCodeGen::EmitIsConstructCall(Register temp) { 55993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Get the frame pointer for the calling frame. 560043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 56013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 56023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Skip the arguments adaptor frame if it exists. 560383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label check_frame_marker; 5604badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ Cmp(Operand(temp, StandardFrameConstants::kContextOffset), 5605badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 560683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_equal, &check_frame_marker, Label::kNear); 560743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset)); 56083a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 56093a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Check the marker in the calling frame. 56103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&check_frame_marker); 5611badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ Cmp(Operand(temp, StandardFrameConstants::kMarkerOffset), 5612badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Smi::FromInt(StackFrame::CONSTRUCT)); 56133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 56143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 56153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 561664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { 56175c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org if (!info()->IsStub()) { 56185c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org // Ensure that we have enough space after the previous lazy-bailout 56195c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org // instruction for patching the code here. 56205c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org int current_pc = masm()->pc_offset(); 56215c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org if (current_pc < last_lazy_deopt_pc_ + space_needed) { 56225c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 56235c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org __ Nop(padding_size); 56245c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org } 562527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } 56265c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org last_lazy_deopt_pc_ = masm()->pc_offset(); 562727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org} 562827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org 562927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org 5630c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLazyBailout(LLazyBailout* instr) { 5631fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org last_lazy_deopt_pc_ = masm()->pc_offset(); 5632e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->HasEnvironment()); 563327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org LEnvironment* env = instr->environment(); 563427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 563527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 5636c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5637c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5638c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5639c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoDeoptimize(LDeoptimize* instr) { 5640c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Deoptimizer::BailoutType type = instr->hydrogen()->type(); 5641c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the 5642c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // needed return address), even though the implementation of LAZY and EAGER is 5643c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // now identical. When LAZY is eventually completely folded into EAGER, remove 5644c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // the special case below. 5645c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (info()->IsStub() && type == Deoptimizer::EAGER) { 5646c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org type = Deoptimizer::LAZY; 5647c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 5648a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DeoptimizeIf(no_condition, instr, instr->hydrogen()->reason(), type); 5649c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5650c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5651c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5652935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgvoid LCodeGen::DoDummy(LDummy* instr) { 5653935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // Nothing to see here, move on! 5654935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org} 5655935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 5656935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 565746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgvoid LCodeGen::DoDummyUse(LDummyUse* instr) { 565846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org // Nothing to see here, move on! 565946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org} 566046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 566146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 566204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgvoid LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { 566327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org PushSafepointRegistersScope scope(this); 566443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 566547390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kStackGuard); 566627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0); 5667e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->HasEnvironment()); 566827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org LEnvironment* env = instr->environment(); 566927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 567004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org} 567104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org 567204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org 5673c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoStackCheck(LStackCheck* instr) { 5674ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredStackCheck FINAL : public LDeferredCode { 567504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org public: 567604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) 567704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org : LDeferredCode(codegen), instr_(instr) { } 5678ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 567932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org codegen()->DoDeferredStackCheck(instr_); 568032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org } 5681ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 568204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org private: 568304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org LStackCheck* instr_; 568404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org }; 5685c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5686e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->HasEnvironment()); 568727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org LEnvironment* env = instr->environment(); 568827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // There is no LLazyBailout instruction for stack-checks. We have to 568927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // prepare for lazy deoptimization explicitly here. 569004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (instr->hydrogen()->is_function_entry()) { 569104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org // Perform stack overflow check. 569204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org Label done; 569304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ CompareRoot(rsp, Heap::kStackLimitRootIndex); 569404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ j(above_equal, &done, Label::kNear); 5695935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 5696e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->context()->IsRegister()); 5697e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 5698dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org CallCode(isolate()->builtins()->StackCheck(), 5699dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org RelocInfo::CODE_TARGET, 5700dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org instr); 570104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ bind(&done); 570204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } else { 5703e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->hydrogen()->is_backwards_branch()); 570404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org // Perform stack overflow check if this goto needs it before jumping. 570504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org DeferredStackCheck* deferred_stack_check = 57067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredStackCheck(this, instr); 570704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ CompareRoot(rsp, Heap::kStackLimitRootIndex); 570804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ j(below, deferred_stack_check->entry()); 570964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 571004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ bind(instr->done_label()); 571104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org deferred_stack_check->SetExit(instr->done_label()); 571227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 571327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // Don't record a deoptimization index for the safepoint here. 571427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // This will be done explicitly when emitting call and the safepoint in 571527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // the deferred code. 571604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } 5717c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5718c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5719c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5720c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoOsrEntry(LOsrEntry* instr) { 572149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // This is a pseudo-instruction that ensures that the environment here is 572249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // properly registered for deoptimization and records the assembler's PC 572349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // offset. 572449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org LEnvironment* environment = instr->environment(); 572549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 572649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // If the environment were already registered, we would have no way of 572749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // backpatching it with the spill slot operands. 5728e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!environment->HasBeenRegistered()); 572927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 57301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 5731c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org GenerateOsrPrologue(); 5732c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5733c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5734be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5735be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { 5736e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(rsi)); 5737be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 573806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(equal, instr, "undefined"); 5739be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5740be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register null_value = rdi; 5741be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ LoadRoot(null_value, Heap::kNullValueRootIndex); 57427a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rax, null_value); 574306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(equal, instr, "null"); 5744be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5745be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Condition cc = masm()->CheckSmi(rax); 574606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(cc, instr, "Smi"); 5747be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5748be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 5749be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ CmpObjectType(rax, LAST_JS_PROXY_TYPE, rcx); 575006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(below_equal, instr, "wrong instance type"); 5751be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5752be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Label use_cache, call_runtime; 5753be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ CheckEnumCache(null_value, &call_runtime); 5754be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 575543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, FieldOperand(rax, HeapObject::kMapOffset)); 5756be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ jmp(&use_cache, Label::kNear); 5757be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5758be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Get the set of properties to enumerate. 5759be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ bind(&call_runtime); 5760763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 5761be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); 5762be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5763be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), 5764be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Heap::kMetaMapRootIndex); 576506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "wrong map"); 5766be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ bind(&use_cache); 5767be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 5768be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5769be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5770be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { 5771be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register map = ToRegister(instr->map()); 5772be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register result = ToRegister(instr->result()); 5773355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Label load_cache, done; 5774355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ EnumLength(result, map); 5775355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ Cmp(result, Smi::FromInt(0)); 5776935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(not_equal, &load_cache, Label::kNear); 5777355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ LoadRoot(result, Heap::kEmptyFixedArrayRootIndex); 5778935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&done, Label::kNear); 5779355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ bind(&load_cache); 5780be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ LoadInstanceDescriptors(map, result); 578143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, 5782304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FieldOperand(result, DescriptorArray::kEnumCacheOffset)); 578343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, 5784be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org FieldOperand(result, FixedArray::SizeFor(instr->idx()))); 5785355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ bind(&done); 5786be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Condition cc = masm()->CheckSmi(result); 578706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(cc, instr, "no cache"); 5788be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 5789be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5790be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5791be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { 5792be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register object = ToRegister(instr->value()); 57937a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(ToRegister(instr->map()), 5794be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org FieldOperand(object, HeapObject::kMapOffset)); 579506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "wrong map"); 5796be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 5797be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5798be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 579963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.orgvoid LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, 580063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register object, 580163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register index) { 580263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org PushSafepointRegistersScope scope(this); 580363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ Push(object); 580463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ Push(index); 580563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ xorp(rsi, rsi); 580663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble); 580763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org RecordSafepointWithRegisters( 580863a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org instr->pointer_map(), 2, Safepoint::kNoLazyDeopt); 580963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ StoreToSafepointRegisterSlot(object, rax); 581063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org} 581163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org 581263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org 5813be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { 5814ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredLoadMutableDouble FINAL : public LDeferredCode { 581563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org public: 581663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org DeferredLoadMutableDouble(LCodeGen* codegen, 581763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org LLoadFieldByIndex* instr, 581863a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register object, 581963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register index) 582063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org : LDeferredCode(codegen), 582163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org instr_(instr), 582263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org object_(object), 582363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org index_(index) { 582463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org } 5825ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 582663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org codegen()->DoDeferredLoadMutableDouble(instr_, object_, index_); 582763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org } 5828ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 582963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org private: 583063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org LLoadFieldByIndex* instr_; 583163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register object_; 583263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register index_; 583363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org }; 583463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org 5835be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register object = ToRegister(instr->object()); 5836be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register index = ToRegister(instr->index()); 5837be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 583863a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org DeferredLoadMutableDouble* deferred; 583963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org deferred = new(zone()) DeferredLoadMutableDouble(this, instr, object, index); 584063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org 5841be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Label out_of_object, done; 584263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ Move(kScratchRegister, Smi::FromInt(1)); 584363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ testp(index, kScratchRegister); 584463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ j(not_zero, deferred->entry()); 584563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org 584663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ sarp(index, Immediate(1)); 584763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org 5848be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ SmiToInteger32(index, index); 5849be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ cmpl(index, Immediate(0)); 5850935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(less, &out_of_object, Label::kNear); 585143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(object, FieldOperand(object, 5852be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org index, 5853be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org times_pointer_size, 5854be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org JSObject::kHeaderSize)); 5855be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ jmp(&done, Label::kNear); 5856be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5857be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ bind(&out_of_object); 585843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(object, FieldOperand(object, JSObject::kPropertiesOffset)); 5859be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ negl(index); 5860be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Index is now equal to out of object property index plus 1. 586143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(object, FieldOperand(object, 5862be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org index, 5863be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org times_pointer_size, 5864be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org FixedArray::kHeaderSize - kPointerSize)); 586563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ bind(deferred->exit()); 5866be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ bind(&done); 5867be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 5868be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5869be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 58701e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.orgvoid LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) { 58711e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Register context = ToRegister(instr->context()); 58721e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), context); 58731e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org} 58741e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org 58751e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org 58761e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.orgvoid LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) { 58771e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Handle<ScopeInfo> scope_info = instr->scope_info(); 58781e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org __ Push(scope_info); 58791e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org __ Push(ToRegister(instr->function())); 588047390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntime(Runtime::kPushBlockContext, 2, instr); 58811e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org RecordSafepoint(Safepoint::kNoLazyDeopt); 58821e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org} 58831e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org 58841e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org 5885c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#undef __ 5886c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5887c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} } // namespace v8::internal 5888c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5889c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#endif // V8_TARGET_ARCH_X64 5890