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