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