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 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/x64/lithium-codegen-x64.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/code-stubs.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/stub-cache.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-osr.h" 13c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 14c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgnamespace v8 { 15c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgnamespace internal { 16c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 17c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org// When invoking builtins, we need to record the safepoint in the middle of 193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org// the invoke instruction sequence generated by the macro assembler. 2032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.orgclass SafepointGenerator V8_FINAL : public CallWrapper { 213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org public: 223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org SafepointGenerator(LCodeGen* codegen, 233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LPointerMap* pointers, 2427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode mode) 253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org : codegen_(codegen), 263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org pointers_(pointers), 2727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org deopt_mode_(mode) { } 2832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual ~SafepointGenerator() {} 293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 305c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org virtual void BeforeCall(int call_size) const V8_OVERRIDE {} 31eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org 3232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual void AfterCall() const V8_OVERRIDE { 3327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org codegen_->RecordSafepoint(pointers_, deopt_mode_); 343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org private: 373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LCodeGen* codegen_; 383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LPointerMap* pointers_; 3927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode deopt_mode_; 403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}; 413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 43c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#define __ masm()-> 44c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 45c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgbool LCodeGen::GenerateCode() { 461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org LPhase phase("Z_Code generation", chunk()); 47c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(is_unused()); 48c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org status_ = GENERATING; 49c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 50c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Open a frame scope to indicate that there is a frame on the stack. The 51c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // MANUAL indicates that the scope shouldn't actually generate code to set up 52c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the frame (that is done in GeneratePrologue). 53c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope frame_scope(masm_, StackFrame::MANUAL); 54c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 55c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return GeneratePrologue() && 56c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org GenerateBody() && 57c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org GenerateDeferredCode() && 589ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org GenerateJumpTable() && 59c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org GenerateSafepointTable(); 60c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 61c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 62c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 63c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::FinishCode(Handle<Code> code) { 64c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(is_done()); 65160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org code->set_stack_slots(GetStackSlotCount()); 6683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); 67f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code); 68c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org PopulateDeoptimizationData(code); 69c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 70c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 71c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 72d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#ifdef _MSC_VER 73d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid LCodeGen::MakeSureStackPagesMapped(int offset) { 74d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org const int kPageSize = 4 * KB; 75d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org for (offset -= kPageSize; offset > 0; offset -= kPageSize) { 7643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rsp, offset), rax); 77d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 78d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 79d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#endif 80d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 81d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 82f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgvoid LCodeGen::SaveCallerDoubles() { 83f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(info()->saves_caller_doubles()); 84f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(NeedsEagerFrame()); 85f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Comment(";;; Save clobbered callee double registers"); 86f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org int count = 0; 87f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org BitVector* doubles = chunk()->allocated_double_registers(); 88f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org BitVector::Iterator save_iterator(doubles); 89f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org while (!save_iterator.Done()) { 90f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org __ movsd(MemOperand(rsp, count * kDoubleSize), 91f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org XMMRegister::FromAllocationIndex(save_iterator.Current())); 92f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org save_iterator.Advance(); 93f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org count++; 94f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } 95f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org} 96f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 97f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 98f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgvoid LCodeGen::RestoreCallerDoubles() { 99f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(info()->saves_caller_doubles()); 100f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(NeedsEagerFrame()); 101f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Comment(";;; Restore clobbered callee double registers"); 102f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org BitVector* doubles = chunk()->allocated_double_registers(); 103f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org BitVector::Iterator save_iterator(doubles); 104f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org int count = 0; 105f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org while (!save_iterator.Done()) { 106f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org __ movsd(XMMRegister::FromAllocationIndex(save_iterator.Current()), 107f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org MemOperand(rsp, count * kDoubleSize)); 108f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org save_iterator.Advance(); 109f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org count++; 110f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } 111f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org} 112f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 113f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 114c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgbool LCodeGen::GeneratePrologue() { 115c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(is_generating()); 116c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 117a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (info()->IsOptimizing()) { 118a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ProfileEntryHookStub::MaybeCallEntryHook(masm_); 119753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org 120c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#ifdef DEBUG 121a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (strlen(FLAG_stop_at) > 0 && 12259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 123a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ int3(); 124a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 125c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#endif 126c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 127486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org // Sloppy mode functions need to replace the receiver with the global proxy 128e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // when called as functions (without an explicit receiver object). 129e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org if (info_->this_has_uses() && 130486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org info_->strict_mode() == SLOPPY && 131e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org !info_->is_native()) { 132a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Label ok; 133d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StackArgumentsAccessor args(rsp, scope()->num_parameters()); 13443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, args.GetReceiverOperand()); 135e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 136e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex); 137e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ j(not_equal, &ok, Label::kNear); 138e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 13943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, GlobalObjectOperand()); 14043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); 141e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 14243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(args.GetReceiverOperand(), rcx); 143e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 144a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ bind(&ok); 145a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 14640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } 14740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 14883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org info()->set_prologue_offset(masm_->pc_offset()); 149a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (NeedsEagerFrame()) { 150a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(!frame_is_built_); 151a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org frame_is_built_ = true; 152285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org if (info()->IsStub()) { 153285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org __ StubPrologue(); 154285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org } else { 155285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org __ Prologue(info()->IsCodePreAgingActive()); 156285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org } 1574e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org info()->AddNoFrameRange(0, masm_->pc_offset()); 158a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 159c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 160c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Reserve space for the stack slots needed by the code. 161160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org int slots = GetStackSlotCount(); 162c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (slots > 0) { 163c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (FLAG_debug_code) { 164fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rsp, Immediate(slots * kPointerSize)); 165d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#ifdef _MSC_VER 166d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org MakeSureStackPagesMapped(slots * kPointerSize); 167d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#endif 168763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 169a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org __ Set(rax, slots); 170e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movq(kScratchRegister, kSlotsZapValue); 171c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Label loop; 172c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org __ bind(&loop); 17343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(MemOperand(rsp, rax, times_pointer_size, 0), 17494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org kScratchRegister); 175c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org __ decl(rax); 176c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org __ j(not_zero, &loop); 177763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rax); 178c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else { 179fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rsp, Immediate(slots * kPointerSize)); 180c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#ifdef _MSC_VER 181d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org MakeSureStackPagesMapped(slots * kPointerSize); 182c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#endif 183c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 18494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 18594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (info()->saves_caller_doubles()) { 186f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org SaveCallerDoubles(); 18794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 188c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 189c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Possibly allocate a local context. 191a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 1923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (heap_slots > 0) { 1933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Comment(";;; Allocate local context"); 1947e6132b924829c353864933f29124419916db550machenbach@chromium.org bool need_write_barrier = true; 1953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Argument to NewContext is the function, which is still in rdi. 1963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (heap_slots <= FastNewContextStub::kMaximumSlots) { 197f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org FastNewContextStub stub(isolate(), heap_slots); 1983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ CallStub(&stub); 1997e6132b924829c353864933f29124419916db550machenbach@chromium.org // Result of FastNewContextStub is always in new space. 2007e6132b924829c353864933f29124419916db550machenbach@chromium.org need_write_barrier = false; 2013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 202763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdi); 203895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); 2043a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 20527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(Safepoint::kNoLazyDeopt); 206bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org // Context is returned in rax. It replaces the context passed to us. 207bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org // It's saved in the stack and kept live in rsi. 208bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org __ movp(rsi, rax); 209bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rax); 2103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 2113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Copy any necessary parameters into the context. 2123a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int num_parameters = scope()->num_parameters(); 2133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org for (int i = 0; i < num_parameters; i++) { 214486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Variable* var = scope()->parameter(i); 215486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (var->IsContextSlot()) { 2163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int parameter_offset = StandardFrameConstants::kCallerSPOffset + 2173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org (num_parameters - 1 - i) * kPointerSize; 2183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Load parameter from stack. 21943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, Operand(rbp, parameter_offset)); 2203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Store it in the context. 221486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org int context_offset = Context::SlotOffset(var->index()); 22243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rsi, context_offset), rax); 223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Update the write barrier. This clobbers rax and rbx. 2247e6132b924829c353864933f29124419916db550machenbach@chromium.org if (need_write_barrier) { 2257e6132b924829c353864933f29124419916db550machenbach@chromium.org __ RecordWriteContextSlot(rsi, context_offset, rax, rbx, kSaveFPRegs); 2267e6132b924829c353864933f29124419916db550machenbach@chromium.org } else if (FLAG_debug_code) { 2277e6132b924829c353864933f29124419916db550machenbach@chromium.org Label done; 2287e6132b924829c353864933f29124419916db550machenbach@chromium.org __ JumpIfInNewSpace(rsi, rax, &done, Label::kNear); 2297e6132b924829c353864933f29124419916db550machenbach@chromium.org __ Abort(kExpectedNewSpaceObject); 2307e6132b924829c353864933f29124419916db550machenbach@chromium.org __ bind(&done); 2317e6132b924829c353864933f29124419916db550machenbach@chromium.org } 2323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 2333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 2343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Comment(";;; End allocate local context"); 2353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 2363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 237c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Trace the call. 238a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (FLAG_trace && info()->IsOptimizing()) { 239c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org __ CallRuntime(Runtime::kTraceEnter, 0); 240c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 241c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return !is_aborted(); 242c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 243c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 244c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 245c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid LCodeGen::GenerateOsrPrologue() { 246c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Generate the OSR entry prologue at the first unknown OSR value, or if there 247c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // are none, at the OSR entrypoint instruction. 248c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org if (osr_pc_offset_ >= 0) return; 249c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 250c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org osr_pc_offset_ = masm()->pc_offset(); 251c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 252c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Adjust the frame size, subsuming the unoptimized frame into the 253c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // optimized frame. 254c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots(); 255c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org ASSERT(slots >= 0); 256fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rsp, Immediate(slots * kPointerSize)); 257c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 258c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 259c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 260486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.orgvoid LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) { 261fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (instr->IsCall()) { 262fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 263fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 264486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (!instr->IsLazyBailout() && !instr->IsGap()) { 265486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org safepoints_.BumpLastLazySafepointIndex(); 266486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } 267486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org} 268486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org 269486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org 270895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgvoid LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { 2712ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (FLAG_debug_code && FLAG_enable_slow_asserts && instr->HasResult() && 2722ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org instr->hydrogen_value()->representation().IsInteger32() && 2732ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org instr->result()->IsRegister()) { 2742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ AssertZeroExtended(ToRegister(instr->result())); 2752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 2762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org 277895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org if (instr->HasResult() && instr->MustSignExtendResult(chunk())) { 2781845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // We sign extend the dehoisted key at the definition point when the pointer 2791845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // size is 64-bit. For x32 port, we sign extend the dehoisted key at the use 2801845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // points and MustSignExtendResult is always false. We can't use 2811845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // STATIC_ASSERT here as the pointer size is 32-bit for x32. 2821845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org ASSERT(kPointerSize == kInt64Size); 283895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org if (instr->result()->IsRegister()) { 284895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Register result_reg = ToRegister(instr->result()); 285895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ movsxlq(result_reg, result_reg); 286895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } else { 287895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // Sign extend the 32bit result in the stack slots. 288895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ASSERT(instr->result()->IsStackSlot()); 289895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Operand src = ToOperand(instr->result()); 290895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ movsxlq(kScratchRegister, src); 291895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ movq(src, kScratchRegister); 292895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 293895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 294895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org} 295895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 296895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 2979ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.orgbool LCodeGen::GenerateJumpTable() { 298169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Label needs_frame; 29932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (jump_table_.length() > 0) { 30032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; -------------------- Jump table --------------------"); 30132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org } 3029ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org for (int i = 0; i < jump_table_.length(); i++) { 303eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org __ bind(&jump_table_[i].label); 304a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Address entry = jump_table_[i].address; 305aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org Deoptimizer::BailoutType type = jump_table_[i].bailout_type; 306876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); 307068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org if (id == Deoptimizer::kNotDeoptimizationEntry) { 308068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org Comment(";;; jump table entry %d.", i); 309068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } else { 310068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); 311068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } 312a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (jump_table_[i].needs_frame) { 313f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(!info()->saves_caller_doubles()); 314e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Move(kScratchRegister, ExternalReference::ForDeoptEntry(entry)); 315169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (needs_frame.is_bound()) { 316169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ jmp(&needs_frame); 317a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 318169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ bind(&needs_frame); 31943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, MemOperand(rbp, StandardFrameConstants::kContextOffset)); 320763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbp); 32143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbp, rsp); 322763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); 323169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // This variant of deopt can only be used with stubs. Since we don't 324169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // have a function pointer to install in the stack frame that we're 325169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // building, install a special marker there instead. 326169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(info()->IsStub()); 327169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ Move(rsi, Smi::FromInt(StackFrame::STUB)); 328763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); 32943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, MemOperand(rsp, kPointerSize)); 330169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ call(kScratchRegister); 331a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 332a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 333f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (info()->saves_caller_doubles()) { 334f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(info()->IsStub()); 335f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org RestoreCallerDoubles(); 336f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } 337169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ call(entry, RelocInfo::RUNTIME_ENTRY); 338a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 3399ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 3409ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org return !is_aborted(); 3419ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org} 3429ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 3439ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 344c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgbool LCodeGen::GenerateDeferredCode() { 345c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(is_generating()); 346ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org if (deferred_.length() > 0) { 347ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 348ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org LDeferredCode* code = deferred_[i]; 349594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 35071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org HValue* value = 35171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org instructions_->at(code->instruction_index())->hydrogen_value(); 352f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org RecordAndWritePosition( 353f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org chunk()->graph()->SourcePositionToScriptPosition(value->position())); 354594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 35532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; <@%d,#%d> " 35632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org "-------------------- Deferred %s --------------------", 35732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org code->instruction_index(), 35832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org code->instr()->hydrogen_value()->id(), 35932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org code->instr()->Mnemonic()); 360ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org __ bind(code->entry()); 361a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (NeedsDeferredFrame()) { 36232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; Build frame"); 363a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(!frame_is_built_); 364a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(info()->IsStub()); 365a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org frame_is_built_ = true; 366a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Build the frame in such a way that esi isn't trashed. 367763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbp); // Caller's frame pointer. 368763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rbp, StandardFrameConstants::kContextOffset)); 369a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ Push(Smi::FromInt(StackFrame::STUB)); 370895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rbp, Operand(rsp, 2 * kPointerSize)); 37132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; Deferred code"); 372a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 373ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org code->Generate(); 374a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (NeedsDeferredFrame()) { 375c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ bind(code->done()); 37632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; Destroy frame"); 377a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(frame_is_built_); 378a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org frame_is_built_ = false; 37943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsp, rbp); 380763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbp); 381a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 382ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org __ jmp(code->exit()); 383ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org } 384c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 385c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 386c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Deferred code is the last part of the instruction sequence. Mark 387c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // the generated code as done unless we bailed out. 388c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (!is_aborted()) status_ = DONE; 389c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return !is_aborted(); 390c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 391c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 392c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 393c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgbool LCodeGen::GenerateSafepointTable() { 3940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ASSERT(is_done()); 395160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org safepoints_.Emit(masm(), GetStackSlotCount()); 3960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return !is_aborted(); 397c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 398c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 399c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 400c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgRegister LCodeGen::ToRegister(int index) const { 401c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return Register::FromAllocationIndex(index); 402c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 403c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 404c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 405c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgXMMRegister LCodeGen::ToDoubleRegister(int index) const { 406c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return XMMRegister::FromAllocationIndex(index); 407c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 408c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 409c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 410c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgRegister LCodeGen::ToRegister(LOperand* op) const { 411c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(op->IsRegister()); 412c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return ToRegister(op->index()); 413c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 414c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 415c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 416c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgXMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const { 417c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(op->IsDoubleRegister()); 418c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return ToDoubleRegister(op->index()); 419c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 420c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 421c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 422c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgbool LCodeGen::IsInteger32Constant(LConstantOperand* op) const { 423a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); 424c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 425c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 426c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 427895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgbool LCodeGen::IsDehoistedKeyConstant(LConstantOperand* op) const { 428895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org return op->IsConstantOperand() && 429895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org chunk_->IsDehoistedKey(chunk_->LookupConstant(op)); 430895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org} 431895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 432895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 433a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgbool LCodeGen::IsSmiConstant(LConstantOperand* op) const { 434a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org return chunk_->LookupLiteralRepresentation(op).IsSmi(); 435c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 436c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 437c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 438fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgint32_t LCodeGen::ToInteger32(LConstantOperand* op) const { 43970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org return ToRepresentation(op, Representation::Integer32()); 44070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org} 44170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org 44270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org 44370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.orgint32_t LCodeGen::ToRepresentation(LConstantOperand* op, 44470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org const Representation& r) const { 445657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org HConstant* constant = chunk_->LookupConstant(op); 44670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org int32_t value = constant->Integer32Value(); 44770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (r.IsInteger32()) return value; 44870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ASSERT(SmiValuesAre31Bits() && r.IsSmiOrTagged()); 44970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org return static_cast<int32_t>(reinterpret_cast<intptr_t>(Smi::FromInt(value))); 450c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 451c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 452c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 453c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgSmi* LCodeGen::ToSmi(LConstantOperand* op) const { 454c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org HConstant* constant = chunk_->LookupConstant(op); 455c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org return Smi::FromInt(constant->Integer32Value()); 456c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org} 457c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 458c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 459394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comdouble LCodeGen::ToDouble(LConstantOperand* op) const { 460657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org HConstant* constant = chunk_->LookupConstant(op); 461657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org ASSERT(constant->HasDoubleValue()); 462657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org return constant->DoubleValue(); 463394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 464394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 465394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 466d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgExternalReference LCodeGen::ToExternalReference(LConstantOperand* op) const { 467d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HConstant* constant = chunk_->LookupConstant(op); 468d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(constant->HasExternalReferenceValue()); 469d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return constant->ExternalReferenceValue(); 470d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 471d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 472d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 473c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgHandle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { 474657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org HConstant* constant = chunk_->LookupConstant(op); 475a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); 476639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org return constant->handle(isolate()); 477c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 478c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 479c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 480ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgstatic int ArgumentsOffsetWithoutFrame(int index) { 481ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(index < 0); 482ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org return -(index + 1) * kPointerSize + kPCOnStackSize; 483ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org} 484ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 485ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 486c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgOperand LCodeGen::ToOperand(LOperand* op) const { 487c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Does not handle registers. In X64 assembler, plain registers are not 488c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // representable as an Operand. 489c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); 490ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (NeedsEagerFrame()) { 491ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org return Operand(rbp, StackSlotOffset(op->index())); 492ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } else { 493ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // Retrieve parameter without eager stack-frame relative to the 494ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // stack-pointer. 495ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org return Operand(rsp, ArgumentsOffsetWithoutFrame(op->index())); 496ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 497c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 498c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 499c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 500c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::WriteTranslation(LEnvironment* environment, 501b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Translation* translation) { 502c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (environment == NULL) return; 503c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 504c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // The translation includes one command per value in the environment. 505b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org int translation_size = environment->translation_size(); 506c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // The output frame height does not include the parameters. 507c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int height = translation_size - environment->parameter_count(); 508c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 509b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org WriteTranslation(environment->outer(), translation); 510a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool has_closure_id = !info()->closure().is_null() && 51132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org !info()->closure().is_identical_to(environment->closure()); 512a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int closure_id = has_closure_id 5135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ? DefineDeoptimizationLiteral(environment->closure()) 5145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org : Translation::kSelfLiteralId; 5155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 516967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org switch (environment->frame_type()) { 517967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org case JS_FUNCTION: 518967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org translation->BeginJSFrame(environment->ast_id(), closure_id, height); 519967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org break; 520967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org case JS_CONSTRUCT: 521967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org translation->BeginConstructStubFrame(closure_id, translation_size); 522967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org break; 523de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org case JS_GETTER: 524de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org ASSERT(translation_size == 1); 525de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org ASSERT(height == 0); 526de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org translation->BeginGetterStubFrame(closure_id); 527de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org break; 528471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org case JS_SETTER: 52946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ASSERT(translation_size == 2); 53046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ASSERT(height == 0); 53146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org translation->BeginSetterStubFrame(closure_id); 532471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org break; 533967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org case ARGUMENTS_ADAPTOR: 534967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); 535967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org break; 536a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org case STUB: 537a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org translation->BeginCompiledStubFrame(); 538a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org break; 539659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 54056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 541594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int object_index = 0; 542594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int dematerialized_index = 0; 543c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = 0; i < translation_size; ++i) { 544c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LOperand* value = environment->values()->at(i); 545594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org AddToTranslation(environment, 546594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation, 54746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org value, 54846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org environment->HasTaggedValueAt(i), 549594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org environment->HasUint32ValueAt(i), 550594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org &object_index, 551594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org &dematerialized_index); 552c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 553c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 554c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 555c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 556594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::AddToTranslation(LEnvironment* environment, 557594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Translation* translation, 558c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LOperand* op, 55946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org bool is_tagged, 560594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org bool is_uint32, 561594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int* object_index_pointer, 562594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int* dematerialized_index_pointer) { 563594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (op == LEnvironment::materialization_marker()) { 564594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int object_index = (*object_index_pointer)++; 565594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (environment->ObjectIsDuplicateAt(object_index)) { 566594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int dupe_of = environment->ObjectDuplicateOfAt(object_index); 567594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation->DuplicateObject(dupe_of); 568594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return; 569594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 570594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int object_length = environment->ObjectLengthAt(object_index); 571594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (environment->ObjectIsArgumentsAt(object_index)) { 572594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation->BeginArgumentsObject(object_length); 573594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 574594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation->BeginCapturedObject(object_length); 575594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 576594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int dematerialized_index = *dematerialized_index_pointer; 577594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int env_offset = environment->translation_size() + dematerialized_index; 578594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org *dematerialized_index_pointer += object_length; 579594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org for (int i = 0; i < object_length; ++i) { 580594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org LOperand* value = environment->values()->at(env_offset + i); 581594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org AddToTranslation(environment, 582594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org translation, 583594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org value, 584594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org environment->HasTaggedValueAt(env_offset + i), 585594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org environment->HasUint32ValueAt(env_offset + i), 586594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org object_index_pointer, 587594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org dematerialized_index_pointer); 588594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 589594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return; 590594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 591594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 592b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (op->IsStackSlot()) { 593c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (is_tagged) { 594c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreStackSlot(op->index()); 59546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } else if (is_uint32) { 59646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org translation->StoreUint32StackSlot(op->index()); 597c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else { 598c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreInt32StackSlot(op->index()); 599c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 600c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else if (op->IsDoubleStackSlot()) { 601c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreDoubleStackSlot(op->index()); 602c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else if (op->IsRegister()) { 603c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Register reg = ToRegister(op); 604c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (is_tagged) { 605c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreRegister(reg); 60646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } else if (is_uint32) { 60746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org translation->StoreUint32Register(reg); 608c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else { 609c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreInt32Register(reg); 610c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 611c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else if (op->IsDoubleRegister()) { 612c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org XMMRegister reg = ToDoubleRegister(op); 613c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreDoubleRegister(reg); 614c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else if (op->IsConstantOperand()) { 615657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op)); 616639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org int src_index = DefineDeoptimizationLiteral(constant->handle(isolate())); 617c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org translation->StoreLiteral(src_index); 618c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else { 619c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org UNREACHABLE(); 620c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 621c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 622c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 623c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 62444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid LCodeGen::CallCodeGeneric(Handle<Code> code, 62544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org RelocInfo::Mode mode, 62644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org LInstruction* instr, 62744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org SafepointMode safepoint_mode, 62844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org int argc) { 62931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org ASSERT(instr != NULL); 63031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org __ call(code, mode); 63127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepointWithLazyDeopt(instr, safepoint_mode, argc); 6320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 6330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Signal that we don't inline smi code before these stubs in the 6340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // optimizing code generator. 63540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org if (code->kind() == Code::BINARY_OP_IC || 6360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com code->kind() == Code::COMPARE_IC) { 6370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __ nop(); 6380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 639c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 640c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 641c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 64244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid LCodeGen::CallCode(Handle<Code> code, 64344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org RelocInfo::Mode mode, 64444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org LInstruction* instr) { 64544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, 0); 64644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org} 64744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 64844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 649ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid LCodeGen::CallRuntime(const Runtime::Function* function, 650c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int num_arguments, 651fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org LInstruction* instr, 652fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org SaveFPRegsMode save_doubles) { 65383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(instr != NULL); 65483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(instr->HasPointerMap()); 65583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 656fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ CallRuntime(function, num_arguments, save_doubles); 657fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org 65827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); 659c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 660c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 661c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 662935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgvoid LCodeGen::LoadContextFromDeferred(LOperand* context) { 663935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (context->IsRegister()) { 664935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (!ToRegister(context).is(rsi)) { 66543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, ToRegister(context)); 666935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } 667935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (context->IsStackSlot()) { 66843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, ToOperand(context)); 669935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (context->IsConstantOperand()) { 670935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org HConstant* constant = 671935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org chunk_->LookupConstant(LConstantOperand::cast(context)); 672935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ Move(rsi, Handle<Object>::cast(constant->handle(isolate()))); 673935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else { 674935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org UNREACHABLE(); 675935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } 676935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org} 677935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 678935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 679935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 68044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 68144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org int argc, 682935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org LInstruction* instr, 683935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org LOperand* context) { 684935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org LoadContextFromDeferred(context); 685935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 68644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org __ CallRuntimeSaveDoubles(id); 68744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org RecordSafepointWithRegisters( 68827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org instr->pointer_map(), argc, Safepoint::kNoLazyDeopt); 689c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 690c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 691c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 69227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, 69327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode mode) { 6944edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org environment->set_has_been_used(); 6950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (!environment->HasBeenRegistered()) { 6960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Physical stack frame layout: 6970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // -x ............. -4 0 ..................................... y 6980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // [incoming arguments] [spill slots] [pushed outgoing arguments] 6990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Layout of the environment: 7010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // 0 ..................................................... size-1 7020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // [parameters] [locals] [expression stack including arguments] 7030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Layout of the translation: 7050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // 0 ........................................................ size - 1 + 4 7060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // [expression stack including arguments] [locals] [4 words] [parameters] 7070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // |>------------ translation_size ------------<| 7080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7090511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com int frame_count = 0; 710659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org int jsframe_count = 0; 7110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com for (LEnvironment* e = environment; e != NULL; e = e->outer()) { 7120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ++frame_count; 713967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org if (e->frame_type() == JS_FUNCTION) { 714659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org ++jsframe_count; 715659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 7160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 71756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Translation translation(&translations_, frame_count, jsframe_count, zone()); 718b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org WriteTranslation(environment, &translation); 7190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com int deoptimization_index = deoptimizations_.length(); 72027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org int pc_offset = masm()->pc_offset(); 72127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org environment->Register(deoptimization_index, 72227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org translation.index(), 72327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 724400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org deoptimizations_.Add(environment, environment->zone()); 7250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 726c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 727c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 728c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 729aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.orgvoid LCodeGen::DeoptimizeIf(Condition cc, 730aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org LEnvironment* environment, 731aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org Deoptimizer::BailoutType bailout_type) { 73227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 7330ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org ASSERT(environment->HasBeenRegistered()); 7340ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org int id = environment->deoptimization_index(); 735a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(info()->IsOptimizing() || info()->IsStub()); 7368432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Address entry = 7378432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); 7380ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (entry == NULL) { 739594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kBailoutWasNotPrepared); 7400ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org return; 7410ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 7420ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 743935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (DeoptEveryNTimes()) { 744e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ExternalReference count = ExternalReference::stress_deopt_count(isolate()); 745e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label no_deopt; 746e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ pushfq(); 747763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 748e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Operand count_operand = masm()->ExternalOperand(count, kScratchRegister); 749e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movl(rax, count_operand); 750e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ subl(rax, Immediate(1)); 751e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ j(not_zero, &no_deopt, Label::kNear); 752e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (FLAG_trap_on_deopt) __ int3(); 753e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movl(rax, Immediate(FLAG_deopt_every_n_times)); 754e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movl(count_operand, rax); 755763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rax); 756e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ popfq(); 757e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(frame_is_built_); 758e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ call(entry, RelocInfo::RUNTIME_ENTRY); 759e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ bind(&no_deopt); 760e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movl(count_operand, rax); 761763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rax); 762e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ popfq(); 763e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 7647c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 765594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (info()->ShouldTrapOnDeopt()) { 7667c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Label done; 7677c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (cc != no_condition) { 7687c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ j(NegateCondition(cc), &done, Label::kNear); 7697c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 7707c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ int3(); 7717c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ bind(&done); 7727c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 7737c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 774a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(info()->IsStub() || frame_is_built_); 775f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Go through jump table if we need to handle condition, build frame, or 776f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // restore caller doubles. 777f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (cc == no_condition && frame_is_built_ && 778f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !info()->saves_caller_doubles()) { 779169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org __ call(entry, RelocInfo::RUNTIME_ENTRY); 7800ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else { 7819ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // We often have several deopts to the same entry, reuse the last 7829ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // jump entry if this is the case. 783eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org if (jump_table_.is_empty() || 784a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org jump_table_.last().address != entry || 785a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org jump_table_.last().needs_frame != !frame_is_built_ || 786aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org jump_table_.last().bailout_type != bailout_type) { 787aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org Deoptimizer::JumpTableEntry table_entry(entry, 788aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org bailout_type, 789aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org !frame_is_built_); 790a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org jump_table_.Add(table_entry, zone()); 7919ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 7927c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (cc == no_condition) { 7937c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ jmp(&jump_table_.last().label); 7947c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } else { 7957c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org __ j(cc, &jump_table_.last().label); 7967c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 7970ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 798c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 799c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 800c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 801aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.orgvoid LCodeGen::DeoptimizeIf(Condition cc, 802aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org LEnvironment* environment) { 803aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org Deoptimizer::BailoutType bailout_type = info()->IsStub() 804aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org ? Deoptimizer::LAZY 805aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org : Deoptimizer::EAGER; 806aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org DeoptimizeIf(cc, environment, bailout_type); 807aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org} 808aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org 809aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org 810c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 811c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int length = deoptimizations_.length(); 812c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (length == 0) return; 813c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Handle<DeoptimizationInputData> data = 8143484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org DeoptimizationInputData::New(isolate(), length, TENURED); 815c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 816876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org Handle<ByteArray> translations = 817876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org translations_.CreateByteArray(isolate()->factory()); 8189ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org data->SetTranslationByteArray(*translations); 819c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); 820f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org data->SetOptimizationId(Smi::FromInt(info_->optimization_id())); 821f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (info_->IsOptimizing()) { 822f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Reference to shared function info does not change between phases. 823f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org AllowDeferredHandleDereference allow_handle_dereference; 824f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org data->SetSharedFunctionInfo(*info_->shared_info()); 825f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 826f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org data->SetSharedFunctionInfo(Smi::FromInt(0)); 827f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 828c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 829c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Handle<FixedArray> literals = 830ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); 83179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org { AllowDeferredHandleDereference copy_handles; 83232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org for (int i = 0; i < deoptimization_literals_.length(); i++) { 83332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org literals->set(i, *deoptimization_literals_[i]); 83432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org } 83532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org data->SetLiteralArray(*literals); 836c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 837c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 838471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); 839c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); 840c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 841c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Populate the deoptimization entries. 842c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = 0; i < length; i++) { 843c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LEnvironment* env = deoptimizations_[i]; 844471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org data->SetAstId(i, env->ast_id()); 845c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); 846c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data->SetArgumentsStackHeight(i, 847c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Smi::FromInt(env->arguments_stack_height())); 84827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org data->SetPc(i, Smi::FromInt(env->pc_offset())); 849c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 850c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org code->set_deoptimization_data(*data); 851c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 852c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 853c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 854c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgint LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) { 855c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int result = deoptimization_literals_.length(); 856c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = 0; i < deoptimization_literals_.length(); ++i) { 857c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (deoptimization_literals_[i].is_identical_to(literal)) return i; 858c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 8597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org deoptimization_literals_.Add(literal, zone()); 860c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org return result; 861c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 862c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 863c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 864c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() { 865c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(deoptimization_literals_.length() == 0); 866c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 867c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org const ZoneList<Handle<JSFunction> >* inlined_closures = 868c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org chunk()->inlined_closures(); 869c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 870c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = 0, length = inlined_closures->length(); 871c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org i < length; 872c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org i++) { 873c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org DefineDeoptimizationLiteral(inlined_closures->at(i)); 874c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 875c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 876c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org inlined_function_count_ = deoptimization_literals_.length(); 877c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 878c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 879c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 88027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::RecordSafepointWithLazyDeopt( 88127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org LInstruction* instr, SafepointMode safepoint_mode, int argc) { 88227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { 88327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt); 88427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } else { 88527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS); 88627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepointWithRegisters( 88727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org instr->pointer_map(), argc, Safepoint::kLazyDeopt); 88827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } 88927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org} 89027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org 89127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org 892378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid LCodeGen::RecordSafepoint( 893378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org LPointerMap* pointers, 894378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Safepoint::Kind kind, 895378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org int arguments, 89627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode deopt_mode) { 89744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ASSERT(kind == expected_safepoint_kind_); 89844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 899c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com const ZoneList<LOperand*>* operands = pointers->GetNormalizedOperands(); 90083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 901c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org Safepoint safepoint = safepoints_.DefineSafepoint(masm(), 90227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org kind, arguments, deopt_mode); 903c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = 0; i < operands->length(); i++) { 904c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LOperand* pointer = operands->at(i); 905c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (pointer->IsStackSlot()) { 906400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org safepoint.DefinePointerSlot(pointer->index(), zone()); 907378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { 9087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org safepoint.DefinePointerRegister(ToRegister(pointer), zone()); 909c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 910c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 911378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org} 912378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 913378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 914378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid LCodeGen::RecordSafepoint(LPointerMap* pointers, 91527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode deopt_mode) { 91627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode); 917c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 918c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 919c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 92027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) { 92171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org LPointerMap empty_pointers(zone()); 92227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(&empty_pointers, deopt_mode); 9233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 9243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 9253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 926c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, 927c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int arguments, 92827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org Safepoint::DeoptMode deopt_mode) { 92927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, deopt_mode); 930c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 931c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 932c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 93371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.orgvoid LCodeGen::RecordAndWritePosition(int position) { 9346d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org if (position == RelocInfo::kNoPosition) return; 935c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org masm()->positions_recorder()->RecordPosition(position); 93671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org masm()->positions_recorder()->WriteRecordedPositions(); 937594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 938594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 939594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 94032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.orgstatic const char* LabelType(LLabel* label) { 94132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (label->is_loop_header()) return " (loop header)"; 94232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (label->is_osr_entry()) return " (OSR entry)"; 94332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org return ""; 94432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org} 94532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org 94632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org 947c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLabel(LLabel* label) { 94832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", 94932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org current_instruction_, 95032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org label->hydrogen_value()->id(), 951b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org label->block_id(), 95232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org LabelType(label)); 953c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org __ bind(label->label()); 954c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org current_block_ = label->block_id(); 9558e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org DoGap(label); 956c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 957c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 958c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 959c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoParallelMove(LParallelMove* move) { 9600ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org resolver_.Resolve(move); 961c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 962c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 963c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 964c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoGap(LGap* gap) { 965c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org for (int i = LGap::FIRST_INNER_POSITION; 966c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org i <= LGap::LAST_INNER_POSITION; 967c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org i++) { 968c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LGap::InnerPosition inner_pos = static_cast<LGap::InnerPosition>(i); 969c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org LParallelMove* move = gap->GetParallelMove(inner_pos); 970c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org if (move != NULL) DoParallelMove(move); 971c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 972c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 973c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 974c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 9758e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid LCodeGen::DoInstructionGap(LInstructionGap* instr) { 9768e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org DoGap(instr); 9778e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org} 9788e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org 9798e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org 980c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoParameter(LParameter* instr) { 981c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org // Nothing to do. 982c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 983c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 984c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 985c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCallStub(LCallStub* instr) { 986935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 987d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ASSERT(ToRegister(instr->result()).is(rax)); 988d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com switch (instr->hydrogen()->major_key()) { 989d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com case CodeStub::RegExpExec: { 990f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org RegExpExecStub stub(isolate()); 991f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 992d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com break; 993d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 994d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com case CodeStub::SubString: { 995f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org SubStringStub stub(isolate()); 996f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 997d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com break; 998d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 999d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com case CodeStub::StringCompare: { 1000f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org StringCompareStub stub(isolate()); 1001f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1002d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com break; 1003d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1004d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com default: 1005d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com UNREACHABLE(); 1006d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1007c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1008c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1009c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1010c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 1011c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org GenerateOsrPrologue(); 1012c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1013c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1014c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1015ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) { 1016ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1017ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t divisor = instr->divisor(); 1018ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT(dividend.is(ToRegister(instr->result()))); 1019ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1020ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Theoretically, a variation of the branch-free code for integer division by 1021ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // a power of 2 (calculating the remainder via an additional multiplication 1022ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // (which gets simplified to an 'and') and subtraction) should be faster, and 1023ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // this is exactly what GCC and clang emit. Nevertheless, benchmarks seem to 1024ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // indicate that positive dividends are heavily favored, so the branching 1025ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // version performs better. 1026ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org HMod* hmod = instr->hydrogen(); 1027ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1028ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Label dividend_is_not_negative, done; 1029381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) { 1030ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(dividend, dividend); 1031ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ j(not_sign, ÷nd_is_not_negative, Label::kNear); 1032ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Note that this is correct even for kMinInt operands. 1033ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ negl(dividend); 1034ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ andl(dividend, Immediate(mask)); 1035ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ negl(dividend); 1036ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1037ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org DeoptimizeIf(zero, instr->environment()); 1038ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1039ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ jmp(&done, Label::kNear); 1040ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1041ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1042ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(÷nd_is_not_negative); 1043ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ andl(dividend, Immediate(mask)); 1044ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(&done); 1045ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org} 1046ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1047ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1048bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgvoid LCodeGen::DoModByConstI(LModByConstI* instr) { 1049bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1050bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org int32_t divisor = instr->divisor(); 1051bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org ASSERT(ToRegister(instr->result()).is(rax)); 1052bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1053bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (divisor == 0) { 1054bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org DeoptimizeIf(no_condition, instr->environment()); 1055bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org return; 1056bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 1057bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1058763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ TruncatingDiv(dividend, Abs(divisor)); 1059bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ imull(rdx, rdx, Immediate(Abs(divisor))); 1060bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ movl(rax, dividend); 1061bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ subl(rax, rdx); 1062bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1063bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // Check for negative zero. 1064bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HMod* hmod = instr->hydrogen(); 1065486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1066bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org Label remainder_not_zero; 1067bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ j(not_zero, &remainder_not_zero, Label::kNear); 1068bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ cmpl(dividend, Immediate(0)); 1069bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org DeoptimizeIf(less, instr->environment()); 1070bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ bind(&remainder_not_zero); 1071bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 1072bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org} 1073bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1074bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1075c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoModI(LModI* instr) { 10768a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org HMod* hmod = instr->hydrogen(); 10778a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org 1078ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register left_reg = ToRegister(instr->left()); 1079ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT(left_reg.is(rax)); 1080ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register right_reg = ToRegister(instr->right()); 1081ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT(!right_reg.is(rax)); 1082ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT(!right_reg.is(rdx)); 1083ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register result_reg = ToRegister(instr->result()); 1084ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT(result_reg.is(rdx)); 10853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1086ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Label done; 1087ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Check for x % 0, idiv would signal a divide error. We have to 1088ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // deopt in this case because we can't return a NaN. 1089486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { 1090ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(right_reg, right_reg); 1091ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org DeoptimizeIf(zero, instr->environment()); 1092ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1093a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1094ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Check for kMinInt % -1, idiv would signal a divide error. We 1095ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // have to deopt if we care about -0, because we can't return that. 1096486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hmod->CheckFlag(HValue::kCanOverflow)) { 1097ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Label no_overflow_possible; 1098ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ cmpl(left_reg, Immediate(kMinInt)); 1099ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ j(not_zero, &no_overflow_possible, Label::kNear); 1100ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ cmpl(right_reg, Immediate(-1)); 1101ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1102ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org DeoptimizeIf(equal, instr->environment()); 1103ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } else { 1104ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ j(not_equal, &no_overflow_possible, Label::kNear); 1105ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ Set(result_reg, 0); 11068a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ jmp(&done, Label::kNear); 1107b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org } 1108ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(&no_overflow_possible); 1109ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1110ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1111ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Sign extend dividend in eax into edx:eax, since we are using only the low 1112ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // 32 bits of the values. 1113ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ cdq(); 1114ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1115ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // If we care about -0, test if the dividend is <0 and the result is 0. 1116486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1117ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Label positive_left; 1118ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(left_reg, left_reg); 1119ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ j(not_sign, &positive_left, Label::kNear); 11208a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ idivl(right_reg); 1121ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(result_reg, result_reg); 1122ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org DeoptimizeIf(zero, instr->environment()); 1123ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ jmp(&done, Label::kNear); 1124ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(&positive_left); 11253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 1126ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ idivl(right_reg); 1127ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(&done); 1128c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1129c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1130c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1131ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { 1132ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1133ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t divisor = instr->divisor(); 1134ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT(dividend.is(ToRegister(instr->result()))); 1135d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1136ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // If the divisor is positive, things are easy: There can be no deopts and we 1137ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // can simply do an arithmetic right shift. 1138ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (divisor == 1) return; 1139ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t shift = WhichPowerOf2Abs(divisor); 1140ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (divisor > 1) { 1141ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ sarl(dividend, Immediate(shift)); 1142d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org return; 1143ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1144d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1145ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // If the divisor is negative, we have to negate and handle edge cases. 1146ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ negl(dividend); 1147ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1148ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org DeoptimizeIf(zero, instr->environment()); 1149ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 11509e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org 11518ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org // Dividing by -1 is basically negation, unless we overflow. 11528ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org if (divisor == -1) { 11538ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 11548ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org DeoptimizeIf(overflow, instr->environment()); 11558ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org } 11569e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org return; 11579e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org } 11589e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org 11598ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org // If the negation could not overflow, simply shifting is OK. 11608ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 11618ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org __ sarl(dividend, Immediate(shift)); 11629e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org return; 1163ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 11649e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org 11659e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org Label not_kmin_int, done; 11669e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org __ j(no_overflow, ¬_kmin_int, Label::kNear); 11679e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org __ movl(dividend, Immediate(kMinInt / divisor)); 11689e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org __ jmp(&done, Label::kNear); 1169ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(¬_kmin_int); 1170ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ sarl(dividend, Immediate(shift)); 1171ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(&done); 1172ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org} 1173d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1174ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1175ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { 1176ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1177ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t divisor = instr->divisor(); 1178bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org ASSERT(ToRegister(instr->result()).is(rdx)); 1179ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 1180ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (divisor == 0) { 1181ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org DeoptimizeIf(no_condition, instr->environment()); 1182d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org return; 1183d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1184d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1185bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // Check for (0 / -x) that will produce negative zero. 1186bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HMathFloorOfDiv* hdiv = instr->hydrogen(); 1187486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1188bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ testl(dividend, dividend); 1189ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org DeoptimizeIf(zero, instr->environment()); 1190d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org } 1191ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 11927010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org // Easy case: We need no dynamic check for the dividend and the flooring 11937010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org // division is the same as the truncating division. 11947010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) || 11957010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) { 11967010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ TruncatingDiv(dividend, Abs(divisor)); 11977010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org if (divisor < 0) __ negl(rdx); 11987010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org return; 11997010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org } 12007010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org 12017010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org // In the general case we may need to adjust before and after the truncating 12027010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org // division to get a flooring division. 12037010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Register temp = ToRegister(instr->temp3()); 12047010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org ASSERT(!temp.is(dividend) && !temp.is(rax) && !temp.is(rdx)); 12057010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Label needs_adjustment, done; 12067010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ cmpl(dividend, Immediate(0)); 12077010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ j(divisor > 0 ? less : greater, &needs_adjustment, Label::kNear); 12087010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ TruncatingDiv(dividend, Abs(divisor)); 12097010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org if (divisor < 0) __ negl(rdx); 12107010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ jmp(&done, Label::kNear); 12117010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ bind(&needs_adjustment); 12127010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ leal(temp, Operand(dividend, divisor > 0 ? 1 : -1)); 12137010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ TruncatingDiv(temp, Abs(divisor)); 12147010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org if (divisor < 0) __ negl(rdx); 12157010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ decl(rdx); 12167010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org __ bind(&done); 1217d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org} 1218d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1219d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org 1220ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI. 1221ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.orgvoid LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { 1222ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org HBinaryOperation* hdiv = instr->hydrogen(); 1223ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1224ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Register divisor = ToRegister(instr->divisor()); 1225ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Register remainder = ToRegister(instr->temp()); 1226ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Register result = ToRegister(instr->result()); 1227ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org ASSERT(dividend.is(rax)); 1228ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org ASSERT(remainder.is(rdx)); 1229ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org ASSERT(result.is(rax)); 1230ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org ASSERT(!divisor.is(rax)); 1231ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org ASSERT(!divisor.is(rdx)); 1232ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1233ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org // Check for x / 0. 1234ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1235ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ testl(divisor, divisor); 1236ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org DeoptimizeIf(zero, instr->environment()); 1237ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org } 1238ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1239ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org // Check for (0 / -x) that will produce negative zero. 1240ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1241ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Label dividend_not_zero; 1242ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ testl(dividend, dividend); 1243ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ j(not_zero, ÷nd_not_zero, Label::kNear); 1244ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ testl(divisor, divisor); 1245ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org DeoptimizeIf(sign, instr->environment()); 1246ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ bind(÷nd_not_zero); 1247ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org } 1248ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1249ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org // Check for (kMinInt / -1). 1250ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org if (hdiv->CheckFlag(HValue::kCanOverflow)) { 1251ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Label dividend_not_min_int; 1252ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ cmpl(dividend, Immediate(kMinInt)); 1253ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ j(not_zero, ÷nd_not_min_int, Label::kNear); 1254ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ cmpl(divisor, Immediate(-1)); 1255ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org DeoptimizeIf(zero, instr->environment()); 1256ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ bind(÷nd_not_min_int); 1257ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org } 1258ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1259ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org // Sign extend to rdx (= remainder). 1260ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ cdq(); 1261ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ idivl(divisor); 1262ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1263ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Label done; 1264ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ testl(remainder, remainder); 1265ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ j(zero, &done, Label::kNear); 1266ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ xorl(remainder, divisor); 1267ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ sarl(remainder, Immediate(31)); 1268ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ addl(result, remainder); 1269ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org __ bind(&done); 1270ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org} 1271ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1272ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1273ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { 1274ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1275ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t divisor = instr->divisor(); 1276ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register result = ToRegister(instr->result()); 1277ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor))); 1278ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT(!result.is(dividend)); 1279052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org 1280ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Check for (0 / -x) that will produce negative zero. 1281ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org HDiv* hdiv = instr->hydrogen(); 1282486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1283ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(dividend, dividend); 1284ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org DeoptimizeIf(zero, instr->environment()); 1285ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1286ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Check for (kMinInt / -1). 1287486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { 1288ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ cmpl(dividend, Immediate(kMinInt)); 1289ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org DeoptimizeIf(zero, instr->environment()); 1290ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1291ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Deoptimize if remainder will not be 0. 1292ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && 1293ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org divisor != 1 && divisor != -1) { 1294ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1295ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(dividend, Immediate(mask)); 1296ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org DeoptimizeIf(not_zero, instr->environment()); 12975323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org } 1298ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ Move(result, dividend); 1299ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org int32_t shift = WhichPowerOf2Abs(divisor); 1300ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (shift > 0) { 1301ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // The arithmetic shift is always OK, the 'if' is an optimization only. 1302ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (shift > 1) __ sarl(result, Immediate(31)); 1303ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ shrl(result, Immediate(32 - shift)); 1304ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ addl(result, dividend); 1305ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ sarl(result, Immediate(shift)); 1306ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 1307ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (divisor < 0) __ negl(result); 1308ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org} 13095323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org 1310d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1311bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgvoid LCodeGen::DoDivByConstI(LDivByConstI* instr) { 1312bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1313bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org int32_t divisor = instr->divisor(); 1314bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org ASSERT(ToRegister(instr->result()).is(rdx)); 1315bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1316bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (divisor == 0) { 1317bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org DeoptimizeIf(no_condition, instr->environment()); 1318bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org return; 1319bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 1320bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1321bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // Check for (0 / -x) that will produce negative zero. 1322bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HDiv* hdiv = instr->hydrogen(); 1323486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1324bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ testl(dividend, dividend); 1325bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org DeoptimizeIf(zero, instr->environment()); 1326bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 1327bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1328763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ TruncatingDiv(dividend, Abs(divisor)); 13292ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (divisor < 0) __ negl(rdx); 1330bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1331bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { 1332bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ movl(rax, rdx); 1333bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ imull(rax, rax, Immediate(divisor)); 1334bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ subl(rax, dividend); 1335bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org DeoptimizeIf(not_equal, instr->environment()); 1336bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 1337bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org} 1338bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1339bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1340ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI. 1341ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoDivI(LDivI* instr) { 1342486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org HBinaryOperation* hdiv = instr->hydrogen(); 1343ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1344ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Register divisor = ToRegister(instr->divisor()); 1345ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register remainder = ToRegister(instr->temp()); 1346ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT(dividend.is(rax)); 1347ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT(remainder.is(rdx)); 1348ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org ASSERT(ToRegister(instr->result()).is(rax)); 1349ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT(!divisor.is(rax)); 1350ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT(!divisor.is(rdx)); 1351d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1352d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Check for x / 0. 1353ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1354ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(divisor, divisor); 1355d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com DeoptimizeIf(zero, instr->environment()); 1356d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1357d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1358d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Check for (0 / -x) that will produce negative zero. 1359ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1360ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Label dividend_not_zero; 1361ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(dividend, dividend); 1362ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ j(not_zero, ÷nd_not_zero, Label::kNear); 1363ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(divisor, divisor); 1364d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com DeoptimizeIf(sign, instr->environment()); 1365ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(÷nd_not_zero); 1366d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1367d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 13685323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org // Check for (kMinInt / -1). 1369ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (hdiv->CheckFlag(HValue::kCanOverflow)) { 1370ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Label dividend_not_min_int; 1371ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ cmpl(dividend, Immediate(kMinInt)); 1372ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ j(not_zero, ÷nd_not_min_int, Label::kNear); 1373ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ cmpl(divisor, Immediate(-1)); 1374d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com DeoptimizeIf(zero, instr->environment()); 1375ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ bind(÷nd_not_min_int); 1376d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1377d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1378ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org // Sign extend to rdx (= remainder). 1379d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ cdq(); 1380ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ idivl(divisor); 1381d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1382ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { 1383837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org // Deoptimize if remainder is not 0. 1384ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ testl(remainder, remainder); 1385837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org DeoptimizeIf(not_zero, instr->environment()); 13864cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 1387d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com} 1388c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1389c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1390c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoMulI(LMulI* instr) { 139156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register left = ToRegister(instr->left()); 139256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 1393d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1394d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1395662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 139643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(kScratchRegister, left); 1397662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } else { 1398662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movl(kScratchRegister, left); 1399662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } 1400d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1401d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1402ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org bool can_overflow = 1403ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1404d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (right->IsConstantOperand()) { 1405594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int32_t right_value = ToInteger32(LConstantOperand::cast(right)); 1406ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (right_value == -1) { 1407ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ negl(left); 1408ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else if (right_value == 0) { 1409ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ xorl(left, left); 1410ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else if (right_value == 2) { 1411ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ addl(left, left); 1412ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else if (!can_overflow) { 1413ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // If the multiplication is known to not overflow, we 1414ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // can use operations that don't set the overflow flag 1415ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // correctly. 1416ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org switch (right_value) { 1417ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 1: 1418ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Do nothing. 1419ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1420ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 3: 1421ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ leal(left, Operand(left, left, times_2, 0)); 1422ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1423ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 4: 1424ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ shll(left, Immediate(2)); 1425ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1426ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 5: 1427ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ leal(left, Operand(left, left, times_4, 0)); 1428ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1429ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 8: 1430ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ shll(left, Immediate(3)); 1431ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1432ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 9: 1433ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ leal(left, Operand(left, left, times_8, 0)); 1434ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1435ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org case 16: 1436ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ shll(left, Immediate(4)); 1437ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1438ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org default: 1439ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ imull(left, left, Immediate(right_value)); 1440ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break; 1441ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 1442ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else { 1443ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ imull(left, left, Immediate(right_value)); 1444ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 1445d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else if (right->IsStackSlot()) { 1446fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 1447662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ SmiToInteger64(left, left); 1448fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ imulp(left, ToOperand(right)); 1449fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1450fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ imull(left, ToOperand(right)); 1451fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 1452d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else { 1453fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 1454662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ SmiToInteger64(left, left); 1455fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ imulp(left, ToRegister(right)); 1456fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1457fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ imull(left, ToRegister(right)); 1458fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 1459d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1460d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1461ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (can_overflow) { 1462d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com DeoptimizeIf(overflow, instr->environment()); 1463d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1464d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1465d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1466d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Bail out if the result is supposed to be negative zero. 146783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 1468662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 14697a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(left, left); 1470662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } else { 1471662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ testl(left, left); 1472662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } 147383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_zero, &done, Label::kNear); 1474d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (right->IsConstantOperand()) { 147570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Constant can't be represented as 32-bit Smi due to immediate size 147670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // limit. 147770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ASSERT(SmiValuesAre32Bits() 147870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ? !instr->hydrogen_value()->representation().IsSmi() 147970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org : SmiValuesAre31Bits()); 148033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (ToInteger32(LConstantOperand::cast(right)) < 0) { 1481d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com DeoptimizeIf(no_condition, instr->environment()); 148233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } else if (ToInteger32(LConstantOperand::cast(right)) == 0) { 148333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org __ cmpl(kScratchRegister, Immediate(0)); 148433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org DeoptimizeIf(less, instr->environment()); 1485d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1486d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else if (right->IsStackSlot()) { 1487662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 1488895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ orp(kScratchRegister, ToOperand(right)); 1489662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } else { 1490662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ orl(kScratchRegister, ToOperand(right)); 1491662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } 1492d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com DeoptimizeIf(sign, instr->environment()); 1493d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else { 1494d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Test the non-zero operand for negative sign. 1495662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 1496895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ orp(kScratchRegister, ToRegister(right)); 1497662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } else { 1498662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ orl(kScratchRegister, ToRegister(right)); 1499662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } 1500d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com DeoptimizeIf(sign, instr->environment()); 1501d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1502d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ bind(&done); 1503d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 1504d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com} 1505c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1506c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1507c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoBitI(LBitI* instr) { 150856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 150956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 151083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(left->Equals(instr->result())); 151183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(left->IsRegister()); 151283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 151383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (right->IsConstantOperand()) { 151470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org int32_t right_operand = 151570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ToRepresentation(LConstantOperand::cast(right), 151670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->right()->representation()); 151783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org switch (instr->op()) { 151883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_AND: 151983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ andl(ToRegister(left), Immediate(right_operand)); 152083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 152183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_OR: 152283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ orl(ToRegister(left), Immediate(right_operand)); 152383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 152483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_XOR: 1525594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (right_operand == int32_t(~0)) { 1526639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org __ notl(ToRegister(left)); 1527594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 1528594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ xorl(ToRegister(left), Immediate(right_operand)); 1529594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 153083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 153183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org default: 153283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org UNREACHABLE(); 153383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 153483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 153583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else if (right->IsStackSlot()) { 153683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org switch (instr->op()) { 153783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_AND: 15382ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->IsInteger32()) { 15392ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ andl(ToRegister(left), ToOperand(right)); 15402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 15412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ andp(ToRegister(left), ToOperand(right)); 15422ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 154383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 154483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_OR: 15452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->IsInteger32()) { 15462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ orl(ToRegister(left), ToOperand(right)); 15472ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 15482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ orp(ToRegister(left), ToOperand(right)); 15492ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 155083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 155183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_XOR: 15522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->IsInteger32()) { 15532ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ xorl(ToRegister(left), ToOperand(right)); 15542ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 15552ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ xorp(ToRegister(left), ToOperand(right)); 15562ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 155783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 155883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org default: 155983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org UNREACHABLE(); 156083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 156183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 156283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 156383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(right->IsRegister()); 156483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org switch (instr->op()) { 156583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_AND: 15662ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->IsInteger32()) { 15672ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ andl(ToRegister(left), ToRegister(right)); 15682ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 15692ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ andp(ToRegister(left), ToRegister(right)); 15702ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 157183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 157283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_OR: 15732ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->IsInteger32()) { 15742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ orl(ToRegister(left), ToRegister(right)); 15752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 15762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ orp(ToRegister(left), ToRegister(right)); 15772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 157883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 157983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::BIT_XOR: 15802ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->IsInteger32()) { 15812ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ xorl(ToRegister(left), ToRegister(right)); 15822ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 15832ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ xorp(ToRegister(left), ToRegister(right)); 15842ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 158583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 158683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org default: 158783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org UNREACHABLE(); 158883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 158983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 159083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 159183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org} 1592c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1593c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1594c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoShiftI(LShiftI* instr) { 159556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 159656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 159783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(left->Equals(instr->result())); 159883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(left->IsRegister()); 159983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (right->IsRegister()) { 160083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(ToRegister(right).is(rcx)); 160183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 160283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org switch (instr->op()) { 1603e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case Token::ROR: 1604e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ rorl_cl(ToRegister(left)); 1605e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 160683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::SAR: 160783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ sarl_cl(ToRegister(left)); 160883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 160983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::SHR: 161083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ shrl_cl(ToRegister(left)); 161183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (instr->can_deopt()) { 161283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ testl(ToRegister(left), ToRegister(left)); 161383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org DeoptimizeIf(negative, instr->environment()); 161483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 161583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 161683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::SHL: 161783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ shll_cl(ToRegister(left)); 161883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 161983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org default: 162083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org UNREACHABLE(); 162183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 162283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 162383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 1624594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int32_t value = ToInteger32(LConstantOperand::cast(right)); 162583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); 162683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org switch (instr->op()) { 1627e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case Token::ROR: 1628e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (shift_count != 0) { 1629e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ rorl(ToRegister(left), Immediate(shift_count)); 1630e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 1631e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 163283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::SAR: 163383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (shift_count != 0) { 163483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ sarl(ToRegister(left), Immediate(shift_count)); 163583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 163683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 163783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::SHR: 163854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org if (shift_count != 0) { 163954ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org __ shrl(ToRegister(left), Immediate(shift_count)); 164054ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org } else if (instr->can_deopt()) { 164183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ testl(ToRegister(left), ToRegister(left)); 164283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org DeoptimizeIf(negative, instr->environment()); 164383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 164483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 164583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org case Token::SHL: 164683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (shift_count != 0) { 1647d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 164870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (SmiValuesAre32Bits()) { 164970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ shlp(ToRegister(left), Immediate(shift_count)); 165070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } else { 165170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 165270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (instr->can_deopt()) { 165370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (shift_count != 1) { 165470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ shll(ToRegister(left), Immediate(shift_count - 1)); 165570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 165670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ Integer32ToSmi(ToRegister(left), ToRegister(left)); 165770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org DeoptimizeIf(overflow, instr->environment()); 165870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } else { 165970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ shll(ToRegister(left), Immediate(shift_count)); 166070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 166170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 1662d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 1663d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ shll(ToRegister(left), Immediate(shift_count)); 1664d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 166583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 166683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 166783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org default: 166883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org UNREACHABLE(); 166983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org break; 167083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 167183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 1672c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1673c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1674c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1675c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoSubI(LSubI* instr) { 167656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 167756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 16780ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org ASSERT(left->Equals(instr->result())); 16790ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 16800ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (right->IsConstantOperand()) { 168170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org int32_t right_operand = 168270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ToRepresentation(LConstantOperand::cast(right), 168370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->right()->representation()); 168470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ subl(ToRegister(left), Immediate(right_operand)); 16850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else if (right->IsRegister()) { 1686fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 1687fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(ToRegister(left), ToRegister(right)); 1688fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1689fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ subl(ToRegister(left), ToRegister(right)); 1690fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 16910ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else { 1692fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 1693fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(ToRegister(left), ToOperand(right)); 1694fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1695fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ subl(ToRegister(left), ToOperand(right)); 1696fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 16970ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 16980ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 16990ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 17000ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org DeoptimizeIf(overflow, instr->environment()); 17010ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 1702c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1703c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1704c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1705c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoConstantI(LConstantI* instr) { 17062ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Register dst = ToRegister(instr->result()); 17072ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->value() == 0) { 17082ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ xorl(dst, dst); 17092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else { 17102ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ movl(dst, Immediate(instr->value())); 17112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 1712c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1713c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1714c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1715b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgvoid LCodeGen::DoConstantS(LConstantS* instr) { 1716b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org __ Move(ToRegister(instr->result()), instr->value()); 1717b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org} 1718b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org 1719b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org 1720c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoConstantD(LConstantD* instr) { 17210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ASSERT(instr->result()->IsDoubleRegister()); 17220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com XMMRegister res = ToDoubleRegister(instr->result()); 17230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com double v = instr->value(); 172449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org uint64_t int_val = BitCast<uint64_t, double>(v); 17250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Use xor to produce +0.0 in a fast and compact way, but avoid to 17260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // do so if the constant is -0.0. 172749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (int_val == 0) { 1728160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ xorps(res, res); 17290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } else { 173056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register tmp = ToRegister(instr->temp()); 173149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org __ Set(tmp, int_val); 173249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org __ movq(res, tmp); 17330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1734c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1735c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1736c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1737d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid LCodeGen::DoConstantE(LConstantE* instr) { 1738d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ LoadAddress(ToRegister(instr->result()), instr->value()); 1739d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 1740d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 1741d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 1742c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoConstantT(LConstantT* instr) { 174329699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org Handle<Object> object = instr->value(isolate()); 174429699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org AllowDeferredHandleDereference smi_check; 174529699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org __ Move(ToRegister(instr->result()), object); 1746c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1747c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1748c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1749355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgvoid LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1750355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Register result = ToRegister(instr->result()); 175156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register map = ToRegister(instr->value()); 1752355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ EnumLength(result, map); 1753355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org} 1754355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 1755355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 17564efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.orgvoid LCodeGen::DoDateField(LDateField* instr) { 175756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register object = ToRegister(instr->date()); 17584efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org Register result = ToRegister(instr->result()); 17594efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org Smi* index = instr->index(); 1760de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org Label runtime, done, not_date_object; 17614efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org ASSERT(object.is(result)); 17624efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org ASSERT(object.is(rax)); 17634efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 1764de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org Condition cc = masm()->CheckSmi(object); 1765de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org DeoptimizeIf(cc, instr->environment()); 17664efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ CmpObjectType(object, JS_DATE_TYPE, kScratchRegister); 1767de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org DeoptimizeIf(not_equal, instr->environment()); 17684efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 17694efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org if (index->value() == 0) { 177043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(object, JSDate::kValueOffset)); 17714efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } else { 17724efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org if (index->value() < JSDate::kFirstUncachedField) { 17734efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); 17746e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Operand stamp_operand = __ ExternalOperand(stamp); 177543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(kScratchRegister, stamp_operand); 17767a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(kScratchRegister, FieldOperand(object, 17774efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org JSDate::kCacheStampOffset)); 17784efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ j(not_equal, &runtime, Label::kNear); 177943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(object, JSDate::kValueOffset + 17804efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org kPointerSize * index->value())); 1781935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&done, Label::kNear); 17824efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 17834efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ bind(&runtime); 17844efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ PrepareCallCFunction(2); 178543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(arg_reg_1, object); 1786af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org __ Move(arg_reg_2, index, Assembler::RelocInfoNone()); 17874efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 17884efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ bind(&done); 17894efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 17904efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org} 17914efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 17924efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 1793e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgOperand LCodeGen::BuildSeqStringOperand(Register string, 1794e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org LOperand* index, 1795e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org String::Encoding encoding) { 1796e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (index->IsConstantOperand()) { 1797e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org int offset = ToInteger32(LConstantOperand::cast(index)); 1798e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (encoding == String::TWO_BYTE_ENCODING) { 1799e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org offset *= kUC16Size; 1800e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1801e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org STATIC_ASSERT(kCharSize == 1); 1802e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return FieldOperand(string, SeqString::kHeaderSize + offset); 1803e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1804e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return FieldOperand( 1805e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org string, ToRegister(index), 1806e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org encoding == String::ONE_BYTE_ENCODING ? times_1 : times_2, 1807e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org SeqString::kHeaderSize); 1808e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org} 1809e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1810e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1811e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvoid LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) { 1812e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org String::Encoding encoding = instr->hydrogen()->encoding(); 1813e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register result = ToRegister(instr->result()); 1814a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register string = ToRegister(instr->string()); 1815a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 1816a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (FLAG_debug_code) { 1817763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(string); 181843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(string, FieldOperand(string, HeapObject::kMapOffset)); 1819895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ movzxbp(string, FieldOperand(string, Map::kInstanceTypeOffset)); 1820a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 1821e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ andb(string, Immediate(kStringRepresentationMask | kStringEncodingMask)); 1822a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 1823a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 18247a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(string, Immediate(encoding == String::ONE_BYTE_ENCODING 1825e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ? one_byte_seq_type : two_byte_seq_type)); 1826594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Check(equal, kUnexpectedStringType); 1827763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(string); 1828a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 1829a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 1830e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Operand operand = BuildSeqStringOperand(string, instr->index(), encoding); 1831a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (encoding == String::ONE_BYTE_ENCODING) { 1832e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movzxbl(result, operand); 1833e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 1834e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movzxwl(result, operand); 1835e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1836e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org} 1837e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1838e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1839e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvoid LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { 1840e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org String::Encoding encoding = instr->hydrogen()->encoding(); 1841e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register string = ToRegister(instr->string()); 1842e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1843e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (FLAG_debug_code) { 18449af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register value = ToRegister(instr->value()); 18459af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register index = ToRegister(instr->index()); 1846e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 1847e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 18489af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org int encoding_mask = 18499af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING 18509af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org ? one_byte_seq_type : two_byte_seq_type; 18519af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org __ EmitSeqStringSetCharCheck(string, index, value, encoding_mask); 1852e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1853e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1854e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Operand operand = BuildSeqStringOperand(string, instr->index(), encoding); 1855e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (instr->value()->IsConstantOperand()) { 1856e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org int value = ToInteger32(LConstantOperand::cast(instr->value())); 1857e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT_LE(0, value); 1858e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (encoding == String::ONE_BYTE_ENCODING) { 1859e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT_LE(value, String::kMaxOneByteCharCode); 1860e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movb(operand, Immediate(value)); 1861e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 1862e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT_LE(value, String::kMaxUtf16CodeUnit); 1863e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movw(operand, Immediate(value)); 1864e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1865a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } else { 1866e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register value = ToRegister(instr->value()); 1867e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (encoding == String::ONE_BYTE_ENCODING) { 1868e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movb(operand, value); 1869e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 1870e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movw(operand, value); 1871e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1872a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 187332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org} 187432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 187532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 1876c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoAddI(LAddI* instr) { 187756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 187856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 18790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 188037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org Representation target_rep = instr->hydrogen()->representation(); 1881fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org bool is_p = target_rep.IsSmi() || target_rep.IsExternal(); 188237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 1883906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { 1884906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (right->IsConstantOperand()) { 188570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // No support for smi-immediates for 32-bit SMI. 188670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ASSERT(SmiValuesAre32Bits() ? !target_rep.IsSmi() : SmiValuesAre31Bits()); 188770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org int32_t offset = 188870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ToRepresentation(LConstantOperand::cast(right), 188970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->right()->representation()); 1890fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (is_p) { 1891895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(ToRegister(instr->result()), 1892895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org MemOperand(ToRegister(left), offset)); 189337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } else { 189437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org __ leal(ToRegister(instr->result()), 189537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org MemOperand(ToRegister(left), offset)); 189637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } 1897906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else { 1898906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org Operand address(ToRegister(left), ToRegister(right), times_1, 0); 1899fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (is_p) { 1900895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(ToRegister(instr->result()), address); 1901fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1902fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ leal(ToRegister(instr->result()), address); 1903fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 1904906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 19050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } else { 1906906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (right->IsConstantOperand()) { 190770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // No support for smi-immediates for 32-bit SMI. 190870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ASSERT(SmiValuesAre32Bits() ? !target_rep.IsSmi() : SmiValuesAre31Bits()); 190970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org int32_t right_operand = 191070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ToRepresentation(LConstantOperand::cast(right), 191170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->right()->representation()); 1912fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (is_p) { 191370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ addp(ToRegister(left), Immediate(right_operand)); 191437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } else { 191570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ addl(ToRegister(left), Immediate(right_operand)); 191637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } 1917906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else if (right->IsRegister()) { 1918fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (is_p) { 1919fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(ToRegister(left), ToRegister(right)); 1920fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1921fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ addl(ToRegister(left), ToRegister(right)); 1922fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 1923906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else { 1924fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (is_p) { 1925fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(ToRegister(left), ToOperand(right)); 1926fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } else { 1927fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ addl(ToRegister(left), ToOperand(right)); 1928fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 1929906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 1930906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1931906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org DeoptimizeIf(overflow, instr->environment()); 1932906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 19330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1934c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 1935c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1936c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 1937471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid LCodeGen::DoMathMinMax(LMathMinMax* instr) { 193856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* left = instr->left(); 193956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* right = instr->right(); 1940471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ASSERT(left->Equals(instr->result())); 1941471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1942d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen()->representation().IsSmiOrInteger32()) { 1943471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Label return_left; 1944471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Condition condition = (operation == HMathMinMax::kMathMin) 1945471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ? less_equal 1946471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org : greater_equal; 1947471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Register left_reg = ToRegister(left); 1948471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (right->IsConstantOperand()) { 194970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Immediate right_imm = Immediate( 195070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ToRepresentation(LConstantOperand::cast(right), 195170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->right()->representation())); 195270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ASSERT(SmiValuesAre32Bits() 195370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ? !instr->hydrogen()->representation().IsSmi() 195470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org : SmiValuesAre31Bits()); 19554121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org __ cmpl(left_reg, right_imm); 1956471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(condition, &return_left, Label::kNear); 195743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(left_reg, right_imm); 195867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org } else if (right->IsRegister()) { 195967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Register right_reg = ToRegister(right); 1960d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 19617a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(left_reg, right_reg); 1962d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 1963d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ cmpl(left_reg, right_reg); 1964d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 196567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org __ j(condition, &return_left, Label::kNear); 196643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(left_reg, right_reg); 1967471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 1968471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Operand right_op = ToOperand(right); 1969d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen_value()->representation().IsSmi()) { 19707a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(left_reg, right_op); 1971d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 1972d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ cmpl(left_reg, right_op); 1973d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 1974471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(condition, &return_left, Label::kNear); 197543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(left_reg, right_op); 1976471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 1977471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&return_left); 1978471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 1979471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ASSERT(instr->hydrogen()->representation().IsDouble()); 1980471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Label check_nan_left, check_zero, return_left, return_right; 1981471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; 1982471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org XMMRegister left_reg = ToDoubleRegister(left); 1983471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org XMMRegister right_reg = ToDoubleRegister(right); 1984471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ ucomisd(left_reg, right_reg); 1985471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN. 1986471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(equal, &check_zero, Label::kNear); // left == right. 1987471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(condition, &return_left, Label::kNear); 1988471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ jmp(&return_right, Label::kNear); 1989471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 1990471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&check_zero); 1991528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 1992471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ xorps(xmm_scratch, xmm_scratch); 1993471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ ucomisd(left_reg, xmm_scratch); 1994471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(not_equal, &return_left, Label::kNear); // left == right != 0. 1995471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // At this point, both left and right are either 0 or -0. 1996471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (operation == HMathMinMax::kMathMin) { 1997057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ orps(left_reg, right_reg); 1998471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 1999471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // Since we operate on +0 and/or -0, addsd and andsd have the same effect. 2000471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ addsd(left_reg, right_reg); 2001471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 2002471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ jmp(&return_left, Label::kNear); 2003471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 2004471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&check_nan_left); 2005471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ ucomisd(left_reg, left_reg); // NaN check. 2006471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ j(parity_even, &return_left, Label::kNear); 2007471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&return_right); 2008057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ movaps(left_reg, right_reg); 2009471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 2010471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org __ bind(&return_left); 2011471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 2012471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org} 2013471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 2014471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 2015c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoArithmeticD(LArithmeticD* instr) { 201656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister left = ToDoubleRegister(instr->left()); 201756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister right = ToDoubleRegister(instr->right()); 20188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org XMMRegister result = ToDoubleRegister(instr->result()); 201949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // All operations except MOD are computed in-place. 20208f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org ASSERT(instr->op() == Token::MOD || left.is(result)); 202149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org switch (instr->op()) { 202249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org case Token::ADD: 20238f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ addsd(left, right); 202449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org break; 202549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org case Token::SUB: 20268f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ subsd(left, right); 202749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org break; 202849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org case Token::MUL: 20298f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ mulsd(left, right); 203049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org break; 203149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org case Token::DIV: 20328f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ divsd(left, right); 2033e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Don't delete this mov. It may improve performance on some CPUs, 2034e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // when there is a mulsd depending on the result 20354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org __ movaps(left, left); 203649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org break; 2037528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org case Token::MOD: { 2038528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 20398f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ PrepareCallCFunction(2); 2040528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ movaps(xmm_scratch, left); 20418f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org ASSERT(right.is(xmm1)); 2042ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ CallCFunction( 20434f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org ExternalReference::mod_two_doubles_operation(isolate()), 2); 2044528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ movaps(result, xmm_scratch); 204549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org break; 2046528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 204749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org default: 204849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org UNREACHABLE(); 204949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org break; 205049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 2051c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2052c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2053c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2054c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoArithmeticT(LArithmeticT* instr) { 2055935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 205656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(ToRegister(instr->left()).is(rdx)); 205756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(ToRegister(instr->right()).is(rax)); 20580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ASSERT(ToRegister(instr->result()).is(rax)); 20590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 2060f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); 2061f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), 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()) { 2102b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(!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()) { 2107b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(!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()) { 2112b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(!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 { 21190a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org ASSERT(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()) { 2123b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(!info()->IsStub()); 2124b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ CompareRoot(reg, Heap::kTrueValueRootIndex); 21251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 21260a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else if (type.IsSmi()) { 2127b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(!info()->IsStub()); 21280a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ SmiCompare(reg, Smi::FromInt(0)); 21291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, not_equal); 21301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (type.IsJSArray()) { 21311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(!info()->IsStub()); 21321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, no_condition); 21331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (type.IsHeapNumber()) { 21341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(!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()) { 21401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(!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)); 2175d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org DeoptimizeIf(zero, instr->environment()); 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. 22291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org DeoptimizeIf(no_condition, instr->environment()); 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(); 23830cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org ASSERT(!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) { 24110ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org ASSERT(!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) { 2500935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 25010ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry Token::Value op = instr->op(); 25020ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 25038432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 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; 25170a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org ASSERT(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)); 25528f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org ASSERT(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) { 2575f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ASSERT(!input.is(temp)); 2576f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ASSERT(!input.is(temp2)); 2577f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ASSERT(!temp.is(temp2)); 2578f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 25790a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ JumpIfSmi(input, is_false); 25800a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 258159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Function"))) { 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); 261259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Object"))) { 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. 26294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(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) { 2657935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(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) { 267432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org class DeferredInstanceOfKnownGlobal V8_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) { } 267932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual void Generate() V8_OVERRIDE { 268027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_); 26813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 268232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual LInstruction* instr() V8_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 2689935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(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); 27174d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org ASSERT(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 2749a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org static const int kAdditionalDelta = 10; 275044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org int delta = 275144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 2752a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org ASSERT(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); 276444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ASSERT(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) { 2784935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 27850a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Token::Value op = instr->op(); 27860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 27878432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 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); 2845d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com DeoptimizeIf(equal, instr->environment()); 2846d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 2847c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2848c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2849c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2850c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgvoid LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { 2851935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 2852c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ASSERT(ToRegister(instr->global_object()).is(rax)); 2853c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ASSERT(ToRegister(instr->result()).is(rax)); 2854c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 2855c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ Move(rcx, instr->name()); 28569cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; 28579cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode); 28589cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 2859c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org} 2860c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 2861c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 286274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { 2863e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org Register value = ToRegister(instr->value()); 2864528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Handle<Cell> cell_handle = instr->hydrogen()->cell().handle(); 2865c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 286683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // If the cell we are storing to contains the hole it could have 286783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // been deleted from the property dictionary. In that case, we need 286883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // to update the property details in the property dictionary to mark 286983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // it as no longer deleted. We deoptimize in that case. 2870c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (instr->hydrogen()->RequiresHoleCheck()) { 2871e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org // We have a temp because CompareRoot might clobber kScratchRegister. 287256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register cell = ToRegister(instr->temp()); 2873e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org ASSERT(!value.is(cell)); 28749cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org __ Move(cell, cell_handle, RelocInfo::CELL); 2875e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org __ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex); 287683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org DeoptimizeIf(equal, instr->environment()); 2877e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org // Store the value. 287843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(cell, 0), value); 2879e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org } else { 2880e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org // Store the value. 28819cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org __ Move(kScratchRegister, cell_handle, RelocInfo::CELL); 288243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(kScratchRegister, 0), value); 288383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 288464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Cells are always rescanned, so no write barrier here. 2885c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2886c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2887c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2888c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 28893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register context = ToRegister(instr->context()); 28903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register result = ToRegister(instr->result()); 289143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, ContextOperand(context, instr->slot_index())); 289264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 289364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 28947ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org if (instr->hydrogen()->DeoptimizesOnHole()) { 28957ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org DeoptimizeIf(equal, instr->environment()); 28967ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } else { 28977ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org Label is_not_hole; 28987ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ j(not_equal, &is_not_hole, Label::kNear); 28997ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ LoadRoot(result, Heap::kUndefinedValueRootIndex); 29007ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ bind(&is_not_hole); 29017ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } 290264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 29033a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 29043a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 29053a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 29063a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { 29073a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register context = ToRegister(instr->context()); 29083a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register value = ToRegister(instr->value()); 29097ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 291064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Operand target = ContextOperand(context, instr->slot_index()); 29117ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 29127ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org Label skip_assignment; 291364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 291464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CompareRoot(target, Heap::kTheHoleValueRootIndex); 29157ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org if (instr->hydrogen()->DeoptimizesOnHole()) { 29167ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org DeoptimizeIf(equal, instr->environment()); 29177ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } else { 29187ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ j(not_equal, &skip_assignment); 29197ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } 292064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 292143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(target, value); 29227ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 2923394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (instr->hydrogen()->NeedsWriteBarrier()) { 2924394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com SmiCheck check_needed = 2925eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org instr->hydrogen()->value()->type().IsHeapObject() 29261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 29273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int offset = Context::SlotOffset(instr->slot_index()); 292856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register scratch = ToRegister(instr->temp()); 2929394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteContextSlot(context, 2930394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com offset, 2931394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com value, 2932394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scratch, 2933394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kSaveFPRegs, 2934394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 2935394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com check_needed); 29363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 29377ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 29387ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org __ bind(&skip_assignment); 2939c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2940c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2941c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2942c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 294353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org HObjectAccess access = instr->hydrogen()->access(); 294453ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org int offset = access.offset(); 2945d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 2946d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (access.IsExternalMemory()) { 2947d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register result = ToRegister(instr->result()); 2948d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->object()->IsConstantOperand()) { 2949d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(result.is(rax)); 2950d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object()))); 2951d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 2952d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register object = ToRegister(instr->object()); 2953d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org __ Load(result, MemOperand(object, offset), access.representation()); 2954d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 2955d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return; 2956d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 2957d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 295856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register object = ToRegister(instr->object()); 295909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org if (instr->hydrogen()->representation().IsDouble()) { 296057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org XMMRegister result = ToDoubleRegister(instr->result()); 296157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movsd(result, FieldOperand(object, offset)); 296257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org return; 2963f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 296457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 296557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Register result = ToRegister(instr->result()); 2966d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (!access.IsInobject()) { 296743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(object, JSObject::kPropertiesOffset)); 2968d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org object = result; 2969378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 2970113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org 2971113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org Representation representation = access.representation(); 297204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (representation.IsSmi() && SmiValuesAre32Bits() && 2973113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org instr->hydrogen()->representation().IsInteger32()) { 29742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (FLAG_debug_code) { 29752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Register scratch = kScratchRegister; 29762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ Load(scratch, FieldOperand(object, offset), representation); 29772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ AssertSmi(scratch); 29782ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 2979f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 2980113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org // Read int value directly from upper half of the smi. 2981113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org STATIC_ASSERT(kSmiTag == 0); 298204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(kSmiTagSize + kSmiShiftSize == 32); 2983113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org offset += kPointerSize / 2; 2984113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org representation = Representation::Integer32(); 2985113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org } 2986113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org __ Load(result, FieldOperand(object, offset), representation); 2987c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2988c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2989c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 2990c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 2991935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 2992d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ASSERT(ToRegister(instr->object()).is(rax)); 2993d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ASSERT(ToRegister(instr->result()).is(rax)); 2994d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 2995d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ Move(rcx, instr->name()); 29969cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL); 2997d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com CallCode(ic, RelocInfo::CODE_TARGET, instr); 2998c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 2999c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3000c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3001c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 3002496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org Register function = ToRegister(instr->function()); 3003496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org Register result = ToRegister(instr->result()); 3004496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3005496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Check that the function really is a function. 3006496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ CmpObjectType(function, JS_FUNCTION_TYPE, result); 3007496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org DeoptimizeIf(not_equal, instr->environment()); 3008496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3009496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Check whether the function has an instance prototype. 301083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label non_instance; 3011496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ testb(FieldOperand(result, Map::kBitFieldOffset), 3012496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org Immediate(1 << Map::kHasNonInstancePrototype)); 301383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_zero, &non_instance, Label::kNear); 3014496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3015496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Get the prototype or initial map from the function. 301643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, 3017496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 3018496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3019496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Check that the function has a prototype or an initial map. 3020496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 3021496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org DeoptimizeIf(equal, instr->environment()); 3022496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3023496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // If the function does not have an initial map, we're done. 302483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 3025496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ CmpObjectType(result, MAP_TYPE, kScratchRegister); 302683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_equal, &done, Label::kNear); 3027496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3028496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Get the prototype from the initial map. 302943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(result, Map::kPrototypeOffset)); 303083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 3031496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3032496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // Non-instance prototype: Fetch prototype from constructor field 3033496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // in the function's map. 3034496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ bind(&non_instance); 303543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(result, Map::kConstructorOffset)); 3036496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3037496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org // All done. 3038496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ bind(&done); 3039c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3040c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3041c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3042528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid LCodeGen::DoLoadRoot(LLoadRoot* instr) { 3043528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register result = ToRegister(instr->result()); 3044528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ LoadRoot(result, instr->index()); 3045528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 3046528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 3047528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 3048c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 304949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org Register arguments = ToRegister(instr->arguments()); 305049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org Register result = ToRegister(instr->result()); 305177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 305277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (instr->length()->IsConstantOperand() && 305377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org instr->index()->IsConstantOperand()) { 3054594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index())); 3055594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int32_t const_length = ToInteger32(LConstantOperand::cast(instr->length())); 30569b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org if (const_index >= 0 && const_index < const_length) { 30579b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org StackArgumentsAccessor args(arguments, const_length, 30589b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org ARGUMENTS_DONT_CONTAIN_RECEIVER); 30599b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org __ movp(result, args.GetArgumentOperand(const_index)); 30609b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org } else if (FLAG_debug_code) { 30619b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org __ int3(); 30629b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org } 306349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } else { 306477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Register length = ToRegister(instr->length()); 306577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // There are two words between the frame pointer and the last argument. 306677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // Subtracting from length accounts for one of them add one more. 306777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (instr->index()->IsRegister()) { 306877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ subl(length, ToRegister(instr->index())); 306977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 307077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ subl(length, ToOperand(instr->index())); 307177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 3072d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StackArgumentsAccessor args(arguments, length, 3073d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ARGUMENTS_DONT_CONTAIN_RECEIVER); 307443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, args.GetArgumentOperand(0)); 307549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 3076c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3077c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3078c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3079eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.orgvoid LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 3080eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org ElementsKind elements_kind = instr->elements_kind(); 3081eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org LOperand* key = instr->key(); 308270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (kPointerSize == kInt32Size && !key->IsConstantOperand()) { 308370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Register key_reg = ToRegister(key); 308470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Representation key_representation = 308570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(); 308670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (ExternalArrayOpRequiresTemp(key_representation, elements_kind)) { 308770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ SmiToInteger64(key_reg, key_reg); 308870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } else if (instr->hydrogen()->IsDehoisted()) { 308970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Sign extend key because it could be a 32 bit negative value 309070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // and the dehoisted address computation happens in 64 bits 309170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ movsxlq(key_reg, key_reg); 309270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 309370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 3094e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Operand operand(BuildFastArrayOperand( 3095e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->elements(), 3096e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org key, 309770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 3098e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org elements_kind, 3099fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org instr->base_offset())); 31000e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org 3101af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || 31025c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org elements_kind == FLOAT32_ELEMENTS) { 3103e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org XMMRegister result(ToDoubleRegister(instr->result())); 3104e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movss(result, operand); 3105e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ cvtss2sd(result, result); 3106af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || 31075c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org elements_kind == FLOAT64_ELEMENTS) { 3108e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movsd(ToDoubleRegister(instr->result()), operand); 3109e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 3110e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Register result(ToRegister(instr->result())); 3111e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org switch (elements_kind) { 3112af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_INT8_ELEMENTS: 31135c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case INT8_ELEMENTS: 31142ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ movsxbl(result, operand); 3115e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3116af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT8_ELEMENTS: 3117af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT8_CLAMPED_ELEMENTS: 31185c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT8_ELEMENTS: 31195c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT8_CLAMPED_ELEMENTS: 31202ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ movzxbl(result, operand); 3121e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3122af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_INT16_ELEMENTS: 31235c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case INT16_ELEMENTS: 31242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ movsxwl(result, operand); 3125e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3126af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT16_ELEMENTS: 31275c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT16_ELEMENTS: 31282ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ movzxwl(result, operand); 3129e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3130af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_INT32_ELEMENTS: 31315c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case INT32_ELEMENTS: 31322ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ movl(result, operand); 3133e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3134af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT32_ELEMENTS: 31355c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT32_ELEMENTS: 3136e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movl(result, operand); 3137e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 3138e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ testl(result, result); 3139e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DeoptimizeIf(negative, instr->environment()); 3140e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 3141e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 3142af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_FLOAT32_ELEMENTS: 3143af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_FLOAT64_ELEMENTS: 31445c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case FLOAT32_ELEMENTS: 31455c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case FLOAT64_ELEMENTS: 3146e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_ELEMENTS: 3147e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_SMI_ELEMENTS: 3148e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_DOUBLE_ELEMENTS: 3149e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_ELEMENTS: 3150e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_SMI_ELEMENTS: 3151e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_DOUBLE_ELEMENTS: 3152e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case DICTIONARY_ELEMENTS: 3153486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org case SLOPPY_ARGUMENTS_ELEMENTS: 3154e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org UNREACHABLE(); 3155e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 31567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 315783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 315883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 315983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 316083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 3161e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { 3162717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org XMMRegister result(ToDoubleRegister(instr->result())); 3163304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org LOperand* key = instr->key(); 316470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (kPointerSize == kInt32Size && !key->IsConstantOperand() && 316570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->IsDehoisted()) { 316670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Sign extend key because it could be a 32 bit negative value 316770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // and the dehoisted address computation happens in 64 bits 316870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ movsxlq(ToRegister(key), ToRegister(key)); 316970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 3170830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 3171830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Operand hole_check_operand = BuildFastArrayOperand( 3172830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org instr->elements(), 3173304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org key, 317470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 3175830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FAST_DOUBLE_ELEMENTS, 3176fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org instr->base_offset() + sizeof(kHoleNanLower32)); 3177830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); 3178830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org DeoptimizeIf(equal, instr->environment()); 3179830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 3180717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 3181717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org Operand double_load_operand = BuildFastArrayOperand( 31820e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org instr->elements(), 3183304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org key, 318470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 31850e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org FAST_DOUBLE_ELEMENTS, 3186fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org instr->base_offset()); 3187717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org __ movsd(result, double_load_operand); 3188717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org} 3189717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 3190717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 3191e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 319271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org HLoadKeyed* hinstr = instr->hydrogen(); 3193e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Register result = ToRegister(instr->result()); 3194e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org LOperand* key = instr->key(); 319571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org bool requires_hole_check = hinstr->RequiresHoleCheck(); 319671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org Representation representation = hinstr->representation(); 3197fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org int offset = instr->base_offset(); 319871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 319970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (kPointerSize == kInt32Size && !key->IsConstantOperand() && 320070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->IsDehoisted()) { 320170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Sign extend key because it could be a 32 bit negative value 320270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // and the dehoisted address computation happens in 64 bits 320370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ movsxlq(ToRegister(key), ToRegister(key)); 320470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 320504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (representation.IsInteger32() && SmiValuesAre32Bits() && 320671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org hinstr->elements_kind() == FAST_SMI_ELEMENTS) { 320771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org ASSERT(!requires_hole_check); 32082ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (FLAG_debug_code) { 32092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Register scratch = kScratchRegister; 32102ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ Load(scratch, 32112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org BuildFastArrayOperand(instr->elements(), 32122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org key, 321370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 32142ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org FAST_ELEMENTS, 3215fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org offset), 32162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Representation::Smi()); 32172ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ AssertSmi(scratch); 32182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 321971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org // Read int value directly from upper half of the smi. 322071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org STATIC_ASSERT(kSmiTag == 0); 322104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(kSmiTagSize + kSmiShiftSize == 32); 322271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org offset += kPointerSize / 2; 322371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } 322471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 322571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ Load(result, 3226e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org BuildFastArrayOperand(instr->elements(), 3227e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org key, 322870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 3229e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org FAST_ELEMENTS, 3230fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org offset), 323171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org representation); 3232e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3233e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org // Check for the hole value. 323471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (requires_hole_check) { 323571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (IsFastSmiElementsKind(hinstr->elements_kind())) { 3236e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Condition smi = __ CheckSmi(result); 3237e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DeoptimizeIf(NegateCondition(smi), instr->environment()); 3238e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 3239e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 3240e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DeoptimizeIf(equal, instr->environment()); 3241e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 3242e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 3243e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 3244e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3245e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3246e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { 32475c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org if (instr->is_typed_elements()) { 3248e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoLoadKeyedExternalArray(instr); 3249e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else if (instr->hydrogen()->representation().IsDouble()) { 3250e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoLoadKeyedFixedDoubleArray(instr); 3251e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 3252e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoLoadKeyedFixedArray(instr); 3253e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 3254e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 3255e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3256e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 3257717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.orgOperand LCodeGen::BuildFastArrayOperand( 3258b645116853c677aca8a316381b87441ba6004f67danno@chromium.org LOperand* elements_pointer, 32596d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org LOperand* key, 326070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Representation key_representation, 326183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ElementsKind elements_kind, 3262fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org uint32_t offset) { 3263b645116853c677aca8a316381b87441ba6004f67danno@chromium.org Register elements_pointer_reg = ToRegister(elements_pointer); 32646d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org int shift_size = ElementsKindToShiftSize(elements_kind); 326583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (key->IsConstantOperand()) { 3266594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int32_t constant_value = ToInteger32(LConstantOperand::cast(key)); 326783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (constant_value & 0xF0000000) { 3268594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kArrayIndexConstantValueTooBig); 326983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 3270b645116853c677aca8a316381b87441ba6004f67danno@chromium.org return Operand(elements_pointer_reg, 3271fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org (constant_value << shift_size) + offset); 327283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 327370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Take the tag bit into account while computing the shift size. 327470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (key_representation.IsSmi() && (shift_size >= 1)) { 327570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 327670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org shift_size -= kSmiTagSize; 327770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 327883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); 32790e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org return Operand(elements_pointer_reg, 32800e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org ToRegister(key), 32810e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org scale_factor, 3282fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org offset); 328383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 3284c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3285c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3286c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3287c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 3288935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 32893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(ToRegister(instr->object()).is(rdx)); 32903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(ToRegister(instr->key()).is(rax)); 32913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 32927979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 32933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 3294c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3295c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3296c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3297c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 329849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org Register result = ToRegister(instr->result()); 329949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 330028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (instr->hydrogen()->from_inlined()) { 3301895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(result, Operand(rsp, -kFPOnStackSize + -kPCOnStackSize)); 330228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } else { 330328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Check for arguments adapter frame. 330428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label done, adapted; 330543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 330628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ Cmp(Operand(result, StandardFrameConstants::kContextOffset), 330728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 330828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ j(equal, &adapted, Label::kNear); 330928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 331028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // No arguments adaptor frame. 331143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, rbp); 331228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ jmp(&done, Label::kNear); 331349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 331428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Arguments adaptor frame present. 331528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ bind(&adapted); 331643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 3317b2a1c078e6f552a66c1426482a3d007b7ea7af7ddanno@chromium.org 331828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Result is the frame pointer for the frame if not adapted and for the real 331928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // frame below the adaptor frame if adapted. 332028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ bind(&done); 332128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 3322c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3323c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3324c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3325c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 332649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org Register result = ToRegister(instr->result()); 332749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 332883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 332949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 333049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // If no arguments adaptor frame the number of arguments is fixed. 333156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org if (instr->elements()->IsRegister()) { 33327a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rbp, ToRegister(instr->elements())); 333349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } else { 33347a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rbp, ToOperand(instr->elements())); 333549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 3336a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org __ movl(result, Immediate(scope()->num_parameters())); 333783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &done, Label::kNear); 333849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 333949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Arguments adaptor frame present. Get argument length from there. 334043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 3341a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org __ SmiToInteger32(result, 3342a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org Operand(result, 3343a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org ArgumentsAdaptorFrameConstants::kLengthOffset)); 334449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 334549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Argument length is in result register. 334649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org __ bind(&done); 3347c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3348c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3349c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3350154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgvoid LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 33513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register receiver = ToRegister(instr->receiver()); 33523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register function = ToRegister(instr->function()); 33533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 3354d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // If the receiver is null or undefined, we have to pass the global 3355d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // object as a receiver to normal functions. Values have to be 3356d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // passed unchanged to builtins and strict-mode functions. 335783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label global_object, receiver_ok; 3358935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 3359d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 336057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (!instr->hydrogen()->known_function()) { 336157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // Do not transform the receiver to object for strict mode 336257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // functions. 336357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ movp(kScratchRegister, 336457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 336557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ testb(FieldOperand(kScratchRegister, 336657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org SharedFunctionInfo::kStrictModeByteOffset), 336757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte)); 336857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ j(not_equal, &receiver_ok, dist); 336957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 337057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // Do not transform the receiver to object for builtins. 337157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ testb(FieldOperand(kScratchRegister, 337257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org SharedFunctionInfo::kNativeByteOffset), 337357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte)); 337457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ j(not_equal, &receiver_ok, dist); 337557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 3376d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 3377d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // Normal function. Replace undefined or null with global receiver. 33783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ CompareRoot(receiver, Heap::kNullValueRootIndex); 337983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &global_object, Label::kNear); 33803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ CompareRoot(receiver, Heap::kUndefinedValueRootIndex); 338183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &global_object, Label::kNear); 33823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 33833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // The receiver should be a JS object. 33843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Condition is_smi = __ CheckSmi(receiver); 33853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org DeoptimizeIf(is_smi, instr->environment()); 3386d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, kScratchRegister); 33873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org DeoptimizeIf(below, instr->environment()); 33883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 338957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ jmp(&receiver_ok, Label::kNear); 33903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&global_object); 339143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(receiver, FieldOperand(function, JSFunction::kContextOffset)); 339243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(receiver, 339357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Operand(receiver, 339457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 339543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(receiver, 3396e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org FieldOperand(receiver, GlobalObject::kGlobalReceiverOffset)); 339757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 33983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&receiver_ok); 3399154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org} 3400154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 3401154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 3402154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgvoid LCodeGen::DoApplyArguments(LApplyArguments* instr) { 3403154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Register receiver = ToRegister(instr->receiver()); 3404154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Register function = ToRegister(instr->function()); 3405154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Register length = ToRegister(instr->length()); 3406154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org Register elements = ToRegister(instr->elements()); 3407154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ASSERT(receiver.is(rax)); // Used for parameter count. 3408154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ASSERT(function.is(rdi)); // Required by InvokeFunction. 3409154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ASSERT(ToRegister(instr->result()).is(rax)); 34103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 34113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Copy the arguments to this function possibly from the 34123a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // adaptor frame below it. 34133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org const uint32_t kArgumentsLimit = 1 * KB; 34147a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(length, Immediate(kArgumentsLimit)); 34153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org DeoptimizeIf(above, instr->environment()); 34163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 3417763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(receiver); 341843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(receiver, length); 34193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 34203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Loop through the arguments pushing them onto the execution 34213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // stack. 342283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label invoke, loop; 34233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // length is a small non-negative integer, due to the test above. 34243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ testl(length, length); 342583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(zero, &invoke, Label::kNear); 34263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&loop); 3427d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StackArgumentsAccessor args(elements, length, 3428d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ARGUMENTS_DONT_CONTAIN_RECEIVER); 3429763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(args.GetArgumentOperand(0)); 34303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ decl(length); 34313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ j(not_zero, &loop); 34323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 34333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Invoke the function. 34343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&invoke); 34351044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org ASSERT(instr->HasPointerMap()); 34363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LPointerMap* pointers = instr->pointer_map(); 343727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org SafepointGenerator safepoint_generator( 343827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org this, pointers, Safepoint::kLazyDeopt); 34392efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ParameterCount actual(rax); 3440e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator); 3441c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3442c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3443c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3444c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoPushArgument(LPushArgument* instr) { 344556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* argument = instr->value(); 3446160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org EmitPushTaggedOperand(argument); 3447c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3448c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3449c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 345028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.orgvoid LCodeGen::DoDrop(LDrop* instr) { 345128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ Drop(instr->count()); 345228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org} 345328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 345428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 3455d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.orgvoid LCodeGen::DoThisFunction(LThisFunction* instr) { 3456d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org Register result = ToRegister(instr->result()); 345743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 3458d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org} 3459d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 3460d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 3461496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgvoid LCodeGen::DoContext(LContext* instr) { 3462496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org Register result = ToRegister(instr->result()); 3463935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (info()->IsOptimizing()) { 346443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, Operand(rbp, StandardFrameConstants::kContextOffset)); 3465935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else { 3466935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // If there is no frame, the context must be in rsi. 3467935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(result.is(rsi)); 3468935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } 3469496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org} 3470496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 3471496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 347256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.orgvoid LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 3473935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 3474763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); // The context is the first argument. 3475c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Push(instr->hydrogen()->pairs()); 347656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ Push(Smi::FromInt(instr->hydrogen()->flags())); 3477895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org CallRuntime(Runtime::kHiddenDeclareGlobals, 3, instr); 347856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org} 347956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org 348056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org 3481c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::CallKnownFunction(Handle<JSFunction> function, 348232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org int formal_parameter_count, 3483c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int arity, 348440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org LInstruction* instr, 3485fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org RDIState rdi_state) { 348632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org bool dont_adapt_arguments = 348732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 348832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org bool can_invoke_directly = 348932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org dont_adapt_arguments || formal_parameter_count == arity; 349083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 349183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org LPointerMap* pointers = instr->pointer_map(); 349283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 34932efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (can_invoke_directly) { 3494fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org if (rdi_state == RDI_UNINITIALIZED) { 3495c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Move(rdi, function); 3496fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org } 34972efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 3498b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org // Change context. 349943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 35002efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 35012efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Set rax to arguments count if adaption is not needed. Assumes that rax 35022efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // is available to write to at this point. 350332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (dont_adapt_arguments) { 35042efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ Set(rax, arity); 35052efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 35062efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 35072efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Invoke function. 350832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (function.is_identical_to(info()->closure())) { 35092efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org __ CallSelf(); 35102efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 3511f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ Call(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 35122efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 35132efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 35142efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Set up deoptimization. 35152efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); 351683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 35172efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // We need to adapt arguments. 35182efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org SafepointGenerator generator( 35192efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org this, pointers, Safepoint::kLazyDeopt); 35202efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ParameterCount count(arity); 352132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ParameterCount expected(formal_parameter_count); 3522e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ InvokeFunction(function, expected, count, CALL_FUNCTION, generator); 352383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 3524c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3525c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3526c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 352726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgvoid LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { 352883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(ToRegister(instr->result()).is(rax)); 352926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 353026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org LPointerMap* pointers = instr->pointer_map(); 353126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 353226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 353326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org if (instr->target()->IsConstantOperand()) { 353426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org LConstantOperand* target = LConstantOperand::cast(instr->target()); 353526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org Handle<Code> code = Handle<Code>::cast(ToHandle(target)); 353626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org generator.BeforeCall(__ CallSize(code)); 353726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ call(code, RelocInfo::CODE_TARGET); 353826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } else { 353926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org ASSERT(instr->target()->IsRegister()); 354026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org Register target = ToRegister(instr->target()); 354126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org generator.BeforeCall(__ CallSize(target)); 3542fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); 354326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ call(target); 354426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } 354526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org generator.AfterCall(); 354626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org} 354726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 354826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 354926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgvoid LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { 355026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org ASSERT(ToRegister(instr->function()).is(rdi)); 355126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org ASSERT(ToRegister(instr->result()).is(rax)); 355226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 355326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org if (instr->hydrogen()->pass_argument_count()) { 355426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ Set(rax, instr->arity()); 355526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } 355626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 355726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org // Change context. 355843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 355926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 356026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org LPointerMap* pointers = instr->pointer_map(); 356126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 356226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 356326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org bool is_self_call = false; 356426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org if (instr->hydrogen()->function()->IsConstant()) { 356526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org Handle<JSFunction> jsfun = Handle<JSFunction>::null(); 356626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org HConstant* fun_const = HConstant::cast(instr->hydrogen()->function()); 356726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org jsfun = Handle<JSFunction>::cast(fun_const->handle(isolate())); 356826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org is_self_call = jsfun.is_identical_to(info()->closure()); 356926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } 357026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 357126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org if (is_self_call) { 357226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ CallSelf(); 357326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } else { 357426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org Operand target = FieldOperand(rdi, JSFunction::kCodeEntryOffset); 357526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org generator.BeforeCall(__ CallSize(target)); 3576f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ Call(target); 357726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } 357826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org generator.AfterCall(); 3579c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3580c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3581c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3582e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 358356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input_reg = ToRegister(instr->value()); 35845d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 35855d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org Heap::kHeapNumberMapRootIndex); 35865d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org DeoptimizeIf(not_equal, instr->environment()); 35875d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 3588fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Label slow, allocated, done; 35895d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org Register tmp = input_reg.is(rax) ? rcx : rax; 35905d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx; 35915d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 35925d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Preserve the value of all registers. 359344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 35945d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 35955d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ movl(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 35965d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Check the sign of the argument. If the argument is positive, just 35975d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // return it. We do not need to patch the stack since |input| and 35985d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // |result| are the same register and |input| will be restored 35995d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // unchanged by popping safepoint registers. 36005d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ testl(tmp, Immediate(HeapNumber::kSignMask)); 3601fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ j(zero, &done); 36025d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36035d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ AllocateHeapNumber(tmp, tmp2, &slow); 3604fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ jmp(&allocated, Label::kNear); 36055d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36065d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Slow case: Call the runtime system to do the number allocation. 36075d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ bind(&slow); 3608935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org CallRuntimeFromDeferred( 3609895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Runtime::kHiddenAllocateHeapNumber, 0, instr, instr->context()); 36105d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Set the pointer to the new heap number in tmp. 361143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org if (!tmp.is(rax)) __ movp(tmp, rax); 36125d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Restore input_reg after call to runtime. 36135d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ LoadFromSafepointRegisterSlot(input_reg, input_reg); 36145d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36155d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ bind(&allocated); 3616bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset)); 36172f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ shlq(tmp2, Immediate(1)); 36182f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ shrq(tmp2, Immediate(1)); 3619bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); 36205d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ StoreToSafepointRegisterSlot(input_reg, tmp); 36215d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36225d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ bind(&done); 36235d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org} 36245d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36255d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 3626e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { 362756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input_reg = ToRegister(instr->value()); 36285d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ testl(input_reg, input_reg); 36295d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org Label is_positive; 3630fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org __ j(not_sign, &is_positive, Label::kNear); 36315d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ negl(input_reg); // Sets flags. 36325d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org DeoptimizeIf(negative, instr->environment()); 36335d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ bind(&is_positive); 3634c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3635c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3636c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3637594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::EmitSmiMathAbs(LMathAbs* instr) { 3638594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Register input_reg = ToRegister(instr->value()); 36397a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(input_reg, input_reg); 3640594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label is_positive; 3641594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ j(not_sign, &is_positive, Label::kNear); 36427a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ negp(input_reg); // Sets flags. 3643594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeoptimizeIf(negative, instr->environment()); 3644594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ bind(&is_positive); 3645594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 3646594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 3647594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 3648e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathAbs(LMathAbs* instr) { 36495d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Class for deferred case. 365032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org class DeferredMathAbsTaggedHeapNumber V8_FINAL : public LDeferredCode { 36515d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org public: 3652e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) 36535d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org : LDeferredCode(codegen), instr_(instr) { } 365432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual void Generate() V8_OVERRIDE { 36555d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 36565d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } 365732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 36585d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org private: 3659e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org LMathAbs* instr_; 36605d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org }; 36615d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 366256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(instr->value()->Equals(instr->result())); 36635d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org Representation r = instr->hydrogen()->value()->representation(); 36645d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 36655d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org if (r.IsDouble()) { 3666528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister scratch = double_scratch0(); 366756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 3668160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ xorps(scratch, scratch); 36695d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ subsd(scratch, input_reg); 3670ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org __ andps(input_reg, scratch); 36715d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } else if (r.IsInteger32()) { 36725d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org EmitIntegerMathAbs(instr); 3673594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else if (r.IsSmi()) { 3674594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org EmitSmiMathAbs(instr); 36755d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } else { // Tagged case. 36765d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org DeferredMathAbsTaggedHeapNumber* deferred = 36777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); 367856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input_reg = ToRegister(instr->value()); 36795d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Smi check. 36805d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ JumpIfNotSmi(input_reg, deferred->entry()); 3681594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org EmitSmiMathAbs(instr); 36825d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ bind(deferred->exit()); 36835d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } 3684c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3685c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3686c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3687e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathFloor(LMathFloor* instr) { 3688528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 36893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register output_reg = ToRegister(instr->result()); 369056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 36913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 3692160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (CpuFeatures::IsSupported(SSE4_1)) { 3693750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CpuFeatureScope scope(masm(), SSE4_1); 3694160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3695160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // Deoptimize if minus zero. 3696160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ movq(output_reg, input_reg); 3697160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ subq(output_reg, Immediate(1)); 3698160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org DeoptimizeIf(overflow, instr->environment()); 3699160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 3700160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown); 3701160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ cvttsd2si(output_reg, xmm_scratch); 3702a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ cmpl(output_reg, Immediate(0x1)); 3703a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org DeoptimizeIf(overflow, instr->environment()); 37043a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 37057a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org Label negative_sign, done; 37068432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // Deoptimize on unordered. 3707160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ xorps(xmm_scratch, xmm_scratch); // Zero the register. 3708160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ ucomisd(input_reg, xmm_scratch); 37097a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org DeoptimizeIf(parity_even, instr->environment()); 37107a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ j(below, &negative_sign, Label::kNear); 37117a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 3712160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 37134acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Check for negative zero. 37144acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Label positive_sign; 37154acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ j(above, &positive_sign, Label::kNear); 37164acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ movmskpd(output_reg, input_reg); 37174acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ testq(output_reg, Immediate(1)); 37184acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org DeoptimizeIf(not_zero, instr->environment()); 37194acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ Set(output_reg, 0); 37205924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org __ jmp(&done); 37214acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ bind(&positive_sign); 3722160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 37233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 3724160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // Use truncating instruction (OK because input is positive). 3725160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ cvttsd2si(output_reg, input_reg); 3726160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // Overflow is signalled with minint. 3727a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ cmpl(output_reg, Immediate(0x1)); 3728a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org DeoptimizeIf(overflow, instr->environment()); 37297a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ jmp(&done, Label::kNear); 37307a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 37317a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org // Non-zero negative reaches here. 37327a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ bind(&negative_sign); 37337a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org // Truncate, then compare and compensate. 37347a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ cvttsd2si(output_reg, input_reg); 3735528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Cvtlsi2sd(xmm_scratch, output_reg); 37367a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ ucomisd(input_reg, xmm_scratch); 37377a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ j(equal, &done, Label::kNear); 37387a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ subl(output_reg, Immediate(1)); 37397a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org DeoptimizeIf(overflow, instr->environment()); 37407a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 37417a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ bind(&done); 3742160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 3743c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3744c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3745c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3746e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathRound(LMathRound* instr) { 3747528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org const XMMRegister xmm_scratch = double_scratch0(); 37483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register output_reg = ToRegister(instr->result()); 374956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 3750381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org XMMRegister input_temp = ToDoubleRegister(instr->temp()); 37518432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org static int64_t one_half = V8_INT64_C(0x3FE0000000000000); // 0.5 37528432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org static int64_t minus_one_half = V8_INT64_C(0xBFE0000000000000); // -0.5 37533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 3754381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org Label done, round_to_zero, below_one_half; 3755935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 3756e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movq(kScratchRegister, one_half); 37573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ movq(xmm_scratch, kScratchRegister); 37584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ ucomisd(xmm_scratch, input_reg); 3759935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(above, &below_one_half, Label::kNear); 37604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 37614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x). 37624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ addsd(xmm_scratch, input_reg); 37634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ cvttsd2si(output_reg, xmm_scratch); 37644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Overflow is signalled with minint. 3765a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ cmpl(output_reg, Immediate(0x1)); 37664a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ RecordComment("D2I conversion overflow"); 3767a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org DeoptimizeIf(overflow, instr->environment()); 3768935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&done, dist); 37693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 37704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ bind(&below_one_half); 3771e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movq(kScratchRegister, minus_one_half); 37724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ movq(xmm_scratch, kScratchRegister); 37734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ ucomisd(xmm_scratch, input_reg); 3774935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(below_equal, &round_to_zero, Label::kNear); 37758432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 37764a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then 37774a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // compare and compensate. 3778381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org __ movq(input_temp, input_reg); // Do not alter input_reg. 3779381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org __ subsd(input_temp, xmm_scratch); 3780381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org __ cvttsd2si(output_reg, input_temp); 37814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Catch minint due to overflow, and to prevent overflow when compensating. 3782a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ cmpl(output_reg, Immediate(0x1)); 37834a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ RecordComment("D2I conversion overflow"); 3784a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org DeoptimizeIf(overflow, instr->environment()); 37858432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 3786528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Cvtlsi2sd(xmm_scratch, output_reg); 3787381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org __ ucomisd(xmm_scratch, input_temp); 3788381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org __ j(equal, &done, dist); 37894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ subl(output_reg, Immediate(1)); 37904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // No overflow because we already ruled out minint. 3791935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&done, dist); 37923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 37934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ bind(&round_to_zero); 37944a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if 37954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // we can ignore the difference between a result of -0 and +0. 37964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 37974a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ movq(output_reg, input_reg); 37984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ testq(output_reg, output_reg); 37994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ RecordComment("Minus zero"); 38004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org DeoptimizeIf(negative, instr->environment()); 38018432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org } 38024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Set(output_reg, 0); 38034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ bind(&done); 3804c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3805c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3806c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3807e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathSqrt(LMathSqrt* instr) { 38087e6132b924829c353864933f29124419916db550machenbach@chromium.org XMMRegister output = ToDoubleRegister(instr->result()); 38097e6132b924829c353864933f29124419916db550machenbach@chromium.org if (instr->value()->IsDoubleRegister()) { 38107e6132b924829c353864933f29124419916db550machenbach@chromium.org XMMRegister input = ToDoubleRegister(instr->value()); 38117e6132b924829c353864933f29124419916db550machenbach@chromium.org __ sqrtsd(output, input); 38127e6132b924829c353864933f29124419916db550machenbach@chromium.org } else { 38137e6132b924829c353864933f29124419916db550machenbach@chromium.org Operand input = ToOperand(instr->value()); 38147e6132b924829c353864933f29124419916db550machenbach@chromium.org __ sqrtsd(output, input); 38157e6132b924829c353864933f29124419916db550machenbach@chromium.org } 3816c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3817c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3818c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3819e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { 3820528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 382156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 38223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 382364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 382464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Note that according to ECMA-262 15.8.2.13: 382564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Math.pow(-Infinity, 0.5) == Infinity 382664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Math.sqrt(-Infinity) == NaN 382764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label done, sqrt; 382864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Check base for -Infinity. According to IEEE-754, double-precision 382964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // -Infinity has the highest 12 bits set and the lowest 52 bits cleared. 3830e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movq(kScratchRegister, V8_INT64_C(0xFFF0000000000000)); 383164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ movq(xmm_scratch, kScratchRegister); 383264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ ucomisd(xmm_scratch, input_reg); 383364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Comparing -Infinity with NaN results in "unordered", which sets the 383464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // zero flag as if both were equal. However, it also sets the carry flag. 383564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ j(not_equal, &sqrt, Label::kNear); 383664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ j(carry, &sqrt, Label::kNear); 383764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // If input is -Infinity, return Infinity. 383864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ xorps(input_reg, input_reg); 383964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ subsd(input_reg, xmm_scratch); 384064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ jmp(&done, Label::kNear); 384164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 384264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Square root. 384364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&sqrt); 3844160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org __ xorps(xmm_scratch, xmm_scratch); 38453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ addsd(input_reg, xmm_scratch); // Convert -0 to +0. 38463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ sqrtsd(input_reg, input_reg); 384764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&done); 3848c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3849c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3850c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3851c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoPower(LPower* instr) { 38529ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org Representation exponent_type = instr->hydrogen()->right()->representation(); 385364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Having marked this as a call, we can use any registers. 385464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Just make sure that the input/output registers are the expected ones. 385564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 385664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Register exponent = rdx; 385756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(!instr->right()->IsRegister() || 385856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ToRegister(instr->right()).is(exponent)); 385956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(!instr->right()->IsDoubleRegister() || 386056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ToDoubleRegister(instr->right()).is(xmm1)); 386156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(ToDoubleRegister(instr->left()).is(xmm2)); 386264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(ToDoubleRegister(instr->result()).is(xmm3)); 386364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 386453ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (exponent_type.IsSmi()) { 3865f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org MathPowStub stub(isolate(), MathPowStub::TAGGED); 386653ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org __ CallStub(&stub); 386753ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org } else if (exponent_type.IsTagged()) { 386864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label no_deopt; 3869935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ JumpIfSmi(exponent, &no_deopt, Label::kNear); 387064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CmpObjectType(exponent, HEAP_NUMBER_TYPE, rcx); 38719ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org DeoptimizeIf(not_equal, instr->environment()); 387264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&no_deopt); 3873f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org MathPowStub stub(isolate(), MathPowStub::TAGGED); 387464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CallStub(&stub); 387564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (exponent_type.IsInteger32()) { 3876f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org MathPowStub stub(isolate(), MathPowStub::INTEGER); 387764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CallStub(&stub); 387864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 387964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(exponent_type.IsDouble()); 3880f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org MathPowStub stub(isolate(), MathPowStub::DOUBLE); 388164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ CallStub(&stub); 38829ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 3883c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3884c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3885c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 38861f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgvoid LCodeGen::DoMathExp(LMathExp* instr) { 38871f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister input = ToDoubleRegister(instr->value()); 38881f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister result = ToDoubleRegister(instr->result()); 3889528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister temp0 = double_scratch0(); 38901f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org Register temp1 = ToRegister(instr->temp1()); 38911f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org Register temp2 = ToRegister(instr->temp2()); 38921f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 3893528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org MathExpGenerator::EmitMathExp(masm(), input, result, temp0, temp1, temp2); 38941f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org} 38951f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 38961f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 3897e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathLog(LMathLog* instr) { 38980fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org ASSERT(instr->value()->Equals(instr->result())); 38990fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 39000fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org XMMRegister xmm_scratch = double_scratch0(); 39010fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org Label positive, done, zero; 39020fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ xorps(xmm_scratch, xmm_scratch); 39030fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ ucomisd(input_reg, xmm_scratch); 39040fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ j(above, &positive, Label::kNear); 39054f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org __ j(not_carry, &zero, Label::kNear); 39060fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org ExternalReference nan = 39070fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org ExternalReference::address_of_canonical_non_hole_nan(); 39080fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org Operand nan_operand = masm()->ExternalOperand(nan); 39090fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(input_reg, nan_operand); 39100fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ jmp(&done, Label::kNear); 39110fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ bind(&zero); 39120fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org ExternalReference ninf = 39130fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org ExternalReference::address_of_negative_infinity(); 39140fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org Operand ninf_operand = masm()->ExternalOperand(ninf); 39150fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(input_reg, ninf_operand); 39160fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ jmp(&done, Label::kNear); 39170fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ bind(&positive); 39180fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ fldln2(); 3919fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rsp, Immediate(kDoubleSize)); 39200fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(Operand(rsp, 0), input_reg); 39210fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ fld_d(Operand(rsp, 0)); 39220fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ fyl2x(); 39230fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ fstp_d(Operand(rsp, 0)); 39240fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ movsd(input_reg, Operand(rsp, 0)); 3925fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rsp, Immediate(kDoubleSize)); 39260fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org __ bind(&done); 3927c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3928c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3929c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3930f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid LCodeGen::DoMathClz32(LMathClz32* instr) { 3931f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register input = ToRegister(instr->value()); 3932f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register result = ToRegister(instr->result()); 3933f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Label not_zero_input; 3934f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ bsrl(result, input); 3935f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3936f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ j(not_zero, ¬_zero_input); 3937f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ Set(result, 63); // 63^31 == 32 3938f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3939f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ bind(¬_zero_input); 3940f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ xorl(result, Immediate(31)); // for x in [0..31], 31^x == 31-x. 3941f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 3942f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3943f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3944160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgvoid LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 3945935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 3946160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(ToRegister(instr->function()).is(rdi)); 3947160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(instr->HasPointerMap()); 3948fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org 394932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 395032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (known_function.is_null()) { 3951fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org LPointerMap* pointers = instr->pointer_map(); 3952fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3953fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org ParameterCount count(instr->arity()); 3954e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ InvokeFunction(rdi, count, CALL_FUNCTION, generator); 3955fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org } else { 395632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CallKnownFunction(known_function, 395732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->hydrogen()->formal_parameter_count(), 3958fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr->arity(), 3959fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org instr, 3960fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org RDI_CONTAINS_TARGET); 3961fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org } 3962160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org} 3963160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 3964160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 3965c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCallFunction(LCallFunction* instr) { 3966935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 3967c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org ASSERT(ToRegister(instr->function()).is(rdi)); 39683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(ToRegister(instr->result()).is(rax)); 39693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 39703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int arity = instr->arity(); 3971f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags()); 3972f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 3973c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3974c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3975c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3976c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCallNew(LCallNew* instr) { 3977935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 397856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(ToRegister(instr->constructor()).is(rdi)); 3979378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ASSERT(ToRegister(instr->result()).is(rax)); 3980378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 3981378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org __ Set(rax, instr->arity()); 39821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // No cell in ebx for construct type feedback in optimized code 39835697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); 3984a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS); 3985f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 3986c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 3987c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 3988c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 39894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid LCodeGen::DoCallNewArray(LCallNewArray* instr) { 3990935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 39914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(ToRegister(instr->constructor()).is(rdi)); 39924a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(ToRegister(instr->result()).is(rax)); 39934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 39944a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Set(rax, instr->arity()); 39955697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); 399657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ElementsKind kind = instr->hydrogen()->elements_kind(); 39971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org AllocationSiteOverrideMode override_mode = 3998bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) 39991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? DISABLE_ALLOCATION_SITES 40001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org : DONT_OVERRIDE; 4001d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 4002ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if (instr->arity() == 0) { 4003f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode); 4004f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 4005ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else if (instr->arity() == 1) { 400641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Label done; 400741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (IsFastPackedElementsKind(kind)) { 400841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Label packed_case; 400941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // We might need a change here 401041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // look at the first argument 401143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, Operand(rsp, 0)); 40127a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rcx, rcx); 4013935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(zero, &packed_case, Label::kNear); 401441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 401541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ElementsKind holey_kind = GetHoleyElementsKind(kind); 4016f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org ArraySingleArgumentConstructorStub stub(isolate(), 4017f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org holey_kind, 4018f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org override_mode); 4019f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 4020935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&done, Label::kNear); 402141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ bind(&packed_case); 402241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } 402341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 4024f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); 4025f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 402641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ bind(&done); 4027ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else { 4028f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); 4029f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 4030ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 40314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 40324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 40334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 4034c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCallRuntime(LCallRuntime* instr) { 4035935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 4036fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles()); 4037c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4038c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4039c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4040662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgvoid LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) { 4041662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org Register function = ToRegister(instr->function()); 4042662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org Register code_object = ToRegister(instr->code_object()); 4043895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(code_object, FieldOperand(code_object, Code::kHeaderSize)); 404443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(function, JSFunction::kCodeEntryOffset), code_object); 4045662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org} 4046662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 4047662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 40482bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { 40492bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result = ToRegister(instr->result()); 40502bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register base = ToRegister(instr->base_object()); 4051ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (instr->offset()->IsConstantOperand()) { 4052ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org LConstantOperand* offset = LConstantOperand::cast(instr->offset()); 4053895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(result, Operand(base, ToInteger32(offset))); 4054ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else { 4055ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Register offset = ToRegister(instr->offset()); 4056895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(result, Operand(base, offset, times_1, 0)); 4057ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 40582bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org} 40592bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 40602bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 4061c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 406271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org HStoreNamedField* hinstr = instr->hydrogen(); 4063f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Representation representation = instr->representation(); 4064f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 406571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org HObjectAccess access = hinstr->access(); 406653ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org int offset = access.offset(); 4067378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 4068d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (access.IsExternalMemory()) { 406971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org ASSERT(!hinstr->NeedsWriteBarrier()); 4070d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register value = ToRegister(instr->value()); 4071d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->object()->IsConstantOperand()) { 4072d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(value.is(rax)); 4073d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org LConstantOperand* object = LConstantOperand::cast(instr->object()); 4074d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ store_rax(ToExternalReference(object)); 4075d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 4076d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register object = ToRegister(instr->object()); 4077d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org __ Store(MemOperand(object, offset), value, representation); 4078d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 4079d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return; 4080d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 4081d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 4082d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Register object = ToRegister(instr->object()); 4083d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org __ AssertNotSmi(object); 4084f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 4085d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org ASSERT(!representation.IsSmi() || 4086d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org !instr->value()->IsConstantOperand() || 4087d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org IsInteger32Constant(LConstantOperand::cast(instr->value()))); 4088d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org if (representation.IsDouble()) { 408953ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org ASSERT(access.IsInobject()); 4090c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org ASSERT(!hinstr->has_transition()); 409171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org ASSERT(!hinstr->NeedsWriteBarrier()); 409257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org XMMRegister value = ToDoubleRegister(instr->value()); 409357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movsd(FieldOperand(object, offset), value); 409457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org return; 4095f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 4096f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 4097c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org if (hinstr->has_transition()) { 4098c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org Handle<Map> transition = hinstr->transition_map(); 4099c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org AddDeprecationDependency(transition); 410071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (!hinstr->NeedsWriteBarrierForMap()) { 4101f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ Move(FieldOperand(object, HeapObject::kMapOffset), transition); 410237141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org } else { 410356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 4104f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ Move(kScratchRegister, transition); 410543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister); 410637141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org // Update the write barrier for the map field. 4107196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org __ RecordWriteForMap(object, 4108196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kScratchRegister, 4109196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org temp, 4110196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kSaveFPRegs); 411137141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org } 4112378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 4113378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 4114378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Do the store. 411577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Register write_register = object; 411653ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (!access.IsInobject()) { 411777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org write_register = ToRegister(instr->temp()); 411843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); 411977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 412077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 412104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (representation.IsSmi() && SmiValuesAre32Bits() && 412271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org hinstr->value()->representation().IsInteger32()) { 412371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); 41242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (FLAG_debug_code) { 41252ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Register scratch = kScratchRegister; 41262ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ Load(scratch, FieldOperand(write_register, offset), representation); 41272ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ AssertSmi(scratch); 41282ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 412971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org // Store int value directly to upper half of the smi. 413071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org STATIC_ASSERT(kSmiTag == 0); 413104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(kSmiTagSize + kSmiShiftSize == 32); 413271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org offset += kPointerSize / 2; 413371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org representation = Representation::Integer32(); 413471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } 413571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 413671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org Operand operand = FieldOperand(write_register, offset); 413771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 413871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (instr->value()->IsRegister()) { 413971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org Register value = ToRegister(instr->value()); 414071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ Store(operand, value, representation); 414171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } else { 414277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 414371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (IsInteger32Constant(operand_value)) { 414471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org ASSERT(!hinstr->NeedsWriteBarrier()); 41450cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org int32_t value = ToInteger32(operand_value); 414671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (representation.IsSmi()) { 414771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ Move(operand, Smi::FromInt(value)); 414871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 414971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } else { 415071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ movl(operand, Immediate(value)); 415171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } 415271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 415377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 415432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Handle<Object> handle_value = ToHandle(operand_value); 415571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org ASSERT(!hinstr->NeedsWriteBarrier()); 415671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ Move(operand, handle_value); 4157378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 415877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 415977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 416071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (hinstr->NeedsWriteBarrier()) { 416177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Register value = ToRegister(instr->value()); 416253ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object; 416377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // Update the write barrier for the object for in-object properties. 416477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ RecordWriteField(write_register, 416577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org offset, 416677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org value, 416777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org temp, 416877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org kSaveFPRegs, 416977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org EMIT_REMEMBERED_SET, 4170196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org hinstr->SmiCheckForWriteBarrier(), 4171196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org hinstr->PointersToHereCheckForValue()); 4172378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 4173c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4174c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4175c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4176c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { 4177935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 41783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(ToRegister(instr->object()).is(rdx)); 41793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(ToRegister(instr->value()).is(rax)); 41803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 41813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Move(rcx, instr->hydrogen()->name()); 4182486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode()); 41833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 41843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 41853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 41863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 4187c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 4188a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Representation representation = instr->hydrogen()->length()->representation(); 4189a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org ASSERT(representation.Equals(instr->hydrogen()->index()->representation())); 419050bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org ASSERT(representation.IsSmiOrInteger32()); 41917c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 4192a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Condition cc = instr->hydrogen()->allow_equality() ? below : below_equal; 4193a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org if (instr->length()->IsConstantOperand()) { 4194a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org int32_t length = ToInteger32(LConstantOperand::cast(instr->length())); 4195a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Register index = ToRegister(instr->index()); 4196a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org if (representation.IsSmi()) { 4197a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ Cmp(index, Smi::FromInt(length)); 4198a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org } else { 4199a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpl(index, Immediate(length)); 4200a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org } 420138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org cc = CommuteCondition(cc); 4202a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org } else if (instr->index()->IsConstantOperand()) { 4203a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org int32_t index = ToInteger32(LConstantOperand::cast(instr->index())); 4204a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org if (instr->length()->IsRegister()) { 4205a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Register length = ToRegister(instr->length()); 420650bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org if (representation.IsSmi()) { 4207a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ Cmp(length, Smi::FromInt(index)); 4208000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org } else { 4209a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpl(length, Immediate(index)); 4210000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org } 4211b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } else { 4212a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Operand length = ToOperand(instr->length()); 421350bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org if (representation.IsSmi()) { 4214a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ Cmp(length, Smi::FromInt(index)); 421550bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org } else { 4216a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpl(length, Immediate(index)); 4217f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 4218b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } 421983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 4220a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Register index = ToRegister(instr->index()); 4221a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org if (instr->length()->IsRegister()) { 4222a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Register length = ToRegister(instr->length()); 422350bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org if (representation.IsSmi()) { 4224a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpp(length, index); 422533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } else { 4226a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpl(length, index); 422733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 4228b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } else { 4229a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Operand length = ToOperand(instr->length()); 423050bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org if (representation.IsSmi()) { 4231a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpp(length, index); 423250bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org } else { 4233a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ cmpl(length, index); 423450bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org } 4235b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } 423683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 4237a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org if (FLAG_debug_code && instr->hydrogen()->skip_check()) { 4238a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Label done; 4239a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ j(NegateCondition(cc), &done, Label::kNear); 4240a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ int3(); 4241a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org __ bind(&done); 4242a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org } else { 4243a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org DeoptimizeIf(cc, instr->environment()); 4244a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org } 4245c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4246c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4247c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4248e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4249e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org ElementsKind elements_kind = instr->elements_kind(); 4250304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org LOperand* key = instr->key(); 425170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (kPointerSize == kInt32Size && !key->IsConstantOperand()) { 425270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Register key_reg = ToRegister(key); 425370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Representation key_representation = 425470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(); 425570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (ExternalArrayOpRequiresTemp(key_representation, elements_kind)) { 425670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ SmiToInteger64(key_reg, key_reg); 425770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } else if (instr->hydrogen()->IsDehoisted()) { 425870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Sign extend key because it could be a 32 bit negative value 425970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // and the dehoisted address computation happens in 64 bits 426070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ movsxlq(key_reg, key_reg); 426170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 426270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 4263e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Operand operand(BuildFastArrayOperand( 4264e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org instr->elements(), 4265e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org key, 426670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 4267e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org elements_kind, 4268fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org instr->base_offset())); 4269d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 4270af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || 42715c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org elements_kind == FLOAT32_ELEMENTS) { 4272e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org XMMRegister value(ToDoubleRegister(instr->value())); 4273e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ cvtsd2ss(value, value); 4274e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movss(operand, value); 4275af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || 42765c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org elements_kind == FLOAT64_ELEMENTS) { 4277e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movsd(operand, ToDoubleRegister(instr->value())); 4278304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } else { 4279e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Register value(ToRegister(instr->value())); 4280e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org switch (elements_kind) { 4281af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT8_CLAMPED_ELEMENTS: 4282af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_INT8_ELEMENTS: 4283af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT8_ELEMENTS: 42845c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case INT8_ELEMENTS: 42855c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT8_ELEMENTS: 42865c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT8_CLAMPED_ELEMENTS: 4287e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movb(operand, value); 4288e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 4289af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_INT16_ELEMENTS: 4290af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT16_ELEMENTS: 42915c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case INT16_ELEMENTS: 42925c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT16_ELEMENTS: 4293e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movw(operand, value); 4294e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 4295af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_INT32_ELEMENTS: 4296af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_UINT32_ELEMENTS: 42975c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case INT32_ELEMENTS: 42985c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case UINT32_ELEMENTS: 4299e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ movl(operand, value); 4300e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 4301af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_FLOAT32_ELEMENTS: 4302af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case EXTERNAL_FLOAT64_ELEMENTS: 43035c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case FLOAT32_ELEMENTS: 43045c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org case FLOAT64_ELEMENTS: 4305e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_ELEMENTS: 4306e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_SMI_ELEMENTS: 4307e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_DOUBLE_ELEMENTS: 4308e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_ELEMENTS: 4309e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_SMI_ELEMENTS: 4310e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_HOLEY_DOUBLE_ELEMENTS: 4311e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case DICTIONARY_ELEMENTS: 4312486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org case SLOPPY_ARGUMENTS_ELEMENTS: 4313e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org UNREACHABLE(); 4314e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org break; 4315e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 4316d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 4317c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4318c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4319c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4320e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { 4321717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org XMMRegister value = ToDoubleRegister(instr->value()); 4322304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org LOperand* key = instr->key(); 432370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (kPointerSize == kInt32Size && !key->IsConstantOperand() && 432470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->IsDehoisted()) { 432570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Sign extend key because it could be a 32 bit negative value 432670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // and the dehoisted address computation happens in 64 bits 432770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ movsxlq(ToRegister(key), ToRegister(key)); 432870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 432928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (instr->NeedsCanonicalization()) { 433028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label have_value; 4331717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 433228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ ucomisd(value, value); 4333935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(parity_odd, &have_value, Label::kNear); // NaN. 433428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 433528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ Set(kScratchRegister, BitCast<uint64_t>( 433628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org FixedDoubleArray::canonical_not_the_hole_nan_as_double())); 433728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ movq(value, kScratchRegister); 433828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 433928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org __ bind(&have_value); 434028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 4341717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 4342717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org Operand double_store_operand = BuildFastArrayOperand( 43430e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org instr->elements(), 4344304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org key, 434570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 43460e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org FAST_DOUBLE_ELEMENTS, 4347fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org instr->base_offset()); 43480e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org 4349717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org __ movsd(double_store_operand, value); 4350717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org} 4351717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 4352e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 4353e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 435471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org HStoreKeyed* hinstr = instr->hydrogen(); 4355e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org LOperand* key = instr->key(); 4356fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org int offset = instr->base_offset(); 435771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org Representation representation = hinstr->value()->representation(); 435871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 435970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (kPointerSize == kInt32Size && !key->IsConstantOperand() && 436070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->IsDehoisted()) { 436170d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Sign extend key because it could be a 32 bit negative value 436270d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // and the dehoisted address computation happens in 64 bits 436370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ movsxlq(ToRegister(key), ToRegister(key)); 436470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 436504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (representation.IsInteger32() && SmiValuesAre32Bits()) { 436671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); 436771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); 43682ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (FLAG_debug_code) { 43692ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Register scratch = kScratchRegister; 43702ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ Load(scratch, 43712ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org BuildFastArrayOperand(instr->elements(), 43722ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org key, 437370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 43742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org FAST_ELEMENTS, 4375fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org offset), 43762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Representation::Smi()); 43772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ AssertSmi(scratch); 43782ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 437971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org // Store int value directly to upper half of the smi. 438071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org STATIC_ASSERT(kSmiTag == 0); 438104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(kSmiTagSize + kSmiShiftSize == 32); 438271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org offset += kPointerSize / 2; 438371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } 438471ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 4385e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Operand operand = 4386e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org BuildFastArrayOperand(instr->elements(), 4387e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org key, 438870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org instr->hydrogen()->key()->representation(), 4389e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org FAST_ELEMENTS, 4390fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org offset); 439177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (instr->value()->IsRegister()) { 439271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ Store(operand, ToRegister(instr->value()), representation); 439377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 439477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 439577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (IsInteger32Constant(operand_value)) { 439671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org int32_t value = ToInteger32(operand_value); 439771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (representation.IsSmi()) { 439871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ Move(operand, Smi::FromInt(value)); 439971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 440071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } else { 440171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org __ movl(operand, Immediate(value)); 440271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } 440377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 440477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Handle<Object> handle_value = ToHandle(operand_value); 440577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ Move(operand, handle_value); 440677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 440777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 4408e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 440971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (hinstr->NeedsWriteBarrier()) { 441071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org Register elements = ToRegister(instr->elements()); 441177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org ASSERT(instr->value()->IsRegister()); 441277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Register value = ToRegister(instr->value()); 441371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org ASSERT(!key->IsConstantOperand()); 4414eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org SmiCheck check_needed = hinstr->value()->type().IsHeapObject() 44151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4416e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org // Compute address of modified element and store it into key register. 4417e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Register key_reg(ToRegister(key)); 4418895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(key_reg, operand); 4419e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org __ RecordWrite(elements, 4420e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org key_reg, 4421e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org value, 4422e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org kSaveFPRegs, 4423e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org EMIT_REMEMBERED_SET, 4424196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org check_needed, 4425196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org hinstr->PointersToHereCheckForValue()); 4426e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 4427e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 4428e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 4429e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 4430e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { 44315c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org if (instr->is_typed_elements()) { 4432e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoStoreKeyedExternalArray(instr); 4433e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else if (instr->hydrogen()->value()->representation().IsDouble()) { 4434e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoStoreKeyedFixedDoubleArray(instr); 4435e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 4436e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org DoStoreKeyedFixedArray(instr); 4437e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 4438e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 4439e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 4440e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 4441c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 4442935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 44433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(ToRegister(instr->object()).is(rdx)); 44443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(ToRegister(instr->key()).is(rcx)); 44453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(ToRegister(instr->value()).is(rax)); 44463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 4447486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org Handle<Code> ic = instr->strict_mode() == STRICT 44487979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 44497979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org : isolate()->builtins()->KeyedStoreIC_Initialize(); 44503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 44513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 44523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 44533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 4454394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 4455394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register object_reg = ToRegister(instr->object()); 4456394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 4457394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Map> from_map = instr->original_map(); 4458394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Map> to_map = instr->transitioned_map(); 4459003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ElementsKind from_kind = instr->from_kind(); 4460003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ElementsKind to_kind = instr->to_kind(); 4461394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 4462394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label not_applicable; 4463394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); 4464394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ j(not_equal, ¬_applicable); 4465830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (IsSimpleMapChangeTransition(from_kind, to_kind)) { 446694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register new_map_reg = ToRegister(instr->new_map_temp()); 44679cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org __ Move(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); 446843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); 4469394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Write barrier. 4470196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org __ RecordWriteForMap(object_reg, new_map_reg, ToRegister(instr->temp()), 4471196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kDontSaveFPRegs); 4472d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else { 44732f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org ASSERT(object_reg.is(rax)); 4474cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 447594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org PushSafepointRegistersScope scope(this); 447694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ Move(rbx, to_map); 44779801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE; 4478f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org TransitionElementsKindStub stub(isolate(), from_kind, to_kind, is_js_array); 447994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ CallStub(&stub); 44802f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0); 4481394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 4482394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(¬_applicable); 4483394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 4484394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 4485394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 448694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 448794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register object = ToRegister(instr->object()); 448894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register temp = ToRegister(instr->temp()); 4489b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Label no_memento_found; 4490b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found); 449194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org DeoptimizeIf(equal, instr->environment()); 4492b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org __ bind(&no_memento_found); 449394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 449494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 449594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 4496160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgvoid LCodeGen::DoStringAdd(LStringAdd* instr) { 4497935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 4498bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org ASSERT(ToRegister(instr->left()).is(rdx)); 4499bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org ASSERT(ToRegister(instr->right()).is(rax)); 4500f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org StringAddStub stub(isolate(), 4501f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org instr->hydrogen()->flags(), 450205150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org instr->hydrogen()->pretenure_flag()); 4503f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 4504160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org} 4505160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 4506160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 45073a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { 450832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { 45093a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org public: 45103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 45113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org : LDeferredCode(codegen), instr_(instr) { } 451232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual void Generate() V8_OVERRIDE { 451332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org codegen()->DoDeferredStringCharCodeAt(instr_); 451432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org } 451532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 45163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org private: 45173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LStringCharCodeAt* instr_; 45183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org }; 45193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org DeferredStringCharCodeAt* deferred = 45217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredStringCharCodeAt(this, instr); 45223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org StringCharLoadGenerator::Generate(masm(), 45241b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ToRegister(instr->string()), 45251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ToRegister(instr->index()), 45261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ToRegister(instr->result()), 45271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org deferred->entry()); 45283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(deferred->exit()); 45293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 45303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { 45333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register string = ToRegister(instr->string()); 45343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register result = ToRegister(instr->result()); 45353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 45373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // result register contain a valid pointer because it is already 45383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // contained in the register pointer map. 45393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Set(result, 0); 45403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 454144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 4542763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(string); 45433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Push the index as a smi. This is safe because of the checks in 45443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // DoStringCharCodeAt above. 45453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); 45463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (instr->index()->IsConstantOperand()) { 4547594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index())); 45483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Push(Smi::FromInt(const_index)); 45493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 45503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register index = ToRegister(instr->index()); 45513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Integer32ToSmi(index, index); 4552763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(index); 45533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 4554935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org CallRuntimeFromDeferred( 45559b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org Runtime::kHiddenStringCharCodeAt, 2, instr, instr->context()); 4556c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ AssertSmi(rax); 45573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ SmiToInteger32(rax, rax); 45583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ StoreToSafepointRegisterSlot(result, rax); 4559c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4560c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4561c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4562b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.orgvoid LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { 456332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org class DeferredStringCharFromCode V8_FINAL : public LDeferredCode { 4564b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org public: 4565b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) 4566b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org : LDeferredCode(codegen), instr_(instr) { } 456732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual void Generate() V8_OVERRIDE { 456832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org codegen()->DoDeferredStringCharFromCode(instr_); 456932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org } 457032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 4571b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org private: 4572b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org LStringCharFromCode* instr_; 4573b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org }; 4574b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4575b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org DeferredStringCharFromCode* deferred = 45767028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredStringCharFromCode(this, instr); 4577b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4578b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); 4579b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register char_code = ToRegister(instr->char_code()); 4580b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register result = ToRegister(instr->result()); 4581b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org ASSERT(!char_code.is(result)); 4582b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 458359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmpl(char_code, Immediate(String::kMaxOneByteCharCode)); 4584b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ j(above, deferred->entry()); 4585f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ movsxlq(char_code, char_code); 4586b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex); 458743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(result, 4588b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org char_code, times_pointer_size, 4589b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org FixedArray::kHeaderSize)); 4590b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ CompareRoot(result, Heap::kUndefinedValueRootIndex); 4591b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ j(equal, deferred->entry()); 4592b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ bind(deferred->exit()); 4593b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org} 4594b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4595b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4596b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.orgvoid LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { 4597b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register char_code = ToRegister(instr->char_code()); 4598b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register result = ToRegister(instr->result()); 4599b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4600b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 4601b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // result register contain a valid pointer because it is already 4602b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // contained in the register pointer map. 4603b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ Set(result, 0); 4604b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 460544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 4606b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ Integer32ToSmi(char_code, char_code); 4607763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(char_code); 4608935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context()); 4609b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ StoreToSafepointRegisterSlot(result, rax); 4610b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org} 4611b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4612b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 4613c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 461456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 46150ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org ASSERT(input->IsRegister() || input->IsStackSlot()); 46160ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org LOperand* output = instr->result(); 46170ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org ASSERT(output->IsDoubleRegister()); 461849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (input->IsRegister()) { 4619528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Cvtlsi2sd(ToDoubleRegister(output), ToRegister(input)); 462049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } else { 4621528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Cvtlsi2sd(ToDoubleRegister(output), ToOperand(input)); 462249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 4623c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4624c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4625c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 462646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 462756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 462846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org LOperand* output = instr->result(); 462946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 46307e6132b924829c353864933f29124419916db550machenbach@chromium.org __ LoadUint32(ToDoubleRegister(output), ToRegister(input)); 463146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 463246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 463346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4634c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4635e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org class DeferredNumberTagI V8_FINAL : public LDeferredCode { 4636e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org public: 4637e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 4638e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org : LDeferredCode(codegen), instr_(instr) { } 4639e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org virtual void Generate() V8_OVERRIDE { 4640e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(), 4641e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org instr_->temp2(), SIGNED_INT32); 4642e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 4643e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 4644e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org private: 4645e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org LNumberTagI* instr_; 4646e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org }; 4647e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 464856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 46490ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org ASSERT(input->IsRegister() && input->Equals(instr->result())); 46500ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org Register reg = ToRegister(input); 4651c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4652e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (SmiValuesAre32Bits()) { 4653e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ Integer32ToSmi(reg, reg); 4654e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } else { 4655e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 4656e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); 4657e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ Integer32ToSmi(reg, reg); 4658e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ j(overflow, deferred->entry()); 4659e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ bind(deferred->exit()); 4660e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 4661c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4662c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4663c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 466446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid LCodeGen::DoNumberTagU(LNumberTagU* instr) { 466532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org class DeferredNumberTagU V8_FINAL : public LDeferredCode { 466646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org public: 466746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 466846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org : LDeferredCode(codegen), instr_(instr) { } 466932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual void Generate() V8_OVERRIDE { 4670e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(), 4671e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org instr_->temp2(), UNSIGNED_INT32); 467246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } 467332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 467446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org private: 467546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org LNumberTagU* instr_; 467646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org }; 467746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 467856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 467946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ASSERT(input->IsRegister() && input->Equals(instr->result())); 468046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Register reg = ToRegister(input); 468146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 468246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 468346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ cmpl(reg, Immediate(Smi::kMaxValue)); 468446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ j(above, deferred->entry()); 468546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ Integer32ToSmi(reg, reg); 468646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ bind(deferred->exit()); 468746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 468846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 468946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4690e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.orgvoid LCodeGen::DoDeferredNumberTagIU(LInstruction* instr, 4691e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org LOperand* value, 4692e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org LOperand* temp1, 4693e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org LOperand* temp2, 4694e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org IntegerSignedness signedness) { 4695bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org Label done, slow; 4696e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Register reg = ToRegister(value); 4697e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Register tmp = ToRegister(temp1); 4698e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org XMMRegister temp_xmm = ToDoubleRegister(temp2); 469946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4700c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org // Load value into temp_xmm which will be preserved across potential call to 470146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // runtime (MacroAssembler::EnterExitFrameEpilogue preserves only allocatable 470246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // XMM registers on x64). 4703e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (signedness == SIGNED_INT32) { 4704e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 4705e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // There was overflow, so bits 30 and 31 of the original integer 4706e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // disagree. Try to allocate a heap number in new space and store 4707e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // the value in there. If that fails, call the runtime system. 4708e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ SmiToInteger32(reg, reg); 4709e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ xorl(reg, Immediate(0x80000000)); 4710e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ cvtlsi2sd(temp_xmm, reg); 4711e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } else { 4712e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(signedness == UNSIGNED_INT32); 4713e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ LoadUint32(temp_xmm, reg); 4714e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 471546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 471646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if (FLAG_inline_new) { 471746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ AllocateHeapNumber(reg, tmp, &slow); 471846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ jmp(&done, Label::kNear); 471946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } 472046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 472146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Slow case: Call the runtime system to do the number allocation. 472246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ bind(&slow); 4723bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org { 4724bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // Put a valid pointer value in the stack slot where the result 4725bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // register is stored, as this register is in the pointer map, but contains 4726bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // an integer value. 4727bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org __ Set(reg, 0); 472846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4729bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // Preserve the value of all registers. 4730bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org PushSafepointRegistersScope scope(this); 4731935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 4732e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // NumberTagIU uses the context from the frame, rather than 4733bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // the environment's HContext or HInlinedContext value. 4734895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // They only call Runtime::kHiddenAllocateHeapNumber. 4735bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // The corresponding HChange instructions are added in a phase that does 4736bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // not have easy access to the local context. 4737bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 4738895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kHiddenAllocateHeapNumber); 4739bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org RecordSafepointWithRegisters( 4740bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 4741bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org __ StoreToSafepointRegisterSlot(reg, rax); 4742bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org } 474346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4744c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org // Done. Put the value in temp_xmm into the value of the allocated heap 474546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // number. 474646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ bind(&done); 4747c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), temp_xmm); 474846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 474946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 475046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4751c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoNumberTagD(LNumberTagD* instr) { 475232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org class DeferredNumberTagD V8_FINAL : public LDeferredCode { 47530ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org public: 47540ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 47550ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org : LDeferredCode(codegen), instr_(instr) { } 475632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual void Generate() V8_OVERRIDE { 475732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org codegen()->DoDeferredNumberTagD(instr_); 475832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org } 475932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 47600ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org private: 47610ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org LNumberTagD* instr_; 47620ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org }; 47630ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 476456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister input_reg = ToDoubleRegister(instr->value()); 47650ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org Register reg = ToRegister(instr->result()); 476656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register tmp = ToRegister(instr->temp()); 47670ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 47687028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 47690ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (FLAG_inline_new) { 47700ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ AllocateHeapNumber(reg, tmp, deferred->entry()); 47710ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else { 47720ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ jmp(deferred->entry()); 47730ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 47740ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ bind(deferred->exit()); 47750ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 4776c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4777c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4778c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4779c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 47800ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 47810ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // result register contain a valid pointer because it is already 47820ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // contained in the register pointer map. 47830ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org Register reg = ToRegister(instr->result()); 47840ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ Move(reg, Smi::FromInt(0)); 47850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 478644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org { 478744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org PushSafepointRegistersScope scope(this); 4788935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // NumberTagD uses the context from the frame, rather than 4789935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // the environment's HContext or HInlinedContext value. 4790895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // They only call Runtime::kHiddenAllocateHeapNumber. 4791935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // The corresponding HChange instructions are added in a phase that does 4792935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // not have easy access to the local context. 479343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 4794895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kHiddenAllocateHeapNumber); 4795935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org RecordSafepointWithRegisters( 4796935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 479743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(kScratchRegister, rax); 479844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 479943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(reg, kScratchRegister); 4800c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4801c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4802c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4803c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoSmiTag(LSmiTag* instr) { 4804381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org HChange* hchange = instr->hydrogen(); 480556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 4806381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org Register output = ToRegister(instr->result()); 4807381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org if (hchange->CheckFlag(HValue::kCanOverflow) && 4808381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org hchange->value()->CheckFlag(HValue::kUint32)) { 480970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org Condition is_smi = __ CheckUInteger32ValidSmiValue(input); 481070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org DeoptimizeIf(NegateCondition(is_smi), instr->environment()); 4811381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org } 4812381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org __ Integer32ToSmi(output, input); 4813381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org if (hchange->CheckFlag(HValue::kCanOverflow) && 4814381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org !hchange->value()->CheckFlag(HValue::kUint32)) { 4815381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org DeoptimizeIf(overflow, instr->environment()); 4816381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org } 4817c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4818c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4819c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4820c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoSmiUntag(LSmiUntag* instr) { 482156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(instr->value()->Equals(instr->result())); 482256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 4823d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (instr->needs_check()) { 4824d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com Condition is_smi = __ CheckSmi(input); 4825d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com DeoptimizeIf(NegateCondition(is_smi), instr->environment()); 48267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } else { 4827c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ AssertSmi(input); 4828d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 4829d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ SmiToInteger32(input, input); 4830c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4831c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4832c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4833c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::EmitNumberUntagD(Register input_reg, 4834c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org XMMRegister result_reg, 4835c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org bool can_convert_undefined_to_nan, 4836f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com bool deoptimize_on_minus_zero, 483794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org LEnvironment* env, 483894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org NumberUntagDMode mode) { 4839528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label convert, load_smi, done; 48400ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4841c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 484294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // Smi check. 484394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ JumpIfSmi(input_reg, &load_smi, Label::kNear); 48440ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 484594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // Heap number map check. 484694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 484794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Heap::kHeapNumberMapRootIndex); 48482f877ace3ac6432b1ce44abd553cd3ff97321680hpayer@chromium.org 4849528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // On x64 it is safe to load at heap number offset before evaluating the map 4850528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // check, since all heap objects are at least two words long. 4851528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); 48522f877ace3ac6432b1ce44abd553cd3ff97321680hpayer@chromium.org 4853528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (can_convert_undefined_to_nan) { 4854935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(not_equal, &convert, Label::kNear); 4855528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } else { 4856528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org DeoptimizeIf(not_equal, env); 48572f877ace3ac6432b1ce44abd553cd3ff97321680hpayer@chromium.org } 4858528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 485994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (deoptimize_on_minus_zero) { 4860528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 486194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ xorps(xmm_scratch, xmm_scratch); 486294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ ucomisd(xmm_scratch, result_reg); 486394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ j(not_equal, &done, Label::kNear); 486494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ movmskpd(kScratchRegister, result_reg); 486594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ testq(kScratchRegister, Immediate(1)); 486694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org DeoptimizeIf(not_zero, env); 486794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 486894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ jmp(&done, Label::kNear); 4869528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4870528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (can_convert_undefined_to_nan) { 4871528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ bind(&convert); 4872528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4873528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Convert undefined (and hole) to NaN. Compute NaN as 0/0. 4874528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex); 4875528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org DeoptimizeIf(not_equal, env); 4876528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4877528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ xorps(result_reg, result_reg); 4878528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ divsd(result_reg, result_reg); 4879528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ jmp(&done, Label::kNear); 4880528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 488194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } else { 488294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); 4883f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } 48840ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 48850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Smi to XMM conversion 48860ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ bind(&load_smi); 488749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org __ SmiToInteger32(kScratchRegister, input_reg); 4888528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Cvtlsi2sd(result_reg, kScratchRegister); 48890ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org __ bind(&done); 4890c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4891c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4892c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4893c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) { 489456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input_reg = ToRegister(instr->value()); 489583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 489683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (instr->truncating()) { 48972efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label no_heap_number, check_bools, check_false; 48982efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 4899c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Heap number map check. 4900c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 4901c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Heap::kHeapNumberMapRootIndex); 49022efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ j(not_equal, &no_heap_number, Label::kNear); 49032efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ TruncateHeapNumberToI(input_reg, input_reg); 49042efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ jmp(done); 49052efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 49062efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ bind(&no_heap_number); 49072efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org // Check for Oddballs. Undefined/False is converted to zero and True to one 49082efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org // for truncating conversions. 490983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex); 49102efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ j(not_equal, &check_bools, Label::kNear); 4911a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org __ Set(input_reg, 0); 4912c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ jmp(done); 491383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 49142efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ bind(&check_bools); 49152efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ CompareRoot(input_reg, Heap::kTrueValueRootIndex); 49162efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ j(not_equal, &check_false, Label::kNear); 49172efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ Set(input_reg, 1); 49182efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ jmp(done); 49192efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 49202efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ bind(&check_false); 49212efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ CompareRoot(input_reg, Heap::kFalseValueRootIndex); 49222efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ RecordComment("Deferred TaggedToI: cannot truncate"); 49232efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org DeoptimizeIf(not_equal, instr->environment()); 49242efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ Set(input_reg, 0); 49252efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ jmp(done); 492683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 4927c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label bailout; 492856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 4929c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ TaggedToI(input_reg, input_reg, xmm_temp, 4930c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); 4931c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 4932c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ jmp(done); 4933c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ bind(&bailout); 4934c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org DeoptimizeIf(no_condition, instr->environment()); 493583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 4936c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4937c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4938c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4939c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoTaggedToI(LTaggedToI* instr) { 494032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org class DeferredTaggedToI V8_FINAL : public LDeferredCode { 4941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 4942c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 4943c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : LDeferredCode(codegen), instr_(instr) { } 494432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual void Generate() V8_OVERRIDE { 4945c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org codegen()->DoDeferredTaggedToI(instr_, done()); 494632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org } 494732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 4948c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 4949c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LTaggedToI* instr_; 4950c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 4951c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 495256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 495383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(input->IsRegister()); 495483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(input->Equals(instr->result())); 49552f877ace3ac6432b1ce44abd553cd3ff97321680hpayer@chromium.org Register input_reg = ToRegister(input); 4956528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4957528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (instr->hydrogen()->value()->representation().IsSmi()) { 4958528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ SmiToInteger32(input_reg, input_reg); 4959528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } else { 4960528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); 4961528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ JumpIfNotSmi(input_reg, deferred->entry()); 4962528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ SmiToInteger32(input_reg, input_reg); 4963528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ bind(deferred->exit()); 4964528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 4965c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4966c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4967c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4968c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 496956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 497049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org ASSERT(input->IsRegister()); 497149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org LOperand* result = instr->result(); 497249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org ASSERT(result->IsDoubleRegister()); 497349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 497449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org Register input_reg = ToRegister(input); 497549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org XMMRegister result_reg = ToDoubleRegister(result); 497649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 497794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org HValue* value = instr->hydrogen()->value(); 4978c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org NumberUntagDMode mode = value->representation().IsSmi() 4979c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED; 498094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 49816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org EmitNumberUntagD(input_reg, result_reg, 4982c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org instr->hydrogen()->can_convert_undefined_to_nan(), 4983f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com instr->hydrogen()->deoptimize_on_minus_zero(), 498494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org instr->environment(), 498594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org mode); 4986c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 4987c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4988c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 4989c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoDoubleToI(LDoubleToI* instr) { 499056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 49913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(input->IsDoubleRegister()); 49923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org LOperand* result = instr->result(); 49933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(result->IsRegister()); 49943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 49953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org XMMRegister input_reg = ToDoubleRegister(input); 49963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register result_reg = ToRegister(result); 49973a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 49983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (instr->truncating()) { 4999c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ TruncateDoubleToI(result_reg, input_reg); 50003a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 5001c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label bailout, done; 5002528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 5003528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ DoubleToI(result_reg, input_reg, xmm_scratch, 5004c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); 5005c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 5006c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ jmp(&done, Label::kNear); 5007c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ bind(&bailout); 5008c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org DeoptimizeIf(no_condition, instr->environment()); 5009c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ bind(&done); 50103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 5011c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5012c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5013c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5014a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 5015a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org LOperand* input = instr->value(); 5016a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ASSERT(input->IsDoubleRegister()); 5017a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org LOperand* result = instr->result(); 5018a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ASSERT(result->IsRegister()); 5019a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5020a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org XMMRegister input_reg = ToDoubleRegister(input); 5021a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register result_reg = ToRegister(result); 5022a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5023c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label bailout, done; 5024528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 5025528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ DoubleToI(result_reg, input_reg, xmm_scratch, 5026c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); 5027c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 5028c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ jmp(&done, Label::kNear); 5029c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ bind(&bailout); 5030c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org DeoptimizeIf(no_condition, instr->environment()); 5031c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ bind(&done); 5032a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5033a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ Integer32ToSmi(result_reg, result_reg); 5034a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org DeoptimizeIf(overflow, instr->environment()); 5035a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org} 5036a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5037a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5038c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCheckSmi(LCheckSmi* instr) { 503956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5040378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Condition cc = masm()->CheckSmi(ToRegister(input)); 5041badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org DeoptimizeIf(NegateCondition(cc), instr->environment()); 5042badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org} 5043badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 5044badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 5045badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 5046eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org if (!instr->hydrogen()->value()->type().IsHeapObject()) { 50471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org LOperand* input = instr->value(); 50481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Condition cc = masm()->CheckSmi(ToRegister(input)); 50491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org DeoptimizeIf(cc, instr->environment()); 50501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 5051c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5052c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5053c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5054c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 505556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 505683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 505743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset)); 505883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 505983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (instr->hydrogen()->is_interval_check()) { 506083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org InstanceType first; 506183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org InstanceType last; 506283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org instr->hydrogen()->GetCheckInterval(&first, &last); 506383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 506483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), 506583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Immediate(static_cast<int8_t>(first))); 506683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 506783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // If there is only one type in the interval check for equality. 506883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (first == last) { 506983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org DeoptimizeIf(not_equal, instr->environment()); 507083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 507183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org DeoptimizeIf(below, instr->environment()); 507283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Omit check for the last type. 507383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (last != LAST_TYPE) { 507483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), 507583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Immediate(static_cast<int8_t>(last))); 507683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org DeoptimizeIf(above, instr->environment()); 507783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 507883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 507983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 508083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org uint8_t mask; 508183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org uint8_t tag; 508283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); 508383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 508483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (IsPowerOf2(mask)) { 508583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(tag == 0 || IsPowerOf2(tag)); 508683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ testb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), 508783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Immediate(mask)); 508883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org DeoptimizeIf(tag == 0 ? not_zero : zero, instr->environment()); 508983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 509083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ movzxbl(kScratchRegister, 509183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); 509283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ andb(kScratchRegister, Immediate(mask)); 509383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ cmpb(kScratchRegister, Immediate(tag)); 509483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org DeoptimizeIf(not_equal, instr->environment()); 509583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 509683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 5097c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5098c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5099c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 51001f410f9a9c4fbd4270749af64b477df87b753158mstarzinger@chromium.orgvoid LCodeGen::DoCheckValue(LCheckValue* instr) { 510164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Register reg = ToRegister(instr->value()); 5102c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Cmp(reg, instr->hydrogen()->object().handle()); 5103378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5104c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5105c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5106c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5107594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 5108594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org { 5109594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org PushSafepointRegistersScope scope(this); 5110763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(object); 5111935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ Set(rsi, 0); 5112e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance); 5113935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org RecordSafepointWithRegisters( 5114935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org instr->pointer_map(), 1, Safepoint::kNoLazyDeopt); 5115935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 51167a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rax, Immediate(kSmiTagMask)); 5117594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5118594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeoptimizeIf(zero, instr->environment()); 5119f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 5120f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 5121f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 51221456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid LCodeGen::DoCheckMaps(LCheckMaps* instr) { 512332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org class DeferredCheckMaps V8_FINAL : public LDeferredCode { 5124594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org public: 5125594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) 5126594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org : LDeferredCode(codegen), instr_(instr), object_(object) { 5127594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org SetExit(check_maps()); 5128594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 512932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual void Generate() V8_OVERRIDE { 5130594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org codegen()->DoDeferredInstanceMigration(instr_, object_); 5131594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5132594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label* check_maps() { return &check_maps_; } 513332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 5134594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org private: 5135594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org LCheckMaps* instr_; 5136594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label check_maps_; 5137594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Register object_; 5138594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org }; 5139594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5140af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org if (instr->hydrogen()->IsStabilityCheck()) { 5141af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org const UniqueSet<Map>* maps = instr->hydrogen()->maps(); 5142af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org for (int i = 0; i < maps->size(); ++i) { 5143af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org AddStabilityDependency(maps->at(i).handle()); 5144af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org } 5145af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org return; 5146af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org } 5147594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 514856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5149378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org ASSERT(input->IsRegister()); 5150378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org Register reg = ToRegister(input); 51511456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 5152594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeferredCheckMaps* deferred = NULL; 5153af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org if (instr->hydrogen()->HasMigrationTarget()) { 5154594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org deferred = new(zone()) DeferredCheckMaps(this, instr, reg); 5155594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ bind(deferred->check_maps()); 5156594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5157594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5158af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org const UniqueSet<Map>* maps = instr->hydrogen()->maps(); 5159594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Label success; 5160af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org for (int i = 0; i < maps->size() - 1; i++) { 5161af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org Handle<Map> map = maps->at(i).handle(); 5162935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ CompareMap(reg, map); 5163935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(equal, &success, Label::kNear); 51641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 5165594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5166af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org Handle<Map> map = maps->at(maps->size() - 1).handle(); 5167935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ CompareMap(reg, map); 5168af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org if (instr->hydrogen()->HasMigrationTarget()) { 5169594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ j(not_equal, deferred->entry()); 5170594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 5171594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5172594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 5173594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 51741456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ bind(&success); 5175c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5176c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5177c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5178c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 5179c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org XMMRegister value_reg = ToDoubleRegister(instr->unclamped()); 5180528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 5181c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register result_reg = ToRegister(instr->result()); 5182528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ ClampDoubleToUint8(value_reg, xmm_scratch, result_reg); 5183c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 5184c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5185c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5186c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 5187c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(instr->unclamped()->Equals(instr->result())); 5188c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register value_reg = ToRegister(instr->result()); 5189c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ ClampUint8(value_reg); 5190c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 5191c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5192c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5193c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 5194c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(instr->unclamped()->Equals(instr->result())); 5195c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register input_reg = ToRegister(instr->unclamped()); 519689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org XMMRegister temp_xmm_reg = ToDoubleRegister(instr->temp_xmm()); 5197528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 5198c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label is_smi, done, heap_number; 5199935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 5200935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ JumpIfSmi(input_reg, &is_smi, dist); 5201c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5202c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check for heap number 5203c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5204c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org factory()->heap_number_map()); 5205c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ j(equal, &heap_number, Label::kNear); 5206c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5207c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check for undefined. Undefined is converted to zero for clamping 5208c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // conversions. 5209c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Cmp(input_reg, factory()->undefined_value()); 5210c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5211a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ xorl(input_reg, input_reg); 5212c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ jmp(&done, Label::kNear); 5213c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5214c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Heap number 5215c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&heap_number); 5216528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ movsd(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5217528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg); 5218c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ jmp(&done, Label::kNear); 5219c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5220c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // smi 5221c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&is_smi); 5222c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ SmiToInteger32(input_reg, input_reg); 5223c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ ClampUint8(input_reg); 5224c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5225c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&done); 5226c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 5227c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5228c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 5229ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoDoubleBits(LDoubleBits* instr) { 5230ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org XMMRegister value_reg = ToDoubleRegister(instr->value()); 5231ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register result_reg = ToRegister(instr->result()); 5232ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (instr->hydrogen()->bits() == HDoubleBits::HIGH) { 5233ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ movq(result_reg, value_reg); 52342f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ shrq(result_reg, Immediate(32)); 5235ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } else { 5236ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ movd(result_reg, value_reg); 5237ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 5238ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org} 5239ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 5240ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 5241ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid LCodeGen::DoConstructDouble(LConstructDouble* instr) { 5242ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register hi_reg = ToRegister(instr->hi()); 5243ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Register lo_reg = ToRegister(instr->lo()); 5244ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org XMMRegister result_reg = ToDoubleRegister(instr->result()); 5245ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org XMMRegister xmm_scratch = double_scratch0(); 5246ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ movd(result_reg, hi_reg); 5247ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ psllq(result_reg, 32); 5248ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ movd(xmm_scratch, lo_reg); 5249ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org __ orps(result_reg, xmm_scratch); 5250ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org} 5251ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 5252ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 525394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::DoAllocate(LAllocate* instr) { 525432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org class DeferredAllocate V8_FINAL : public LDeferredCode { 525594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org public: 525694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org DeferredAllocate(LCodeGen* codegen, LAllocate* instr) 525794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org : LDeferredCode(codegen), instr_(instr) { } 525832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual void Generate() V8_OVERRIDE { 525932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org codegen()->DoDeferredAllocate(instr_); 526032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org } 526132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 526294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org private: 526394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org LAllocate* instr_; 526494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org }; 526594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 526694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org DeferredAllocate* deferred = 526794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org new(zone()) DeferredAllocate(this, instr); 526894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 526994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register result = ToRegister(instr->result()); 527094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register temp = ToRegister(instr->temp()); 527194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 527271fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org // Allocate memory for the object. 527371fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org AllocationFlags flags = TAG_OBJECT; 527471fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org if (instr->hydrogen()->MustAllocateDoubleAligned()) { 527571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); 527671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org } 5277d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { 5278d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5279d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5280e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE); 5281d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5282d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5283c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE); 5284e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5285c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 528671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org if (instr->size()->IsConstantOperand()) { 528771fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 52886b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org if (size <= Page::kMaxRegularHeapObjectSize) { 52896b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); 52906b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org } else { 52916b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org __ jmp(deferred->entry()); 52926b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org } 529394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } else { 529471fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org Register size = ToRegister(instr->size()); 5295f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); 529694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 529794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 529894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ bind(deferred->exit()); 5299c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 5300c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (instr->hydrogen()->MustPrefillWithFiller()) { 5301c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (instr->size()->IsConstantOperand()) { 5302c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5303c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ movl(temp, Immediate((size / kPointerSize) - 1)); 5304c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } else { 5305c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org temp = ToRegister(instr->size()); 53062f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ sarp(temp, Immediate(kPointerSizeLog2)); 5307c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ decl(temp); 5308c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 5309c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Label loop; 5310c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ bind(&loop); 5311c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ Move(FieldOperand(result, temp, times_pointer_size, 0), 5312c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org isolate()->factory()->one_pointer_filler_map()); 5313c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ decl(temp); 5314c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org __ j(not_zero, &loop); 5315c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 531694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 531794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 531894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 531994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::DoDeferredAllocate(LAllocate* instr) { 532094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register result = ToRegister(instr->result()); 532194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 532294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 532394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // result register contain a valid pointer because it is already 532494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // contained in the register pointer map. 5325f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ Move(result, Smi::FromInt(0)); 532694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 532794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org PushSafepointRegistersScope scope(this); 5328f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (instr->size()->IsRegister()) { 5329f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Register size = ToRegister(instr->size()); 5330f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ASSERT(!size.is(result)); 5331f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ Integer32ToSmi(size, size); 5332763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(size); 5333f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } else { 5334f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5335f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ Push(Smi::FromInt(size)); 5336f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 5337f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 5338ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org int flags = 0; 5339d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { 5340d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5341d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5342ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org flags = AllocateTargetSpace::update(flags, OLD_POINTER_SPACE); 5343d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5344d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5345ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org flags = AllocateTargetSpace::update(flags, OLD_DATA_SPACE); 5346e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 5347ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org flags = AllocateTargetSpace::update(flags, NEW_SPACE); 5348e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5349ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org __ Push(Smi::FromInt(flags)); 5350ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 5351ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org CallRuntimeFromDeferred( 5352895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Runtime::kHiddenAllocateInTargetSpace, 2, instr, instr->context()); 535394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ StoreToSafepointRegisterSlot(result, rax); 535494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 535594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 535694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 5357ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid LCodeGen::DoToFastProperties(LToFastProperties* instr) { 535856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org ASSERT(ToRegister(instr->value()).is(rax)); 5359763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 5360ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org CallRuntime(Runtime::kToFastProperties, 1, instr); 5361ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 5362ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 5363ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 5364c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 5365935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 536683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label materialized; 53673a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Registers will be used as follows: 53683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // rcx = literals array. 53693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // rbx = regexp literal. 53703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // rax = regexp literal clone. 53719c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org int literal_offset = 53729c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); 5373c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Move(rcx, instr->hydrogen()->literals()); 537443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, FieldOperand(rcx, literal_offset)); 53753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex); 537683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_equal, &materialized, Label::kNear); 53773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 53783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Create regexp literal using runtime function 53793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Result will be in rax. 5380763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rcx); 53813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Push(Smi::FromInt(instr->hydrogen()->literal_index())); 53823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Push(instr->hydrogen()->pattern()); 53833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Push(instr->hydrogen()->flags()); 5384895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4, instr); 538543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, rax); 53863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 53873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&materialized); 53883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 53893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Label allocated, runtime_allocate; 53902bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ Allocate(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT); 5391935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&allocated, Label::kNear); 53923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 53933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&runtime_allocate); 5394763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rbx); 53953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ Push(Smi::FromInt(size)); 5396895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1, instr); 5397763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rbx); 53983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 53993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&allocated); 54003a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Copy the content into the newly allocated memory. 54013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // (Unroll copy loop once for better throughput). 54023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { 540343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rbx, i)); 540443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, FieldOperand(rbx, i + kPointerSize)); 540543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, i), rdx); 540643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, i + kPointerSize), rcx); 54073a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 54083a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if ((size % (2 * kPointerSize)) != 0) { 540943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rbx, size - kPointerSize)); 541043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, size - kPointerSize), rdx); 54113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 5412c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5413c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5414c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5415c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { 5416935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 541783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // Use the fast case closure allocation code that allocates in new 541883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // space for nested functions that don't need literals cloning. 541983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org bool pretenure = instr->hydrogen()->pretenure(); 542032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org if (!pretenure && instr->hydrogen()->has_no_literals()) { 5421f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org FastNewClosureStub stub(isolate(), 5422f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org instr->hydrogen()->strict_mode(), 542332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org instr->hydrogen()->is_generator()); 5424662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ Move(rbx, instr->hydrogen()->shared_info()); 5425f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 542683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } else { 5427763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); 542832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ Push(instr->hydrogen()->shared_info()); 542932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ PushRoot(pretenure ? Heap::kTrueValueRootIndex : 543032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Heap::kFalseValueRootIndex); 5431895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org CallRuntime(Runtime::kHiddenNewClosure, 3, instr); 543283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 5433c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5434c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5435c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5436c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoTypeof(LTypeof* instr) { 5437935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 543856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org LOperand* input = instr->value(); 5439160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org EmitPushTaggedOperand(input); 54403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org CallRuntime(Runtime::kTypeof, 1, instr); 5441c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5442c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5443c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5444160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgvoid LCodeGen::EmitPushTaggedOperand(LOperand* operand) { 5445160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!operand->IsDoubleRegister()); 5446160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (operand->IsConstantOperand()) { 5447c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Push(ToHandle(LConstantOperand::cast(operand))); 5448160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else if (operand->IsRegister()) { 5449763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(ToRegister(operand)); 54503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 5451763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(ToOperand(operand)); 54523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 5453d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com} 5454d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 5455d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 5456c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 545756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register input = ToRegister(instr->value()); 5458af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Condition final_branch_condition = EmitTypeofIs(instr, input); 5459394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (final_branch_condition != no_condition) { 54601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, final_branch_condition); 5461394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 5462c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5463c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5464c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5465af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgCondition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) { 5466af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label* true_label = instr->TrueLabel(chunk_); 5467af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label* false_label = instr->FalseLabel(chunk_); 5468af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Handle<String> type_name = instr->type_literal(); 5469af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org int left_block = instr->TrueDestination(chunk_); 5470af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org int right_block = instr->FalseDestination(chunk_); 5471af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org int next_block = GetNextEmittedBlock(); 5472af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 5473af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label::Distance true_distance = left_block == next_block ? Label::kNear 5474af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org : Label::kFar; 5475af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label::Distance false_distance = right_block == next_block ? Label::kNear 5476af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org : Label::kFar; 54770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Condition final_branch_condition = no_condition; 54782ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Factory* factory = isolate()->factory(); 54792ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (String::Equals(type_name, factory->number_string())) { 5480af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfSmi(input, true_label, true_distance); 5481b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org __ CompareRoot(FieldOperand(input, HeapObject::kMapOffset), 5482b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Heap::kHeapNumberMapRootIndex); 5483b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 54840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org final_branch_condition = equal; 54850a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 54862ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(type_name, factory->string_string())) { 5487af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 54888f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); 5489af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ j(above_equal, false_label, false_distance); 54900a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ testb(FieldOperand(input, Map::kBitFieldOffset), 54910a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Immediate(1 << Map::kIsUndetectable)); 54928f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org final_branch_condition = zero; 54930a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 54942ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(type_name, factory->symbol_string())) { 5495af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 5496f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ CmpObjectType(input, SYMBOL_TYPE, input); 5497f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org final_branch_condition = equal; 5498f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 54992ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(type_name, factory->boolean_string())) { 55000a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ CompareRoot(input, Heap::kTrueValueRootIndex); 5501af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ j(equal, true_label, true_distance); 55020a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ CompareRoot(input, Heap::kFalseValueRootIndex); 55030a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org final_branch_condition = equal; 55040a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 55052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (FLAG_harmony_typeof && 55062ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org String::Equals(type_name, factory->null_string())) { 55074acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ CompareRoot(input, Heap::kNullValueRootIndex); 55084acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org final_branch_condition = equal; 55094acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 55102ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(type_name, factory->undefined_string())) { 55110a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ CompareRoot(input, Heap::kUndefinedValueRootIndex); 5512af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ j(equal, true_label, true_distance); 5513af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 55140a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Check for undetectable objects => true. 551543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(input, FieldOperand(input, HeapObject::kMapOffset)); 55160a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ testb(FieldOperand(input, Map::kBitFieldOffset), 55170a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Immediate(1 << Map::kIsUndetectable)); 55180a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org final_branch_condition = not_zero; 55190a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 55202ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(type_name, factory->function_string())) { 5521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 5522af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 5523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CmpObjectType(input, JS_FUNCTION_TYPE, input); 5524af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ j(equal, true_label, true_distance); 5525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); 5526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com final_branch_condition = equal; 55270a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 55282ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(type_name, factory->object_string())) { 5529af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 55304acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (!FLAG_harmony_typeof) { 55314acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ CompareRoot(input, Heap::kNullValueRootIndex); 5532af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ j(equal, true_label, true_distance); 55334acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 5534f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); 5535af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ j(below, false_label, false_distance); 5536d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 5537af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ j(above, false_label, false_distance); 55380a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Check for undetectable objects => false. 55390a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org __ testb(FieldOperand(input, Map::kBitFieldOffset), 55400a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Immediate(1 << Map::kIsUndetectable)); 55418f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org final_branch_condition = zero; 55420a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 55430a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 5544af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ jmp(false_label, false_distance); 55450a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 55460a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 55470a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return final_branch_condition; 5548c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5549c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5550c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 55513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 555256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Register temp = ToRegister(instr->temp()); 55533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 55543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org EmitIsConstructCall(temp); 55551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org EmitBranch(instr, equal); 55563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 55573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 55583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 55593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid LCodeGen::EmitIsConstructCall(Register temp) { 55603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Get the frame pointer for the calling frame. 556143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 55623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 55633a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Skip the arguments adaptor frame if it exists. 556483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label check_frame_marker; 5565badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ Cmp(Operand(temp, StandardFrameConstants::kContextOffset), 5566badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 556783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_equal, &check_frame_marker, Label::kNear); 556843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset)); 55693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 55703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Check the marker in the calling frame. 55713a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org __ bind(&check_frame_marker); 5572badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ Cmp(Operand(temp, StandardFrameConstants::kMarkerOffset), 5573badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Smi::FromInt(StackFrame::CONSTRUCT)); 55743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 55753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 55763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 557764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { 55785c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org if (!info()->IsStub()) { 55795c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org // Ensure that we have enough space after the previous lazy-bailout 55805c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org // instruction for patching the code here. 55815c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org int current_pc = masm()->pc_offset(); 55825c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org if (current_pc < last_lazy_deopt_pc_ + space_needed) { 55835c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 55845c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org __ Nop(padding_size); 55855c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org } 558627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org } 55875c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org last_lazy_deopt_pc_ = masm()->pc_offset(); 558827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org} 558927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org 559027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org 5591c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLazyBailout(LLazyBailout* instr) { 5592fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org last_lazy_deopt_pc_ = masm()->pc_offset(); 559327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(instr->HasEnvironment()); 559427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org LEnvironment* env = instr->environment(); 559527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 559627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 5597c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5598c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5599c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5600c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoDeoptimize(LDeoptimize* instr) { 5601c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Deoptimizer::BailoutType type = instr->hydrogen()->type(); 5602c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the 5603c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // needed return address), even though the implementation of LAZY and EAGER is 5604c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // now identical. When LAZY is eventually completely folded into EAGER, remove 5605c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // the special case below. 5606c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (info()->IsStub() && type == Deoptimizer::EAGER) { 5607c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org type = Deoptimizer::LAZY; 5608c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 5609594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 5610594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Comment(";;; deoptimize: %s", instr->hydrogen()->reason()); 5611c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org DeoptimizeIf(no_condition, instr->environment(), type); 5612c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5613c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5614c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5615935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgvoid LCodeGen::DoDummy(LDummy* instr) { 5616935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // Nothing to see here, move on! 5617935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org} 5618935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 5619935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 562046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgvoid LCodeGen::DoDummyUse(LDummyUse* instr) { 562146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org // Nothing to see here, move on! 562246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org} 562346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 562446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 562504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgvoid LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { 562627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org PushSafepointRegistersScope scope(this); 562743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 5628895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kHiddenStackGuard); 562927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0); 563027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(instr->HasEnvironment()); 563127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org LEnvironment* env = instr->environment(); 563227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 563304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org} 563404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org 563504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org 5636c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoStackCheck(LStackCheck* instr) { 563732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org class DeferredStackCheck V8_FINAL : public LDeferredCode { 563804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org public: 563904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) 564004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org : LDeferredCode(codegen), instr_(instr) { } 564132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual void Generate() V8_OVERRIDE { 564232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org codegen()->DoDeferredStackCheck(instr_); 564332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org } 564432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 564504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org private: 564604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org LStackCheck* instr_; 564704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org }; 5648c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 564927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org ASSERT(instr->HasEnvironment()); 565027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org LEnvironment* env = instr->environment(); 565127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // There is no LLazyBailout instruction for stack-checks. We have to 565227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // prepare for lazy deoptimization explicitly here. 565304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org if (instr->hydrogen()->is_function_entry()) { 565404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org // Perform stack overflow check. 565504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org Label done; 565604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ CompareRoot(rsp, Heap::kStackLimitRootIndex); 565704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ j(above_equal, &done, Label::kNear); 5658935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 5659935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(instr->context()->IsRegister()); 5660935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 5661dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org CallCode(isolate()->builtins()->StackCheck(), 5662dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org RelocInfo::CODE_TARGET, 5663dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org instr); 566404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ bind(&done); 566504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } else { 566604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org ASSERT(instr->hydrogen()->is_backwards_branch()); 566704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org // Perform stack overflow check if this goto needs it before jumping. 566804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org DeferredStackCheck* deferred_stack_check = 56697028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) DeferredStackCheck(this, instr); 567004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ CompareRoot(rsp, Heap::kStackLimitRootIndex); 567104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ j(below, deferred_stack_check->entry()); 567264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 567304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org __ bind(instr->done_label()); 567404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org deferred_stack_check->SetExit(instr->done_label()); 567527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 567627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // Don't record a deoptimization index for the safepoint here. 567727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // This will be done explicitly when emitting call and the safepoint in 567827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org // the deferred code. 567904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org } 5680c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5681c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5682c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5683c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoOsrEntry(LOsrEntry* instr) { 568449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // This is a pseudo-instruction that ensures that the environment here is 568549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // properly registered for deoptimization and records the assembler's PC 568649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // offset. 568749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org LEnvironment* environment = instr->environment(); 568849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 568949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // If the environment were already registered, we would have no way of 569049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // backpatching it with the spill slot operands. 569149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org ASSERT(!environment->HasBeenRegistered()); 569227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 56931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 5694c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org GenerateOsrPrologue(); 5695c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} 5696c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5697be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5698be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { 5699935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org ASSERT(ToRegister(instr->context()).is(rsi)); 5700be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 5701be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org DeoptimizeIf(equal, instr->environment()); 5702be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5703be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register null_value = rdi; 5704be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ LoadRoot(null_value, Heap::kNullValueRootIndex); 57057a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rax, null_value); 5706be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org DeoptimizeIf(equal, instr->environment()); 5707be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5708be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Condition cc = masm()->CheckSmi(rax); 5709be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org DeoptimizeIf(cc, instr->environment()); 5710be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5711be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 5712be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ CmpObjectType(rax, LAST_JS_PROXY_TYPE, rcx); 5713be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org DeoptimizeIf(below_equal, instr->environment()); 5714be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5715be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Label use_cache, call_runtime; 5716be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ CheckEnumCache(null_value, &call_runtime); 5717be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 571843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, FieldOperand(rax, HeapObject::kMapOffset)); 5719be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ jmp(&use_cache, Label::kNear); 5720be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5721be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Get the set of properties to enumerate. 5722be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ bind(&call_runtime); 5723763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 5724be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); 5725be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5726be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), 5727be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Heap::kMetaMapRootIndex); 5728be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5729be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ bind(&use_cache); 5730be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 5731be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5732be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5733be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { 5734be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register map = ToRegister(instr->map()); 5735be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register result = ToRegister(instr->result()); 5736355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Label load_cache, done; 5737355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ EnumLength(result, map); 5738355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ Cmp(result, Smi::FromInt(0)); 5739935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(not_equal, &load_cache, Label::kNear); 5740355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ LoadRoot(result, Heap::kEmptyFixedArrayRootIndex); 5741935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ jmp(&done, Label::kNear); 5742355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ bind(&load_cache); 5743be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ LoadInstanceDescriptors(map, result); 574443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, 5745304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FieldOperand(result, DescriptorArray::kEnumCacheOffset)); 574643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, 5747be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org FieldOperand(result, FixedArray::SizeFor(instr->idx()))); 5748355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ bind(&done); 5749be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Condition cc = masm()->CheckSmi(result); 575088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org DeoptimizeIf(cc, instr->environment()); 5751be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 5752be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5753be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5754be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { 5755be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register object = ToRegister(instr->value()); 57567a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(ToRegister(instr->map()), 5757be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org FieldOperand(object, HeapObject::kMapOffset)); 5758be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org DeoptimizeIf(not_equal, instr->environment()); 5759be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 5760be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5761be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 576263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.orgvoid LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, 576363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register object, 576463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register index) { 576563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org PushSafepointRegistersScope scope(this); 576663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ Push(object); 576763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ Push(index); 576863a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ xorp(rsi, rsi); 576963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble); 577063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org RecordSafepointWithRegisters( 577163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org instr->pointer_map(), 2, Safepoint::kNoLazyDeopt); 577263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ StoreToSafepointRegisterSlot(object, rax); 577363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org} 577463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org 577563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org 5776be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { 577763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org class DeferredLoadMutableDouble V8_FINAL : public LDeferredCode { 577863a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org public: 577963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org DeferredLoadMutableDouble(LCodeGen* codegen, 578063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org LLoadFieldByIndex* instr, 578163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register object, 578263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register index) 578363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org : LDeferredCode(codegen), 578463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org instr_(instr), 578563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org object_(object), 578663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org index_(index) { 578763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org } 578863a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org virtual void Generate() V8_OVERRIDE { 578963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org codegen()->DoDeferredLoadMutableDouble(instr_, object_, index_); 579063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org } 579163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 579263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org private: 579363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org LLoadFieldByIndex* instr_; 579463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register object_; 579563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register index_; 579663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org }; 579763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org 5798be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register object = ToRegister(instr->object()); 5799be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register index = ToRegister(instr->index()); 5800be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 580163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org DeferredLoadMutableDouble* deferred; 580263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org deferred = new(zone()) DeferredLoadMutableDouble(this, instr, object, index); 580363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org 5804be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Label out_of_object, done; 580563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ Move(kScratchRegister, Smi::FromInt(1)); 580663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ testp(index, kScratchRegister); 580763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ j(not_zero, deferred->entry()); 580863a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org 580963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ sarp(index, Immediate(1)); 581063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org 5811be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ SmiToInteger32(index, index); 5812be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ cmpl(index, Immediate(0)); 5813935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org __ j(less, &out_of_object, Label::kNear); 581443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(object, FieldOperand(object, 5815be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org index, 5816be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org times_pointer_size, 5817be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org JSObject::kHeaderSize)); 5818be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ jmp(&done, Label::kNear); 5819be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5820be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ bind(&out_of_object); 582143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(object, FieldOperand(object, JSObject::kPropertiesOffset)); 5822be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ negl(index); 5823be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Index is now equal to out of object property index plus 1. 582443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(object, FieldOperand(object, 5825be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org index, 5826be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org times_pointer_size, 5827be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org FixedArray::kHeaderSize - kPointerSize)); 582863a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org __ bind(deferred->exit()); 5829be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ bind(&done); 5830be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 5831be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5832be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 58331e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.orgvoid LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) { 58341e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Register context = ToRegister(instr->context()); 58351e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), context); 58361e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org} 58371e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org 58381e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org 58391e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.orgvoid LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) { 58401e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Handle<ScopeInfo> scope_info = instr->scope_info(); 58411e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org __ Push(scope_info); 58421e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org __ Push(ToRegister(instr->function())); 58431e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org CallRuntime(Runtime::kHiddenPushBlockContext, 2, instr); 58441e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org RecordSafepoint(Safepoint::kNoLazyDeopt); 58451e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org} 58461e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org 58471e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org 5848c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#undef __ 5849c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5850c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org} } // namespace v8::internal 5851c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 5852c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#endif // V8_TARGET_ARCH_X64 5853