1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved.
2a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Redistribution and use in source and binary forms, with or without
3a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// modification, are permitted provided that the following conditions are
4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// met:
5a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Redistributions of source code must retain the above copyright
7a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       notice, this list of conditions and the following disclaimer.
8a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Redistributions in binary form must reproduce the above
9a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       copyright notice, this list of conditions and the following
10a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       disclaimer in the documentation and/or other materials provided
11a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       with the distribution.
12a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Neither the name of Google Inc. nor the names of its
13a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       contributors may be used to endorse or promote products derived
14a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       from this software without specific prior written permission.
15a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
16a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
28c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#include "v8.h"
29c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
3093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32
31c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
32a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "ia32/lithium-codegen-ia32.h"
33a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#include "ic.h"
34a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "code-stubs.h"
357979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org#include "deoptimizer.h"
36a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "stub-cache.h"
370ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry#include "codegen.h"
38a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
39a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace v8 {
40a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace internal {
41a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
42a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
43750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgstatic SaveFPRegsMode GetSaveFPRegsMode() {
44750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // We don't need to save floating point regs when generating the snapshot
45750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return CpuFeatures::IsSafeForSnapshot(SSE2) ? kSaveFPRegs : kDontSaveFPRegs;
46750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
47750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
48750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
4931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org// When invoking builtins, we need to record the safepoint in the middle of
5031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org// the invoke instruction sequence generated by the macro assembler.
51fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.orgclass SafepointGenerator : public CallWrapper {
52a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
53a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SafepointGenerator(LCodeGen* codegen,
54a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                     LPointerMap* pointers,
5527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                     Safepoint::DeoptMode mode)
56a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      : codegen_(codegen),
57a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        pointers_(pointers),
5827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org        deopt_mode_(mode) {}
59a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  virtual ~SafepointGenerator() { }
60a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
61fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  virtual void BeforeCall(int call_size) const {}
62fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
63fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  virtual void AfterCall() const {
6427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    codegen_->RecordSafepoint(pointers_, deopt_mode_);
65a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
66a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
67a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
68a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LCodeGen* codegen_;
69a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LPointerMap* pointers_;
7027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  Safepoint::DeoptMode deopt_mode_;
71a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
72a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
73a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
74a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define __ masm()->
75a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
76a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgbool LCodeGen::GenerateCode() {
771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  LPhase phase("Z_Code generation", chunk());
78a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(is_unused());
79a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  status_ = GENERATING;
80c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
81c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Open a frame scope to indicate that there is a frame on the stack.  The
82c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // MANUAL indicates that the scope shouldn't actually generate code to set up
83c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the frame (that is done in GeneratePrologue).
84c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  FrameScope frame_scope(masm_, StackFrame::MANUAL);
85c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
8694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  support_aligned_spilled_doubles_ = info()->IsOptimizing();
8794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
88a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  dynamic_frame_alignment_ = info()->IsOptimizing() &&
89a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      ((chunk()->num_double_slots() > 2 &&
90a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        !chunk()->graph()->is_recursive()) ||
91a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org       !info()->osr_ast_id().IsNone());
927028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
93a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return GeneratePrologue() &&
94a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      GenerateBody() &&
95a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      GenerateDeferredCode() &&
96a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      GenerateJumpTable() &&
97a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      GenerateSafepointTable();
98a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
99a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::FinishCode(Handle<Code> code) {
102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(is_done());
103160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  code->set_stack_slots(GetStackSlotCount());
10483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
1056ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  if (FLAG_weak_embedded_maps_in_optimized_code) {
1066ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org    RegisterDependentCodeForEmbeddedMaps(code);
1076ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  }
108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  PopulateDeoptimizationData(code);
109a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (!info()->IsStub()) {
110a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
111a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
1121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  info()->CommitDependencies(code);
113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
116594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::Abort(BailoutReason reason) {
11746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  info()->set_bailout_reason(reason);
118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  status_ = ABORTED;
119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
122a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::Comment(const char* format, ...) {
123a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (!FLAG_code_comments) return;
124a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  char buffer[4 * KB];
125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  StringBuilder builder(buffer, ARRAY_SIZE(buffer));
126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  va_list arguments;
127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  va_start(arguments, format);
128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  builder.AddFormattedList(format, arguments);
129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  va_end(arguments);
130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
131a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Copy the string before recording it in the assembler to avoid
132a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // issues when the stack allocated buffer goes out of scope.
133a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  size_t length = builder.position();
134a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Vector<char> copy = Vector<char>::New(length + 1);
135e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  OS::MemCopy(copy.start(), builder.Finalize(), copy.length());
136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  masm()->RecordComment(copy.start());
137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
140d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#ifdef _MSC_VER
141d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid LCodeGen::MakeSureStackPagesMapped(int offset) {
142d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  const int kPageSize = 4 * KB;
143d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  for (offset -= kPageSize; offset > 0; offset -= kPageSize) {
144d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    __ mov(Operand(esp, offset), eax);
145d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
146d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
147d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#endif
148d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
149d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
150a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgbool LCodeGen::GeneratePrologue() {
151a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(is_generating());
152a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
153a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (info()->IsOptimizing()) {
154a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ProfileEntryHookStub::MaybeCallEntryHook(masm_);
155753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
156a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
157a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (strlen(FLAG_stop_at) > 0 &&
15859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
159a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ int3();
160a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
161a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
162a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
163a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // Strict mode functions and builtins need to replace the receiver
164a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // with undefined when called as functions (without an explicit
165a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // receiver object). ecx is zero for method calls and non-zero for
166a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // function calls.
167a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (!info_->is_classic_mode() || info_->is_native()) {
168a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      Label ok;
169a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ test(ecx, Operand(ecx));
170a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ j(zero, &ok, Label::kNear);
171a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      // +1 for return address.
172a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize;
173a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ mov(Operand(esp, receiver_offset),
174a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org             Immediate(isolate()->factory()->undefined_value()));
175a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ bind(&ok);
176a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
1775323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org
17894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) {
179a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      // Move state of dynamic frame alignment into edx.
180a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ mov(edx, Immediate(kNoAlignmentPadding));
181a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
182a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      Label do_not_pad, align_loop;
183a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      STATIC_ASSERT(kDoubleSize == 2 * kPointerSize);
184a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      // Align esp + 4 to a multiple of 2 * kPointerSize.
185a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ test(esp, Immediate(kPointerSize));
186a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ j(not_zero, &do_not_pad, Label::kNear);
187a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ push(Immediate(0));
188a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ mov(ebx, esp);
189a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ mov(edx, Immediate(kAlignmentPaddingPushed));
190a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      // Copy arguments, receiver, and return address.
191a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ mov(ecx, Immediate(scope()->num_parameters() + 2));
192a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
193a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ bind(&align_loop);
194a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ mov(eax, Operand(ebx, 1 * kPointerSize));
195a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ mov(Operand(ebx, 0), eax);
196a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ add(Operand(ebx), Immediate(kPointerSize));
197a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ dec(ecx);
198a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ j(not_zero, &align_loop, Label::kNear);
199a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue));
200a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ bind(&do_not_pad);
201a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
2027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
2037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
20483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  info()->set_prologue_offset(masm_->pc_offset());
205a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (NeedsEagerFrame()) {
206a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ASSERT(!frame_is_built_);
207a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    frame_is_built_ = true;
208a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    __ push(ebp);  // Caller's frame pointer.
209a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    __ mov(ebp, esp);
2104e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    info()->AddNoFrameRange(0, masm_->pc_offset());
211a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    __ push(esi);  // Callee's context.
212a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (info()->IsStub()) {
213a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ push(Immediate(Smi::FromInt(StackFrame::STUB)));
214a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    } else {
215a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ push(edi);  // Callee's JS function.
216a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
217a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
219a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (info()->IsOptimizing() &&
220a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      dynamic_frame_alignment_ &&
221a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      FLAG_debug_code) {
2227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    __ test(esp, Immediate(kPointerSize));
223594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Assert(zero, kFrameIsExpectedToBeAligned);
2247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
2257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Reserve space for the stack slots needed by the code.
227160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  int slots = GetStackSlotCount();
228a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(slots != 0 || !info()->IsOptimizing());
229a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (slots > 0) {
230a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (slots == 1) {
231a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      if (dynamic_frame_alignment_) {
232a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        __ push(edx);
233a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      } else {
234a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        __ push(Immediate(kNoAlignmentPadding));
235a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      }
2365323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    } else {
237a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      if (FLAG_debug_code) {
23894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        __ sub(Operand(esp), Immediate(slots * kPointerSize));
239d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#ifdef _MSC_VER
240d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        MakeSureStackPagesMapped(slots * kPointerSize);
241d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#endif
24294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        __ push(eax);
243a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        __ mov(Operand(eax), Immediate(slots));
244a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        Label loop;
245a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        __ bind(&loop);
24694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        __ mov(MemOperand(esp, eax, times_4, 0),
24794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org               Immediate(kSlotsZapValue));
248a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        __ dec(eax);
249a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        __ j(not_zero, &loop);
25094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        __ pop(eax);
251a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      } else {
252a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        __ sub(Operand(esp), Immediate(slots * kPointerSize));
253a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#ifdef _MSC_VER
254d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        MakeSureStackPagesMapped(slots * kPointerSize);
255a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#endif
256c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      }
2577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
25894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      if (support_aligned_spilled_doubles_) {
25994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        Comment(";;; Store dynamic frame alignment tag for spilled doubles");
26094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        // Store dynamic frame alignment state in the first local.
26194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        int offset = JavaScriptFrameConstants::kDynamicAlignmentStateOffset;
26294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        if (dynamic_frame_alignment_) {
26394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org          __ mov(Operand(ebp, offset), edx);
26494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        } else {
26594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org          __ mov(Operand(ebp, offset), Immediate(kNoAlignmentPadding));
26694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        }
26794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      }
26894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    }
26994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
27094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) {
27194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      Comment(";;; Save clobbered callee double registers");
272750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      CpuFeatureScope scope(masm(), SSE2);
27394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      int count = 0;
27494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      BitVector* doubles = chunk()->allocated_double_registers();
27594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      BitVector::Iterator save_iterator(doubles);
27694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      while (!save_iterator.Done()) {
27794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        __ movdbl(MemOperand(esp, count * kDoubleSize),
27894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                  XMMRegister::FromAllocationIndex(save_iterator.Current()));
27994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        save_iterator.Advance();
28094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        count++;
281a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      }
282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Possibly allocate a local context.
286a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
2873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if (heap_slots > 0) {
2883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    Comment(";;; Allocate local context");
2893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Argument to NewContext is the function, which is still in edi.
2903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    __ push(edi);
2913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    if (heap_slots <= FastNewContextStub::kMaximumSlots) {
2923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      FastNewContextStub stub(heap_slots);
2933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      __ CallStub(&stub);
2943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    } else {
2956d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      __ CallRuntime(Runtime::kNewFunctionContext, 1);
2963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
29727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    RecordSafepoint(Safepoint::kNoLazyDeopt);
2983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Context is returned in both eax and esi.  It replaces the context
2993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // passed to us.  It's saved in the stack and kept live in esi.
3003a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi);
3013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
3023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Copy parameters into context if necessary.
3033a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    int num_parameters = scope()->num_parameters();
3043a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    for (int i = 0; i < num_parameters; i++) {
305486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      Variable* var = scope()->parameter(i);
306486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      if (var->IsContextSlot()) {
3073a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org        int parameter_offset = StandardFrameConstants::kCallerSPOffset +
3083a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org            (num_parameters - 1 - i) * kPointerSize;
3093a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org        // Load parameter from stack.
3103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org        __ mov(eax, Operand(ebp, parameter_offset));
3113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org        // Store it in the context.
312486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        int context_offset = Context::SlotOffset(var->index());
3133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org        __ mov(Operand(esi, context_offset), eax);
314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Update the write barrier. This clobbers eax and ebx.
315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ RecordWriteContextSlot(esi,
316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  context_offset,
317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  eax,
318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  ebx,
319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  kDontSaveFPRegs);
3203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      }
3213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
3223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    Comment(";;; End allocate local context");
3233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
3243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
325a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Trace the call.
326a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (FLAG_trace && info()->IsOptimizing()) {
327496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    // We have not executed any compiled code yet, so esi still holds the
328496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    // incoming context.
329a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ CallRuntime(Runtime::kTraceEnter, 0);
330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return !is_aborted();
332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
333a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
334a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
335a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgbool LCodeGen::GenerateBody() {
336a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(is_generating());
337a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool emit_instructions = true;
338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (current_instruction_ = 0;
339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org       !is_aborted() && current_instruction_ < instructions_->length();
340a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org       current_instruction_++) {
341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    LInstruction* instr = instructions_->at(current_instruction_);
34232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
34332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    // Don't emit code for basic blocks with a replacement.
344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (instr->IsLabel()) {
34532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      emit_instructions = !LLabel::cast(instr)->HasReplacement();
346a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
34732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    if (!emit_instructions) continue;
348a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
34932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    if (FLAG_code_comments && instr->HasInterestingComment(this)) {
35032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      Comment(";;; <@%d,#%d> %s",
35132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              current_instruction_,
35232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              instr->hydrogen_value()->id(),
35332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              instr->Mnemonic());
35432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    }
355e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
35632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr);
357e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
358594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    RecordAndUpdatePosition(instr->position());
359594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
36032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    instr->CompileToNative(this);
361e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
36232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    if (!CpuFeatures::IsSupported(SSE2)) {
36332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
36432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org        __ VerifyX87StackDepth(x87_stack_depth_);
365e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      }
366a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
367a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
36827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  EnsureSpaceForLazyDeopt();
369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return !is_aborted();
370a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
373a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool LCodeGen::GenerateJumpTable() {
374169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Label needs_frame;
37532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (jump_table_.length() > 0) {
37632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    Comment(";;; -------------------- Jump table --------------------");
37732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  }
378a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  for (int i = 0; i < jump_table_.length(); i++) {
379a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    __ bind(&jump_table_[i].label);
380a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Address entry = jump_table_[i].address;
381aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org    Deoptimizer::BailoutType type = jump_table_[i].bailout_type;
382876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type);
383068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    if (id == Deoptimizer::kNotDeoptimizationEntry) {
384068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      Comment(";;; jump table entry %d.", i);
385068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    } else {
386068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id);
387068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    }
388a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (jump_table_[i].needs_frame) {
389a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ push(Immediate(ExternalReference::ForDeoptEntry(entry)));
390169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      if (needs_frame.is_bound()) {
391169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ jmp(&needs_frame);
392a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      } else {
393169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ bind(&needs_frame);
394169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ push(MemOperand(ebp, StandardFrameConstants::kContextOffset));
395169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // This variant of deopt can only be used with stubs. Since we don't
396169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // have a function pointer to install in the stack frame that we're
397169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // building, install a special marker there instead.
398169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        ASSERT(info()->IsStub());
399169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ push(Immediate(Smi::FromInt(StackFrame::STUB)));
400169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // Push a PC inside the function so that the deopt code can find where
401169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // the deopt comes from. It doesn't have to be the precise return
402169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // address of a "calling" LAZY deopt, it only has to be somewhere
403169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // inside the code body.
404169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        Label push_approx_pc;
405169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ call(&push_approx_pc);
406169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ bind(&push_approx_pc);
407169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // Push the continuation which was stashed were the ebp should
408169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // be. Replace it with the saved ebp.
409169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ push(MemOperand(esp, 3 * kPointerSize));
410169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ mov(MemOperand(esp, 4 * kPointerSize), ebp);
411169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ lea(ebp, MemOperand(esp, 4 * kPointerSize));
412169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ ret(0);  // Call the continuation without clobbering registers.
413a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      }
414a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    } else {
415169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      __ call(entry, RelocInfo::RUNTIME_ENTRY);
416a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
417a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
418a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return !is_aborted();
419a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
420a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
421a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
422a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgbool LCodeGen::GenerateDeferredCode() {
423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(is_generating());
424ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  if (deferred_.length() > 0) {
425ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
426ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      LDeferredCode* code = deferred_[i];
427594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
428594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      int pos = instructions_->at(code->instruction_index())->position();
429594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      RecordAndUpdatePosition(pos);
430594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
43132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      Comment(";;; <@%d,#%d> "
43232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              "-------------------- Deferred %s --------------------",
43332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              code->instruction_index(),
43432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              code->instr()->hydrogen_value()->id(),
43532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              code->instr()->Mnemonic());
436ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      __ bind(code->entry());
437a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      if (NeedsDeferredFrame()) {
43832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org        Comment(";;; Build frame");
439a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        ASSERT(!frame_is_built_);
440a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        ASSERT(info()->IsStub());
441a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        frame_is_built_ = true;
442a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        // Build the frame in such a way that esi isn't trashed.
443a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        __ push(ebp);  // Caller's frame pointer.
444a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        __ push(Operand(ebp, StandardFrameConstants::kContextOffset));
445a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        __ push(Immediate(Smi::FromInt(StackFrame::STUB)));
446a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        __ lea(ebp, Operand(esp, 2 * kPointerSize));
44732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org        Comment(";;; Deferred code");
448a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      }
449ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      code->Generate();
450a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      if (NeedsDeferredFrame()) {
45132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org        Comment(";;; Destroy frame");
452a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        ASSERT(frame_is_built_);
453a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        frame_is_built_ = false;
454a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        __ mov(esp, ebp);
455a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        __ pop(ebp);
456a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      }
457ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      __ jmp(code->exit());
458ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    }
459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Deferred code is the last part of the instruction sequence. Mark
462a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // the generated code as done unless we bailed out.
463a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (!is_aborted()) status_ = DONE;
464a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return !is_aborted();
465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
467a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
468a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgbool LCodeGen::GenerateSafepointTable() {
469a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(is_done());
470a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (!info()->IsStub()) {
471a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // For lazy deoptimization we need space to patch a call after every call.
472a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // Ensure there is always space for such patching, even if the code ends
473a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // in a call.
474a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    int target_offset = masm()->pc_offset() + Deoptimizer::patch_size();
475a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    while (masm()->pc_offset() < target_offset) {
476a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      masm()->nop();
477a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
478a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
479160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  safepoints_.Emit(masm(), GetStackSlotCount());
480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return !is_aborted();
481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgRegister LCodeGen::ToRegister(int index) const {
485a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return Register::FromAllocationIndex(index);
486a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
489169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgX87Register LCodeGen::ToX87Register(int index) const {
490169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  return X87Register::FromAllocationIndex(index);
491169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
492169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
493169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgXMMRegister LCodeGen::ToDoubleRegister(int index) const {
495a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return XMMRegister::FromAllocationIndex(index);
496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
499169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87LoadForUsage(X87Register reg) {
500169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(X87StackContains(reg));
501169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  X87Fxch(reg);
502169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  x87_stack_depth_--;
503a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
504a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
505a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
506169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87Fxch(X87Register reg, int other_slot) {
507169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(X87StackContains(reg) && x87_stack_depth_ > other_slot);
508169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int i  = X87ArrayIndex(reg);
509169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int st = x87_st2idx(i);
510169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (st != other_slot) {
511169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    int other_i = x87_st2idx(other_slot);
512169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    X87Register other   = x87_stack_[other_i];
513169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    x87_stack_[other_i] = reg;
514169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    x87_stack_[i]       = other;
515169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    if (st == 0) {
516169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      __ fxch(other_slot);
517169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    } else if (other_slot == 0) {
518169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      __ fxch(st);
519169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    } else {
520169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      __ fxch(st);
521169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      __ fxch(other_slot);
522169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      __ fxch(st);
523169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    }
524169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
525e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
526e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
527e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
528169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgint LCodeGen::x87_st2idx(int pos) {
529169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  return x87_stack_depth_ - pos - 1;
530e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
531e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
532e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
533169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgint LCodeGen::X87ArrayIndex(X87Register reg) {
534169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  for (int i = 0; i < x87_stack_depth_; i++) {
535169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    if (x87_stack_[i].is(reg)) return i;
536169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
537169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  UNREACHABLE();
538169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  return -1;
539169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
540169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
541169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
542169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgbool LCodeGen::X87StackContains(X87Register reg) {
543169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  for (int i = 0; i < x87_stack_depth_; i++) {
544169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    if (x87_stack_[i].is(reg)) return true;
545169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
546169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  return false;
547e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
548e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
549e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
550169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87Free(X87Register reg) {
551169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(X87StackContains(reg));
552169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int i  = X87ArrayIndex(reg);
553169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int st = x87_st2idx(i);
554169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (st > 0) {
555169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    // keep track of how fstp(i) changes the order of elements
556169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    int tos_i = x87_st2idx(0);
557169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    x87_stack_[i] = x87_stack_[tos_i];
558169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
559e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  x87_stack_depth_--;
560169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  __ fstp(st);
561169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
562169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
563169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
564169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87Mov(X87Register dst, Operand src, X87OperandType opts) {
565169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (X87StackContains(dst)) {
566169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    X87Fxch(dst);
567169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ fstp(0);
568169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  } else {
569169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    ASSERT(x87_stack_depth_ < X87Register::kNumAllocatableRegisters);
570169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    x87_stack_[x87_stack_depth_] = dst;
571169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    x87_stack_depth_++;
572169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
573169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  X87Fld(src, opts);
574e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
575e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
576e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
577169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87Fld(Operand src, X87OperandType opts) {
578169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (opts == kX87DoubleOperand) {
579169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ fld_d(src);
580169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  } else if (opts == kX87FloatOperand) {
581169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ fld_s(src);
582169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  } else if (opts == kX87IntOperand) {
583169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ fild_s(src);
584169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  } else {
585169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    UNREACHABLE();
586e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
587e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
588e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
589e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
590169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87Mov(Operand dst, X87Register src) {
591169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  X87Fxch(src);
592169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  __ fst_d(dst);
593169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
594169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
595169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
596169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87PrepareToWrite(X87Register reg) {
597169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (X87StackContains(reg)) {
598169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    X87Free(reg);
599169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
600169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Mark this register as the next register to write to
601169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  x87_stack_[x87_stack_depth_] = reg;
602169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
603169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
604169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
605169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87CommitWrite(X87Register reg) {
606169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Assert the reg is prepared to write, but not on the virtual stack yet
607169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!X87StackContains(reg) && x87_stack_[x87_stack_depth_].is(reg) &&
608169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      x87_stack_depth_ < X87Register::kNumAllocatableRegisters);
609169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  x87_stack_depth_++;
610169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
611169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
612169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
613169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::X87PrepareBinaryOp(
614169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    X87Register left, X87Register right, X87Register result) {
615169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // You need to use DefineSameAsFirst for x87 instructions
616169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(result.is(left));
617169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  X87Fxch(right, 1);
618169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  X87Fxch(left);
619169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
620169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
621169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
622e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::FlushX87StackIfNecessary(LInstruction* instr) {
623169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (x87_stack_depth_ > 0 && instr->ClobbersDoubleRegisters()) {
624169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    bool double_inputs = instr->HasDoubleRegisterInput();
625169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
626169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    // Flush stack from tos down, since FreeX87() will mess with tos
627169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    for (int i = x87_stack_depth_-1; i >= 0; i--) {
628169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      X87Register reg = x87_stack_[i];
629169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      // Skip registers which contain the inputs for the next instruction
630169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      // when flushing the stack
631169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      if (double_inputs && instr->IsDoubleInput(reg, this)) {
632169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        continue;
633169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      }
634169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      X87Free(reg);
635169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      if (i < x87_stack_depth_-1) i++;
636e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
637e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
638169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (instr->IsReturn()) {
639169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    while (x87_stack_depth_ > 0) {
640169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      __ fstp(0);
641169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      x87_stack_depth_--;
642169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    }
643169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
644169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
645169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
646169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
647169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid LCodeGen::EmitFlushX87ForDeopt() {
648169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  for (int i = 0; i < x87_stack_depth_; i++) __ fstp(0);
649e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
650e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
651e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
652a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgRegister LCodeGen::ToRegister(LOperand* op) const {
653a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(op->IsRegister());
654a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return ToRegister(op->index());
655a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
656a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
657a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
658169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgX87Register LCodeGen::ToX87Register(LOperand* op) const {
659169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(op->IsDoubleRegister());
660169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  return ToX87Register(op->index());
661169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
662169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
663169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
664a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgXMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
665a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(op->IsDoubleRegister());
666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return ToDoubleRegister(op->index());
667a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
668a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
669a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
670fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgint32_t LCodeGen::ToInteger32(LConstantOperand* op) const {
671fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  return ToRepresentation(op, Representation::Integer32());
672fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org}
673fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
674fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
675fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgint32_t LCodeGen::ToRepresentation(LConstantOperand* op,
676fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                                   const Representation& r) const {
677657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  HConstant* constant = chunk_->LookupConstant(op);
678fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  int32_t value = constant->Integer32Value();
679fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (r.IsInteger32()) return value;
680fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  ASSERT(r.IsSmiOrTagged());
681fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  return reinterpret_cast<int32_t>(Smi::FromInt(value));
682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
683a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
684a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
68564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgHandle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
686657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  HConstant* constant = chunk_->LookupConstant(op);
687a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
688657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return constant->handle();
68964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org}
69064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
69164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
692394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comdouble LCodeGen::ToDouble(LConstantOperand* op) const {
693657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  HConstant* constant = chunk_->LookupConstant(op);
694657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  ASSERT(constant->HasDoubleValue());
695657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return constant->DoubleValue();
696394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
697394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
698394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
699d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgExternalReference LCodeGen::ToExternalReference(LConstantOperand* op) const {
700d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HConstant* constant = chunk_->LookupConstant(op);
701d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ASSERT(constant->HasExternalReferenceValue());
702d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  return constant->ExternalReferenceValue();
703d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
704d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
705d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
706bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.orgbool LCodeGen::IsInteger32(LConstantOperand* op) const {
70753ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32();
708a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
710a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
711a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgbool LCodeGen::IsSmi(LConstantOperand* op) const {
712a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  return chunk_->LookupLiteralRepresentation(op).IsSmi();
713a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org}
714a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
715a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
716a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgOperand LCodeGen::ToOperand(LOperand* op) const {
717a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (op->IsRegister()) return Operand(ToRegister(op));
718a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (op->IsDoubleRegister()) return Operand(ToDoubleRegister(op));
719a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot());
720ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org  return Operand(ebp, StackSlotOffset(op->index()));
721a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
722a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
723a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comOperand LCodeGen::HighOperand(LOperand* op) {
7250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  ASSERT(op->IsDoubleStackSlot());
726ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org  return Operand(ebp, StackSlotOffset(op->index()) + kPointerSize);
7270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com}
7280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
7290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
730c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::WriteTranslation(LEnvironment* environment,
731b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                Translation* translation) {
732c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  if (environment == NULL) return;
733c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
734c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // The translation includes one command per value in the environment.
735b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  int translation_size = environment->translation_size();
736c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // The output frame height does not include the parameters.
737c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  int height = translation_size - environment->parameter_count();
738c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
739b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  WriteTranslation(environment->outer(), translation);
740a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool has_closure_id = !info()->closure().is_null() &&
74132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      !info()->closure().is_identical_to(environment->closure());
742a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int closure_id = has_closure_id
7435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      ? DefineDeoptimizationLiteral(environment->closure())
7445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      : Translation::kSelfLiteralId;
745967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  switch (environment->frame_type()) {
746967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    case JS_FUNCTION:
747967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      translation->BeginJSFrame(environment->ast_id(), closure_id, height);
748967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      break;
749967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    case JS_CONSTRUCT:
750967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      translation->BeginConstructStubFrame(closure_id, translation_size);
751967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      break;
752de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    case JS_GETTER:
753de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      ASSERT(translation_size == 1);
754de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      ASSERT(height == 0);
755de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      translation->BeginGetterStubFrame(closure_id);
756de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      break;
757471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    case JS_SETTER:
75846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      ASSERT(translation_size == 2);
75946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      ASSERT(height == 0);
76046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      translation->BeginSetterStubFrame(closure_id);
761471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      break;
762967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    case ARGUMENTS_ADAPTOR:
763967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
764967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      break;
765a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    case STUB:
766a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      translation->BeginCompiledStubFrame();
767a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      break;
768a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    default:
769a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      UNREACHABLE();
770659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
77156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
772594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int object_index = 0;
773594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int dematerialized_index = 0;
774c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  for (int i = 0; i < translation_size; ++i) {
775c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    LOperand* value = environment->values()->at(i);
776594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    AddToTranslation(environment,
777594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                     translation,
77846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                     value,
77946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                     environment->HasTaggedValueAt(i),
780594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                     environment->HasUint32ValueAt(i),
781594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                     &object_index,
782594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                     &dematerialized_index);
783c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  }
784c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org}
785c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
786c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
787594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::AddToTranslation(LEnvironment* environment,
788594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                Translation* translation,
789a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                LOperand* op,
79046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                                bool is_tagged,
791594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                bool is_uint32,
792594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                int* object_index_pointer,
793594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                int* dematerialized_index_pointer) {
794594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (op == LEnvironment::materialization_marker()) {
795594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int object_index = (*object_index_pointer)++;
796594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (environment->ObjectIsDuplicateAt(object_index)) {
797594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      int dupe_of = environment->ObjectDuplicateOfAt(object_index);
798594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      translation->DuplicateObject(dupe_of);
799594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return;
800594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
801594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int object_length = environment->ObjectLengthAt(object_index);
802594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (environment->ObjectIsArgumentsAt(object_index)) {
803594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      translation->BeginArgumentsObject(object_length);
804594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    } else {
805594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      translation->BeginCapturedObject(object_length);
806594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
807594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int dematerialized_index = *dematerialized_index_pointer;
808594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int env_offset = environment->translation_size() + dematerialized_index;
809594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    *dematerialized_index_pointer += object_length;
810594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    for (int i = 0; i < object_length; ++i) {
811594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      LOperand* value = environment->values()->at(env_offset + i);
812594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      AddToTranslation(environment,
813594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       translation,
814594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       value,
815594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       environment->HasTaggedValueAt(env_offset + i),
816594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       environment->HasUint32ValueAt(env_offset + i),
817594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       object_index_pointer,
818594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       dematerialized_index_pointer);
819594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
820594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return;
821594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
822594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
823b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  if (op->IsStackSlot()) {
824a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (is_tagged) {
825a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      translation->StoreStackSlot(op->index());
82646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    } else if (is_uint32) {
82746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      translation->StoreUint32StackSlot(op->index());
828a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      translation->StoreInt32StackSlot(op->index());
830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (op->IsDoubleStackSlot()) {
832a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    translation->StoreDoubleStackSlot(op->index());
833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (op->IsArgument()) {
834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(is_tagged);
835160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    int src_index = GetStackSlotCount() + op->index();
836a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    translation->StoreStackSlot(src_index);
837a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (op->IsRegister()) {
838a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Register reg = ToRegister(op);
839a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (is_tagged) {
840a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      translation->StoreRegister(reg);
84146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    } else if (is_uint32) {
84246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      translation->StoreUint32Register(reg);
843a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
844a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      translation->StoreInt32Register(reg);
845a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
846a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (op->IsDoubleRegister()) {
847a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    XMMRegister reg = ToDoubleRegister(op);
848a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    translation->StoreDoubleRegister(reg);
849a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (op->IsConstantOperand()) {
850657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op));
851657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    int src_index = DefineDeoptimizationLiteral(constant->handle());
852a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    translation->StoreLiteral(src_index);
853a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
854a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    UNREACHABLE();
855a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
856a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
857a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
858a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
85944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid LCodeGen::CallCodeGeneric(Handle<Code> code,
86044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                               RelocInfo::Mode mode,
86144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                               LInstruction* instr,
86244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                               SafepointMode safepoint_mode) {
86331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  ASSERT(instr != NULL);
86431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  LPointerMap* pointers = instr->pointer_map();
86531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  RecordPosition(pointers->position());
86631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  __ call(code, mode);
86727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  RecordSafepointWithLazyDeopt(instr, safepoint_mode);
8685f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
8695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Signal that we don't inline smi code before these stubs in the
8705f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // optimizing code generator.
87140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  if (code->kind() == Code::BINARY_OP_IC ||
8725f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      code->kind() == Code::COMPARE_IC) {
8735f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    __ nop();
8745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  }
875a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
876a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
877a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
87844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgvoid LCodeGen::CallCode(Handle<Code> code,
87944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                        RelocInfo::Mode mode,
880ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org                        LInstruction* instr) {
881ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
88244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org}
88344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
88444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
885ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid LCodeGen::CallRuntime(const Runtime::Function* fun,
886496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org                           int argc,
887ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org                           LInstruction* instr) {
888a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(instr != NULL);
88931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  ASSERT(instr->HasPointerMap());
890a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LPointerMap* pointers = instr->pointer_map();
891a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  RecordPosition(pointers->position());
892a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
893496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  __ CallRuntime(fun, argc);
8947979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
89527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
896a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
897a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(info()->is_calling());
898a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
899a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
900a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
90194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::LoadContextFromDeferred(LOperand* context) {
902ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  if (context->IsRegister()) {
903ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    if (!ToRegister(context).is(esi)) {
904ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      __ mov(esi, ToRegister(context));
905ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    }
906c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else if (context->IsStackSlot()) {
907ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    __ mov(esi, ToOperand(context));
908c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else if (context->IsConstantOperand()) {
909657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    HConstant* constant =
910657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org        chunk_->LookupConstant(LConstantOperand::cast(context));
911594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ LoadObject(esi, Handle<Object>::cast(constant->handle()));
912c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
913c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    UNREACHABLE();
914ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  }
91594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
91694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
91794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
91894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                                       int argc,
91994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                                       LInstruction* instr,
92094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                                       LOperand* context) {
92194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  LoadContextFromDeferred(context);
922ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org
92344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  __ CallRuntimeSaveDoubles(id);
92444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  RecordSafepointWithRegisters(
92527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
926a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
927a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(info()->is_calling());
92844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org}
92944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
93044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
93127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::RegisterEnvironmentForDeoptimization(
93227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    LEnvironment* environment, Safepoint::DeoptMode mode) {
933a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (!environment->HasBeenRegistered()) {
934a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Physical stack frame layout:
935a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // -x ............. -4  0 ..................................... y
936a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // [incoming arguments] [spill slots] [pushed outgoing arguments]
937a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
938a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Layout of the environment:
939a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // 0 ..................................................... size-1
940a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // [parameters] [locals] [expression stack including arguments]
941a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
942a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Layout of the translation:
943a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // 0 ........................................................ size - 1 + 4
944a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // [expression stack including arguments] [locals] [4 words] [parameters]
945a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // |>------------  translation_size ------------<|
946a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
947a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    int frame_count = 0;
948659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    int jsframe_count = 0;
949a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
950a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ++frame_count;
951967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      if (e->frame_type() == JS_FUNCTION) {
952659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        ++jsframe_count;
953659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      }
954a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
95556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    Translation translation(&translations_, frame_count, jsframe_count, zone());
956b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    WriteTranslation(environment, &translation);
957a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    int deoptimization_index = deoptimizations_.length();
95827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    int pc_offset = masm()->pc_offset();
95927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    environment->Register(deoptimization_index,
96027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                          translation.index(),
96127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                          (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
9627028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    deoptimizations_.Add(environment, zone());
963a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
964a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
965a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
966a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
967aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.orgvoid LCodeGen::DeoptimizeIf(Condition cc,
968aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org                            LEnvironment* environment,
969aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org                            Deoptimizer::BailoutType bailout_type) {
97027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
971a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(environment->HasBeenRegistered());
972a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int id = environment->deoptimization_index();
973a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(info()->IsOptimizing() || info()->IsStub());
9748432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Address entry =
9758432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
976a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (entry == NULL) {
977594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Abort(kBailoutWasNotPrepared);
978a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return;
979a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
980a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
981e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (FLAG_deopt_every_n_times != 0 && !info()->IsStub()) {
982ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    ExternalReference count = ExternalReference::stress_deopt_count(isolate());
983a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Label no_deopt;
984a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ pushfd();
985a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ push(eax);
986ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    __ mov(eax, Operand::StaticVariable(count));
987ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    __ sub(eax, Immediate(1));
98883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    __ j(not_zero, &no_deopt, Label::kNear);
989a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (FLAG_trap_on_deopt) __ int3();
990ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    __ mov(eax, Immediate(FLAG_deopt_every_n_times));
991ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    __ mov(Operand::StaticVariable(count), eax);
992a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ pop(eax);
993a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ popfd();
99410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    ASSERT(frame_is_built_);
99510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    __ call(entry, RelocInfo::RUNTIME_ENTRY);
996a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ bind(&no_deopt);
997ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    __ mov(Operand::StaticVariable(count), eax);
998a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ pop(eax);
999a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ popfd();
1000a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1001a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1002169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // Before Instructions which can deopt, we normally flush the x87 stack. But
1003169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // we can have inputs or outputs of the current instruction on the stack,
1004169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // thus we need to flush them here from the physical stack to leave it in a
1005169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // consistent state.
1006169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (x87_stack_depth_ > 0) {
1007169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    Label done;
1008169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear);
1009169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    EmitFlushX87ForDeopt();
1010169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ bind(&done);
1011169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
1012169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1013594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (info()->ShouldTrapOnDeopt()) {
10147c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    Label done;
1015169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear);
10167c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    __ int3();
10177c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    __ bind(&done);
10187c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  }
10197c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
1020a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(info()->IsStub() || frame_is_built_);
10217c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  if (cc == no_condition && frame_is_built_) {
1022169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ call(entry, RelocInfo::RUNTIME_ENTRY);
1023a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
10247c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    // We often have several deopts to the same entry, reuse the last
10257c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    // jump entry if this is the case.
10267c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    if (jump_table_.is_empty() ||
10277c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org        jump_table_.last().address != entry ||
10287c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org        jump_table_.last().needs_frame != !frame_is_built_ ||
1029aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org        jump_table_.last().bailout_type != bailout_type) {
1030aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org      Deoptimizer::JumpTableEntry table_entry(entry,
1031aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org                                              bailout_type,
1032aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org                                              !frame_is_built_);
10337c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      jump_table_.Add(table_entry, zone());
1034a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
10357c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    if (cc == no_condition) {
10367c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ jmp(&jump_table_.last().label);
1037a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
10387c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ j(cc, &jump_table_.last().label);
1039a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1040a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1041a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1042a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1043a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1044aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.orgvoid LCodeGen::DeoptimizeIf(Condition cc,
1045aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org                            LEnvironment* environment) {
1046aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  Deoptimizer::BailoutType bailout_type = info()->IsStub()
1047aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org      ? Deoptimizer::LAZY
1048aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org      : Deoptimizer::EAGER;
1049aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  DeoptimizeIf(cc, environment, bailout_type);
1050aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org}
1051aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org
1052aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org
10536ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.orgvoid LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
10546ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  ZoneList<Handle<Map> > maps(1, zone());
10556ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
10566ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
10576ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org    RelocInfo::Mode mode = it.rinfo()->rmode();
10586ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org    if (mode == RelocInfo::EMBEDDED_OBJECT &&
10596ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org        it.rinfo()->target_object()->IsMap()) {
10606ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org      Handle<Map> map(Map::cast(it.rinfo()->target_object()));
10616ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org      if (map->CanTransition()) {
10626ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org        maps.Add(map, zone());
10636ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org      }
10646ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org    }
10656ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  }
10666ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org#ifdef VERIFY_HEAP
10676ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  // This disables verification of weak embedded maps after full GC.
10686ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  // AddDependentCode can cause a GC, which would observe the state where
10696ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  // this code is not yet in the depended code lists of the embedded maps.
10706ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  NoWeakEmbeddedMapsVerificationScope disable_verification_of_embedded_maps;
10716ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org#endif
10726ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  for (int i = 0; i < maps.length(); i++) {
10732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code);
10746ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  }
10756ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org}
10766ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org
10776ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org
1078a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
1079a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int length = deoptimizations_.length();
1080a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (length == 0) return;
1081a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Handle<DeoptimizationInputData> data =
1082ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      factory()->NewDeoptimizationInputData(length, TENURED);
1083a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1084876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  Handle<ByteArray> translations =
1085876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      translations_.CreateByteArray(isolate()->factory());
10869ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  data->SetTranslationByteArray(*translations);
1087a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_));
1088a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1089a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Handle<FixedArray> literals =
1090ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      factory()->NewFixedArray(deoptimization_literals_.length(), TENURED);
109179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  { AllowDeferredHandleDereference copy_handles;
109232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    for (int i = 0; i < deoptimization_literals_.length(); i++) {
109332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      literals->set(i, *deoptimization_literals_[i]);
109432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    }
109532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    data->SetLiteralArray(*literals);
1096a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1097a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1098471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt()));
1099a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_));
1100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Populate the deoptimization entries.
1102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < length; i++) {
1103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    LEnvironment* env = deoptimizations_[i];
1104471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    data->SetAstId(i, env->ast_id());
1105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    data->SetTranslationIndex(i, Smi::FromInt(env->translation_index()));
1106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    data->SetArgumentsStackHeight(i,
1107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                  Smi::FromInt(env->arguments_stack_height()));
110827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    data->SetPc(i, Smi::FromInt(env->pc_offset()));
1109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  code->set_deoptimization_data(*data);
1111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgint LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) {
1115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int result = deoptimization_literals_.length();
1116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < deoptimization_literals_.length(); ++i) {
1117a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (deoptimization_literals_[i].is_identical_to(literal)) return i;
1118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
11197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  deoptimization_literals_.Add(literal, zone());
1120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return result;
1121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1122a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1123a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1124a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() {
1125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(deoptimization_literals_.length() == 0);
1126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const ZoneList<Handle<JSFunction> >* inlined_closures =
1128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      chunk()->inlined_closures();
1129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0, length = inlined_closures->length();
1131a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org       i < length;
1132a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org       i++) {
1133a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DefineDeoptimizationLiteral(inlined_closures->at(i));
1134a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  inlined_function_count_ = deoptimization_literals_.length();
1137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
114027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::RecordSafepointWithLazyDeopt(
114127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    LInstruction* instr, SafepointMode safepoint_mode) {
114227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) {
114327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
114427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  } else {
114527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
114627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    RecordSafepointWithRegisters(
114727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org        instr->pointer_map(), 0, Safepoint::kLazyDeopt);
114827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  }
114927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org}
115027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
115127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
1152378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid LCodeGen::RecordSafepoint(
1153378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    LPointerMap* pointers,
1154378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    Safepoint::Kind kind,
1155378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    int arguments,
115627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    Safepoint::DeoptMode deopt_mode) {
115744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  ASSERT(kind == expected_safepoint_kind_);
1158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  const ZoneList<LOperand*>* operands = pointers->GetNormalizedOperands();
115927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  Safepoint safepoint =
116027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      safepoints_.DefineSafepoint(masm(), kind, arguments, deopt_mode);
1161a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < operands->length(); i++) {
1162a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    LOperand* pointer = operands->at(i);
1163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (pointer->IsStackSlot()) {
1164400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      safepoint.DefinePointerSlot(pointer->index(), zone());
1165378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) {
11667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      safepoint.DefinePointerRegister(ToRegister(pointer), zone());
1167a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1168a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1169378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org}
1170378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
1171378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
1172378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid LCodeGen::RecordSafepoint(LPointerMap* pointers,
117327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                               Safepoint::DeoptMode mode) {
117427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  RecordSafepoint(pointers, Safepoint::kSimple, 0, mode);
1175a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1176a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1177a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
117827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::RecordSafepoint(Safepoint::DeoptMode mode) {
11797028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  LPointerMap empty_pointers(RelocInfo::kNoPosition, zone());
118027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  RecordSafepoint(&empty_pointers, mode);
11813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
11823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
11833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers,
1185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                            int arguments,
118627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                            Safepoint::DeoptMode mode) {
118727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, mode);
1188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::RecordPosition(int position) {
11926d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  if (position == RelocInfo::kNoPosition) return;
1193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  masm()->positions_recorder()->RecordPosition(position);
1194a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1195a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1196a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1197594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::RecordAndUpdatePosition(int position) {
1198594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (position >= 0 && position != old_position_) {
1199594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    masm()->positions_recorder()->RecordPosition(position);
1200594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    old_position_ = position;
1201594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
1202594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
1203594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1204594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
120532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.orgstatic const char* LabelType(LLabel* label) {
120632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (label->is_loop_header()) return " (loop header)";
120732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (label->is_osr_entry()) return " (OSR entry)";
120832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  return "";
120932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org}
121032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
121132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
1212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoLabel(LLabel* label) {
121332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------",
121432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org          current_instruction_,
121532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org          label->hydrogen_value()->id(),
1216b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org          label->block_id(),
121732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org          LabelType(label));
1218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(label->label());
1219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  current_block_ = label->block_id();
12208e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DoGap(label);
1221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoParallelMove(LParallelMove* move) {
12250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  resolver_.Resolve(move);
1226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoGap(LGap* gap) {
1230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = LGap::FIRST_INNER_POSITION;
1231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org       i <= LGap::LAST_INNER_POSITION;
1232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org       i++) {
1233a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    LGap::InnerPosition inner_pos = static_cast<LGap::InnerPosition>(i);
1234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    LParallelMove* move = gap->GetParallelMove(inner_pos);
1235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (move != NULL) DoParallelMove(move);
1236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12408e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid LCodeGen::DoInstructionGap(LInstructionGap* instr) {
12418e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DoGap(instr);
12428e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org}
12438e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
12448e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1245a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoParameter(LParameter* instr) {
1246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Nothing to do.
1247a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1248a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1249a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1250a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallStub(LCallStub* instr) {
1251496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
1252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
1253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  switch (instr->hydrogen()->major_key()) {
1254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case CodeStub::RegExpConstructResult: {
1255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      RegExpConstructResultStub stub;
12568432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1257a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
1258a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1259a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case CodeStub::RegExpExec: {
1260a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      RegExpExecStub stub;
12618432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
1263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1264a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case CodeStub::SubString: {
1265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      SubStringStub stub;
12668432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
1268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case CodeStub::NumberToString: {
1270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      NumberToStringStub stub;
12718432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
1273a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case CodeStub::StringCompare: {
1275a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      StringCompareStub stub;
12768432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
1278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case CodeStub::TranscendentalCache: {
1280023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org      TranscendentalCacheStub stub(instr->transcendental_type(),
1281023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org                                   TranscendentalCacheStub::TAGGED);
12828432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
1284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    default:
1286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      UNREACHABLE();
1287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
12921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Record the address of the first unknown OSR value as the place to enter.
12931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (osr_pc_offset_ == -1) osr_pc_offset_ = masm()->pc_offset();
1294a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1295a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoModI(LModI* instr) {
12988a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  HMod* hmod = instr->hydrogen();
12998a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  HValue* left = hmod->left();
13008a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  HValue* right = hmod->right();
13018a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  if (hmod->HasPowerOf2Divisor()) {
13028a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // TODO(svenpanne) We should really do the strength reduction on the
13038a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // Hydrogen level.
13048a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    Register left_reg = ToRegister(instr->left());
13058a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    ASSERT(left_reg.is(ToRegister(instr->result())));
1306b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
13078a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // Note: The code below even works when right contains kMinInt.
13088a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    int32_t divisor = Abs(right->GetInteger32Constant());
1309b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
13108a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    Label left_is_not_negative, done;
13118a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    if (left->CanBeNegative()) {
13128a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ test(left_reg, Operand(left_reg));
13138a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ j(not_sign, &left_is_not_negative, Label::kNear);
13148a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ neg(left_reg);
13158a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ and_(left_reg, divisor - 1);
13168a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ neg(left_reg);
13178a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
13188a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org        DeoptimizeIf(zero, instr->environment());
13198a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      }
13207b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      __ jmp(&done, Label::kNear);
1321b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    }
13228a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org
13238a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    __ bind(&left_is_not_negative);
13248a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    __ and_(left_reg, divisor - 1);
1325b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    __ bind(&done);
13268a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org
13271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  } else if (hmod->fixed_right_arg().has_value) {
132856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    Register left_reg = ToRegister(instr->left());
13298a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    ASSERT(left_reg.is(ToRegister(instr->result())));
133056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    Register right_reg = ToRegister(instr->right());
1331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
13321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    int32_t divisor = hmod->fixed_right_arg().value;
13338a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    ASSERT(IsPowerOf2(divisor));
13348a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org
13358a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // Check if our assumption of a fixed right operand still holds.
13368a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    __ cmp(right_reg, Immediate(divisor));
13378a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    DeoptimizeIf(not_equal, instr->environment());
13388a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org
13398a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    Label left_is_not_negative, done;
13408a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    if (left->CanBeNegative()) {
13418a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ test(left_reg, Operand(left_reg));
13428a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ j(not_sign, &left_is_not_negative, Label::kNear);
13438a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ neg(left_reg);
13448a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ and_(left_reg, divisor - 1);
13458a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ neg(left_reg);
13468a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
13478a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org        DeoptimizeIf(zero, instr->environment());
13488a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      }
13498a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ jmp(&done, Label::kNear);
13508a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    }
13518a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org
13528a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    __ bind(&left_is_not_negative);
13538a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    __ and_(left_reg, divisor - 1);
13548a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    __ bind(&done);
13558a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org
13568a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  } else {
13578a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    Register left_reg = ToRegister(instr->left());
13588e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    ASSERT(left_reg.is(eax));
13598a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    Register right_reg = ToRegister(instr->right());
1360b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    ASSERT(!right_reg.is(eax));
1361b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    ASSERT(!right_reg.is(edx));
13628a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    Register result_reg = ToRegister(instr->result());
13638a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    ASSERT(result_reg.is(edx));
1364a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
13658a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    Label done;
13668a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // Check for x % 0, idiv would signal a divide error. We have to
13678a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // deopt in this case because we can't return a NaN.
13688a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    if (right->CanBeZero()) {
13698e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      __ test(right_reg, Operand(right_reg));
1370b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org      DeoptimizeIf(zero, instr->environment());
1371b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    }
1372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
13738a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // Check for kMinInt % -1, idiv would signal a divide error. We
13748a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // have to deopt if we care about -0, because we can't return that.
13758a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) {
13768a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      Label no_overflow_possible;
1377a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ cmp(left_reg, kMinInt);
13788a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ j(not_equal, &no_overflow_possible, Label::kNear);
1379a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ cmp(right_reg, -1);
13808a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
13818a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org        DeoptimizeIf(equal, instr->environment());
13828a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      } else {
13838a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org        __ j(not_equal, &no_overflow_possible, Label::kNear);
13848a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org        __ Set(result_reg, Immediate(0));
13858a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org        __ jmp(&done, Label::kNear);
13868a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      }
13878a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ bind(&no_overflow_possible);
1388a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
1389a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
13908a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // Sign extend dividend in eax into edx:eax.
1391b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    __ cdq();
1392a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
13938a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // If we care about -0, test if the dividend is <0 and the result is 0.
13948a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    if (left->CanBeNegative() &&
13958a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org        hmod->CanBeZero() &&
13968a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org        hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
139783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Label positive_left;
13988e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      __ test(left_reg, Operand(left_reg));
139983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      __ j(not_sign, &positive_left, Label::kNear);
1400b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org      __ idiv(right_reg);
14018e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      __ test(result_reg, Operand(result_reg));
14028a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      DeoptimizeIf(zero, instr->environment());
14038a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ jmp(&done, Label::kNear);
1404b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org      __ bind(&positive_left);
1405b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    }
14068a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    __ idiv(right_reg);
14078e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    __ bind(&done);
1408a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1409a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1410a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1411a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1412a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoDivI(LDivI* instr) {
14134cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (!instr->is_flooring() && instr->hydrogen()->HasPowerOf2Divisor()) {
14145323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    Register dividend = ToRegister(instr->left());
1415837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org    int32_t divisor = instr->hydrogen()->right()->GetInteger32Constant();
14165323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    int32_t test_value = 0;
14175323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    int32_t power = 0;
14185323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org
14195323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    if (divisor > 0) {
14205323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org      test_value = divisor - 1;
14215323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org      power = WhichPowerOf2(divisor);
14225323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    } else {
14235323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org      // Check for (0 / -x) that will produce negative zero.
14245323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org      if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
14255323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org        __ test(dividend, Operand(dividend));
14265323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org        DeoptimizeIf(zero, instr->environment());
14275323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org      }
14285323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org      // Check for (kMinInt / -1).
14295323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org      if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
14305323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org        __ cmp(dividend, kMinInt);
14315323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org        DeoptimizeIf(zero, instr->environment());
14325323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org      }
14335323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org      test_value = - divisor - 1;
14345323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org      power = WhichPowerOf2(-divisor);
14355323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    }
14365323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org
14375323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    if (test_value != 0) {
1438837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org      if (instr->hydrogen()->CheckFlag(
1439837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org          HInstruction::kAllUsesTruncatingToInt32)) {
1440837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        Label done, negative;
1441837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        __ cmp(dividend, 0);
1442837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        __ j(less, &negative, Label::kNear);
1443837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        __ sar(dividend, power);
144421af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org        if (divisor < 0) __ neg(dividend);
1445837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        __ jmp(&done, Label::kNear);
1446837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org
1447837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        __ bind(&negative);
1448837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        __ neg(dividend);
1449837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        __ sar(dividend, power);
1450837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        if (divisor > 0) __ neg(dividend);
1451837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        __ bind(&done);
1452837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        return;  // Don't fall through to "__ neg" below.
1453837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org      } else {
1454837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        // Deoptimize if remainder is not 0.
1455837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        __ test(dividend, Immediate(test_value));
1456837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        DeoptimizeIf(not_zero, instr->environment());
1457837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org        __ sar(dividend, power);
1458837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org      }
14595323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    }
14605323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org
14615323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    if (divisor < 0) __ neg(dividend);
14625323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org
14635323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    return;
14645323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org  }
14655323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org
146656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* right = instr->right();
1467a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
146856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  ASSERT(ToRegister(instr->left()).is(eax));
146956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  ASSERT(!ToRegister(instr->right()).is(eax));
147056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  ASSERT(!ToRegister(instr->right()).is(edx));
1471a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1472a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register left_reg = eax;
1473a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1474a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Check for x / 0.
1475a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register right_reg = ToRegister(right);
14764cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
1477a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ test(right_reg, ToOperand(right));
1478a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizeIf(zero, instr->environment());
1479a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Check for (0 / -x) that will produce negative zero.
14824cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (instr->hydrogen_value()->CheckFlag(HValue::kBailoutOnMinusZero)) {
148383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label left_not_zero;
1484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ test(left_reg, Operand(left_reg));
148583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    __ j(not_zero, &left_not_zero, Label::kNear);
1486a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ test(right_reg, ToOperand(right));
1487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizeIf(sign, instr->environment());
1488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ bind(&left_not_zero);
1489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
14915323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org  // Check for (kMinInt / -1).
14924cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)) {
149383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label left_not_min_int;
1494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ cmp(left_reg, kMinInt);
149583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    __ j(not_zero, &left_not_min_int, Label::kNear);
1496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ cmp(right_reg, -1);
1497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizeIf(zero, instr->environment());
1498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ bind(&left_not_min_int);
1499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Sign extend to edx.
1502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ cdq();
1503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ idiv(right_reg);
1504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1505837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  if (instr->is_flooring()) {
15064cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    Label done;
15074cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    __ test(edx, edx);
15084cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    __ j(zero, &done, Label::kNear);
15094cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    __ xor_(edx, right_reg);
15104cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    __ sar(edx, 31);
15114cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    __ add(eax, edx);
15124cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    __ bind(&done);
1513837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  } else if (!instr->hydrogen()->CheckFlag(
1514837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org      HInstruction::kAllUsesTruncatingToInt32)) {
1515837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org    // Deoptimize if remainder is not 0.
1516837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org    __ test(edx, Operand(edx));
1517837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org    DeoptimizeIf(not_zero, instr->environment());
15184cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
1519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1521a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1522d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.orgvoid LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
152356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  ASSERT(instr->right()->IsConstantOperand());
1524d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org
152556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register dividend = ToRegister(instr->left());
152656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
1527d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org  Register result = ToRegister(instr->result());
1528d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org
1529d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org  switch (divisor) {
1530d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org  case 0:
1531d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    DeoptimizeIf(no_condition, instr->environment());
1532d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    return;
1533d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org
1534d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org  case 1:
1535d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    __ Move(result, dividend);
1536d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    return;
1537d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org
1538d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org  case -1:
1539d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    __ Move(result, dividend);
1540d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    __ neg(result);
1541d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1542d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      DeoptimizeIf(zero, instr->environment());
1543d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    }
1544d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1545d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      DeoptimizeIf(overflow, instr->environment());
1546d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    }
1547d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    return;
1548d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org  }
1549d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org
1550d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org  uint32_t divisor_abs = abs(divisor);
1551d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org  if (IsPowerOf2(divisor_abs)) {
1552d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    int32_t power = WhichPowerOf2(divisor_abs);
1553d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    if (divisor < 0) {
1554d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      // Input[dividend] is clobbered.
1555d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      // The sequence is tedious because neg(dividend) might overflow.
1556d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ mov(result, dividend);
1557d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ sar(dividend, 31);
1558d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ neg(result);
1559d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1560d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org        DeoptimizeIf(zero, instr->environment());
1561d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      }
1562d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ shl(dividend, 32 - power);
1563d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ sar(result, power);
1564d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ not_(dividend);
1565d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      // Clear result.sign if dividend.sign is set.
1566d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ and_(result, dividend);
1567d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    } else {
1568d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ Move(result, dividend);
1569d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ sar(result, power);
1570d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    }
1571d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org  } else {
157256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(ToRegister(instr->left()).is(eax));
1573d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    ASSERT(ToRegister(instr->result()).is(edx));
157456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    Register scratch = ToRegister(instr->temp());
1575d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org
1576d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    // Find b which: 2^b < divisor_abs < 2^(b+1).
1577d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
1578d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    unsigned shift = 32 + b;  // Precision +1bit (effectively).
1579d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    double multiplier_f =
1580d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org        static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs;
1581d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    int64_t multiplier;
1582d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    if (multiplier_f - floor(multiplier_f) < 0.5) {
1583d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org        multiplier = static_cast<int64_t>(floor(multiplier_f));
1584d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    } else {
1585d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org        multiplier = static_cast<int64_t>(floor(multiplier_f)) + 1;
1586d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    }
1587d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    // The multiplier is a uint32.
1588d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    ASSERT(multiplier > 0 &&
1589d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org           multiplier < (static_cast<int64_t>(1) << 32));
1590d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    __ mov(scratch, dividend);
1591d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    if (divisor < 0 &&
1592d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org        instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1593d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ test(dividend, dividend);
1594d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      DeoptimizeIf(zero, instr->environment());
1595d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    }
1596d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    __ mov(edx, static_cast<int32_t>(multiplier));
1597d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    __ imul(edx);
1598d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    if (static_cast<int32_t>(multiplier) < 0) {
1599d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ add(edx, scratch);
1600d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    }
1601d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    Register reg_lo = eax;
1602d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    Register reg_byte_scratch = scratch;
1603d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    if (!reg_byte_scratch.is_byte_register()) {
1604d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org        __ xchg(reg_lo, reg_byte_scratch);
1605d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org        reg_lo = scratch;
1606d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org        reg_byte_scratch = eax;
1607d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    }
1608d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    if (divisor < 0) {
1609d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ xor_(reg_byte_scratch, reg_byte_scratch);
1610d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ cmp(reg_lo, 0x40000000);
1611d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ setcc(above, reg_byte_scratch);
1612d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ neg(edx);
1613d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ sub(edx, reg_byte_scratch);
1614d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    } else {
1615d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ xor_(reg_byte_scratch, reg_byte_scratch);
1616d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ cmp(reg_lo, 0xC0000000);
1617d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ setcc(above_equal, reg_byte_scratch);
1618d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org      __ add(edx, reg_byte_scratch);
1619d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    }
1620d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org    __ sar(edx, shift - 32);
1621d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org  }
1622d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org}
1623d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org
1624d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org
1625a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoMulI(LMulI* instr) {
162656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register left = ToRegister(instr->left());
162756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* right = instr->right();
1628a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1629a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
163056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    __ mov(ToRegister(instr->temp()), left);
1631a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1632a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1633a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (right->IsConstantOperand()) {
1634badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    // Try strength reductions on the multiplication.
1635badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    // All replacement instructions are at most as long as the imul
1636badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    // and have better latency.
1637badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    int constant = ToInteger32(LConstantOperand::cast(right));
1638badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    if (constant == -1) {
1639badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org      __ neg(left);
1640badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    } else if (constant == 0) {
1641badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org      __ xor_(left, Operand(left));
1642badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    } else if (constant == 2) {
1643badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org      __ add(left, Operand(left));
1644badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    } else if (!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1645badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org      // If we know that the multiplication can't overflow, it's safe to
1646badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org      // use instructions that don't set the overflow flag for the
1647badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org      // multiplication.
1648badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org      switch (constant) {
1649badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org        case 1:
1650badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          // Do nothing.
1651badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          break;
1652badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org        case 3:
1653badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          __ lea(left, Operand(left, left, times_2, 0));
1654badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          break;
1655badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org        case 4:
1656badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          __ shl(left, 2);
1657badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          break;
1658badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org        case 5:
1659badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          __ lea(left, Operand(left, left, times_4, 0));
1660badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          break;
1661badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org        case 8:
1662badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          __ shl(left, 3);
1663badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          break;
1664badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org        case 9:
1665badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          __ lea(left, Operand(left, left, times_8, 0));
1666badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          break;
1667badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org       case 16:
1668badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org         __ shl(left, 4);
1669badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org         break;
1670badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org        default:
1671badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          __ imul(left, left, constant);
1672badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org          break;
1673badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org      }
1674badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    } else {
1675badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org      __ imul(left, left, constant);
1676badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    }
1677a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
1678fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    if (instr->hydrogen()->representation().IsSmi()) {
1679fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      __ SmiUntag(left);
1680fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    }
1681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ imul(left, ToOperand(right));
1682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1683a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1684a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1685a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizeIf(overflow, instr->environment());
1686a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1687a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1688a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1689a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Bail out if the result is supposed to be negative zero.
169083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label done;
1691a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ test(left, Operand(left));
169283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    __ j(not_zero, &done, Label::kNear);
1693a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (right->IsConstantOperand()) {
169433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      if (ToInteger32(LConstantOperand::cast(right)) < 0) {
1695a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        DeoptimizeIf(no_condition, instr->environment());
169633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      } else if (ToInteger32(LConstantOperand::cast(right)) == 0) {
169733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org        __ cmp(ToRegister(instr->temp()), Immediate(0));
169833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org        DeoptimizeIf(less, instr->environment());
1699a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
1700a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
1701a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Test the non-zero operand for negative sign.
170256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      __ or_(ToRegister(instr->temp()), ToOperand(right));
1703a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      DeoptimizeIf(sign, instr->environment());
1704a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1705a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ bind(&done);
1706a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1707a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1708a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1710a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoBitI(LBitI* instr) {
171156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* left = instr->left();
171256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* right = instr->right();
1713a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(left->Equals(instr->result()));
1714a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(left->IsRegister());
1715a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1716a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (right->IsConstantOperand()) {
1717594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int32_t right_operand =
1718594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        ToRepresentation(LConstantOperand::cast(right),
1719594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                         instr->hydrogen()->representation());
1720a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    switch (instr->op()) {
1721a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case Token::BIT_AND:
1722a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        __ and_(ToRegister(left), right_operand);
1723a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1724a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case Token::BIT_OR:
1725a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        __ or_(ToRegister(left), right_operand);
1726a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1727a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case Token::BIT_XOR:
1728594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        if (right_operand == int32_t(~0)) {
1729594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          __ not_(ToRegister(left));
1730594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        } else {
1731594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          __ xor_(ToRegister(left), right_operand);
1732594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        }
1733a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1734a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      default:
1735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        UNREACHABLE();
1736a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1737a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1738a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
1739a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    switch (instr->op()) {
1740a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case Token::BIT_AND:
1741a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        __ and_(ToRegister(left), ToOperand(right));
1742a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1743a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case Token::BIT_OR:
1744a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        __ or_(ToRegister(left), ToOperand(right));
1745a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1746a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case Token::BIT_XOR:
1747a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        __ xor_(ToRegister(left), ToOperand(right));
1748a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1749a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      default:
1750a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        UNREACHABLE();
1751a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1752a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1753a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1754a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1755a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1756a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1757a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoShiftI(LShiftI* instr) {
175856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* left = instr->left();
175956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* right = instr->right();
1760a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(left->Equals(instr->result()));
1761a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(left->IsRegister());
1762a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (right->IsRegister()) {
1763a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(ToRegister(right).is(ecx));
1764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    switch (instr->op()) {
1766e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case Token::ROR:
1767e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        __ ror_cl(ToRegister(left));
1768e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        if (instr->can_deopt()) {
1769e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          __ test(ToRegister(left), Immediate(0x80000000));
1770e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          DeoptimizeIf(not_zero, instr->environment());
1771e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        }
1772e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        break;
1773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case Token::SAR:
1774a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        __ sar_cl(ToRegister(left));
1775a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1776a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case Token::SHR:
1777a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        __ shr_cl(ToRegister(left));
1778a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        if (instr->can_deopt()) {
1779a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          __ test(ToRegister(left), Immediate(0x80000000));
1780a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          DeoptimizeIf(not_zero, instr->environment());
1781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
1782a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1783a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case Token::SHL:
1784a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        __ shl_cl(ToRegister(left));
1785a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1786a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      default:
1787a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        UNREACHABLE();
1788a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1789a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1790a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
1791a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    int value = ToInteger32(LConstantOperand::cast(right));
1792a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
1793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    switch (instr->op()) {
1794e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case Token::ROR:
1795e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        if (shift_count == 0 && instr->can_deopt()) {
1796e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          __ test(ToRegister(left), Immediate(0x80000000));
1797e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          DeoptimizeIf(not_zero, instr->environment());
1798e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        } else {
1799e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          __ ror(ToRegister(left), shift_count);
1800e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        }
1801e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        break;
1802a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case Token::SAR:
1803a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        if (shift_count != 0) {
1804a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          __ sar(ToRegister(left), shift_count);
1805a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
1806a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1807a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case Token::SHR:
1808a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        if (shift_count == 0 && instr->can_deopt()) {
1809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          __ test(ToRegister(left), Immediate(0x80000000));
1810a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          DeoptimizeIf(not_zero, instr->environment());
1811a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        } else {
1812a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          __ shr(ToRegister(left), shift_count);
1813a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
1814a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1815a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case Token::SHL:
1816a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        if (shift_count != 0) {
1817d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          if (instr->hydrogen_value()->representation().IsSmi() &&
1818d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org              instr->can_deopt()) {
1819d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            if (shift_count != 1) {
1820d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org              __ shl(ToRegister(left), shift_count - 1);
1821d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            }
1822d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            __ SmiTag(ToRegister(left));
1823d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            DeoptimizeIf(overflow, instr->environment());
1824d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          } else {
1825d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            __ shl(ToRegister(left), shift_count);
1826d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          }
1827a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
1828a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      default:
1830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        UNREACHABLE();
1831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
1832a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1835a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1836a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1837a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoSubI(LSubI* instr) {
183856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* left = instr->left();
183956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* right = instr->right();
1840a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(left->Equals(instr->result()));
1841a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1842a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (right->IsConstantOperand()) {
1843fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    __ sub(ToOperand(left),
1844fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org           ToImmediate(right, instr->hydrogen()->representation()));
1845a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
1846a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ sub(ToRegister(left), ToOperand(right));
1847a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1848a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1849a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizeIf(overflow, instr->environment());
1850a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1851a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1852a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1853a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1854a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoConstantI(LConstantI* instr) {
1855b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  __ Set(ToRegister(instr->result()), Immediate(instr->value()));
1856b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org}
1857b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
1858b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
1859b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgvoid LCodeGen::DoConstantS(LConstantS* instr) {
18609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  __ Set(ToRegister(instr->result()), Immediate(instr->value()));
1861a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1862a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1863a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1864a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoConstantD(LConstantD* instr) {
1865a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  double v = instr->value();
1866e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  uint64_t int_val = BitCast<uint64_t, double>(v);
1867e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  int32_t lower = static_cast<int32_t>(int_val);
1868e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
1869e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1870e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!CpuFeatures::IsSafeForSnapshot(SSE2)) {
1871e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ push(Immediate(upper));
1872169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ push(Immediate(lower));
1873169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    X87Mov(ToX87Register(instr->result()), Operand(esp, 0));
1874e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ add(Operand(esp), Immediate(kDoubleSize));
1875a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
1876e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatureScope scope1(masm(), SSE2);
1877e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    ASSERT(instr->result()->IsDoubleRegister());
1878e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    XMMRegister res = ToDoubleRegister(instr->result());
1879e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (int_val == 0) {
1880e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ xorps(res, res);
1881e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    } else {
1882e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      Register temp = ToRegister(instr->temp());
1883e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      if (CpuFeatures::IsSupported(SSE4_1)) {
1884e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        CpuFeatureScope scope2(masm(), SSE4_1);
1885e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        if (lower != 0) {
1886e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          __ Set(temp, Immediate(lower));
1887e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          __ movd(res, Operand(temp));
1888e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          __ Set(temp, Immediate(upper));
1889e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          __ pinsrd(res, Operand(temp), 1);
1890e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        } else {
1891e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          __ xorps(res, res);
1892e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          __ Set(temp, Immediate(upper));
1893e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          __ pinsrd(res, Operand(temp), 1);
1894e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        }
1895d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com      } else {
1896d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com        __ Set(temp, Immediate(upper));
1897e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ movd(res, Operand(temp));
1898e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ psllq(res, 32);
1899e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        if (lower != 0) {
1900e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          __ Set(temp, Immediate(lower));
1901e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          __ movd(xmm0, Operand(temp));
1902e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          __ por(res, xmm0);
1903e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        }
1904d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com      }
1905a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1906a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1907a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1908a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1909a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1910d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid LCodeGen::DoConstantE(LConstantE* instr) {
1911d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value()));
1912d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
1913d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1914d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1915a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoConstantT(LConstantT* instr) {
1916c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Register reg = ToRegister(instr->result());
1917c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<Object> handle = instr->value();
191879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowDeferredHandleDereference smi_check;
1919fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  __ LoadObject(reg, handle);
1920a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1921a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1922a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1923355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgvoid LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1924355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  Register result = ToRegister(instr->result());
192556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register map = ToRegister(instr->value());
1926355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  __ EnumLength(result, map);
1927355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org}
1928355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
1929355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
19307b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgvoid LCodeGen::DoElementsKind(LElementsKind* instr) {
19317b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  Register result = ToRegister(instr->result());
193256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register input = ToRegister(instr->value());
19337b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
19347b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Load map into |result|.
19357b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  __ mov(result, FieldOperand(input, HeapObject::kMapOffset));
19367b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Load the map's "bit field 2" into |result|. We only need the first byte,
19377b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // but the following masking takes care of that anyway.
19387b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  __ mov(result, FieldOperand(result, Map::kBitField2Offset));
19397b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Retrieve elements_kind from bit field 2.
19407b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  __ and_(result, Map::kElementsKindMask);
19417b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  __ shr(result, Map::kElementsKindShift);
19427b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
19437b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
19447b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
1945a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoValueOf(LValueOf* instr) {
194656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register input = ToRegister(instr->value());
1947a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register result = ToRegister(instr->result());
194856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register map = ToRegister(instr->temp());
1949a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(input.is(result));
19504efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
195183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label done;
19521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
19531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!instr->hydrogen()->value()->IsHeapObject()) {
19541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    // If the object is a smi return the object.
19551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ JumpIfSmi(input, &done, Label::kNear);
19561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
1957a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1958a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // If the object is not a value type, return the object.
1959a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ CmpObjectType(input, JS_VALUE_TYPE, map);
196083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ j(not_equal, &done, Label::kNear);
1961a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(result, FieldOperand(input, JSValue::kValueOffset));
1962a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1963a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&done);
1964a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
1965a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1966a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
19674efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.orgvoid LCodeGen::DoDateField(LDateField* instr) {
196856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register object = ToRegister(instr->date());
19694efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  Register result = ToRegister(instr->result());
197056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register scratch = ToRegister(instr->temp());
19714efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  Smi* index = instr->index();
19724efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  Label runtime, done;
19734efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  ASSERT(object.is(result));
19744efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  ASSERT(object.is(eax));
19754efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
1976de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  __ test(object, Immediate(kSmiTagMask));
1977de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  DeoptimizeIf(zero, instr->environment());
19784efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  __ CmpObjectType(object, JS_DATE_TYPE, scratch);
1979de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  DeoptimizeIf(not_equal, instr->environment());
19804efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
19814efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  if (index->value() == 0) {
19824efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    __ mov(result, FieldOperand(object, JSDate::kValueOffset));
19834efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  } else {
19844efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    if (index->value() < JSDate::kFirstUncachedField) {
19854efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
19864efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      __ mov(scratch, Operand::StaticVariable(stamp));
19874efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      __ cmp(scratch, FieldOperand(object, JSDate::kCacheStampOffset));
19884efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      __ j(not_equal, &runtime, Label::kNear);
19894efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      __ mov(result, FieldOperand(object, JSDate::kValueOffset +
19904efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org                                          kPointerSize * index->value()));
19914efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      __ jmp(&done);
19924efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    }
19934efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    __ bind(&runtime);
19944efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    __ PrepareCallCFunction(2, scratch);
19954efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    __ mov(Operand(esp, 0), object);
19964efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    __ mov(Operand(esp, 1 * kPointerSize), Immediate(index));
19974efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
19984efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    __ bind(&done);
19994efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  }
20004efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org}
20014efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
20024efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
200332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.orgvoid LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
2004a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register string = ToRegister(instr->string());
2005a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register index = ToRegister(instr->index());
2006a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register value = ToRegister(instr->value());
2007a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  String::Encoding encoding = instr->encoding();
2008a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
2009a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  if (FLAG_debug_code) {
2010a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ push(value);
2011a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ mov(value, FieldOperand(string, HeapObject::kMapOffset));
2012a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ movzx_b(value, FieldOperand(value, Map::kInstanceTypeOffset));
2013a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
2014a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ and_(value, Immediate(kStringRepresentationMask | kStringEncodingMask));
2015a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
2016a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
2017a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ cmp(value, Immediate(encoding == String::ONE_BYTE_ENCODING
2018a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                                ? one_byte_seq_type : two_byte_seq_type));
2019594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Check(equal, kUnexpectedStringType);
2020a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ pop(value);
2021a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
2022a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
2023a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  if (encoding == String::ONE_BYTE_ENCODING) {
2024a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ mov_b(FieldOperand(string, index, times_1, SeqString::kHeaderSize),
2025a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org             value);
2026a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  } else {
2027a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ mov_w(FieldOperand(string, index, times_2, SeqString::kHeaderSize),
2028a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org             value);
2029a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
203032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org}
203132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
203232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
2033a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoThrow(LThrow* instr) {
2034ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  __ push(ToOperand(instr->value()));
2035ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
2036ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallRuntime(Runtime::kThrow, 1, instr);
2037a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2038a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (FLAG_debug_code) {
2039a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Comment("Unreachable code.");
2040a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ int3();
2041a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2042a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2043a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2044a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2045a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoAddI(LAddI* instr) {
204656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* left = instr->left();
204756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* right = instr->right();
2048a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2049906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
2050906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    if (right->IsConstantOperand()) {
2051fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      int32_t offset = ToRepresentation(LConstantOperand::cast(right),
2052fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                                        instr->hydrogen()->representation());
2053906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset));
2054906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    } else {
2055906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      Operand address(ToRegister(left), ToRegister(right), times_1, 0);
2056906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      __ lea(ToRegister(instr->result()), address);
2057906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    }
2058a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
2059906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    if (right->IsConstantOperand()) {
2060fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      __ add(ToOperand(left),
2061fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org             ToImmediate(right, instr->hydrogen()->representation()));
2062906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    } else {
2063906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      __ add(ToRegister(left), ToOperand(right));
2064906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    }
2065906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
2066906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      DeoptimizeIf(overflow, instr->environment());
2067906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    }
2068a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2069a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2070a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2071a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2072471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid LCodeGen::DoMathMinMax(LMathMinMax* instr) {
2073750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope scope(masm(), SSE2);
207456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* left = instr->left();
207556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* right = instr->right();
2076471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  ASSERT(left->Equals(instr->result()));
2077471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  HMathMinMax::Operation operation = instr->hydrogen()->operation();
2078fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
2079471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    Label return_left;
2080471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    Condition condition = (operation == HMathMinMax::kMathMin)
2081471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        ? less_equal
2082471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        : greater_equal;
2083471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    if (right->IsConstantOperand()) {
2084471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      Operand left_op = ToOperand(left);
2085fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      Immediate immediate = ToImmediate(LConstantOperand::cast(instr->right()),
2086fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                                        instr->hydrogen()->representation());
2087fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      __ cmp(left_op, immediate);
2088471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ j(condition, &return_left, Label::kNear);
2089fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      __ mov(left_op, immediate);
2090471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    } else {
2091471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      Register left_reg = ToRegister(left);
2092471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      Operand right_op = ToOperand(right);
2093471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ cmp(left_reg, right_op);
2094471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ j(condition, &return_left, Label::kNear);
2095471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ mov(left_reg, right_op);
2096471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    }
2097471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ bind(&return_left);
2098471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  } else {
2099471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    ASSERT(instr->hydrogen()->representation().IsDouble());
2100471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    Label check_nan_left, check_zero, return_left, return_right;
2101471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    Condition condition = (operation == HMathMinMax::kMathMin) ? below : above;
2102471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    XMMRegister left_reg = ToDoubleRegister(left);
2103471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    XMMRegister right_reg = ToDoubleRegister(right);
2104471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ ucomisd(left_reg, right_reg);
2105471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ j(parity_even, &check_nan_left, Label::kNear);  // At least one NaN.
2106471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ j(equal, &check_zero, Label::kNear);  // left == right.
2107471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ j(condition, &return_left, Label::kNear);
2108471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ jmp(&return_right, Label::kNear);
2109471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
2110471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ bind(&check_zero);
2111471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    XMMRegister xmm_scratch = xmm0;
2112471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ xorps(xmm_scratch, xmm_scratch);
2113471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ ucomisd(left_reg, xmm_scratch);
2114471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ j(not_equal, &return_left, Label::kNear);  // left == right != 0.
2115471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // At this point, both left and right are either 0 or -0.
2116471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    if (operation == HMathMinMax::kMathMin) {
2117471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ orpd(left_reg, right_reg);
2118471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    } else {
2119471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      // Since we operate on +0 and/or -0, addsd and andsd have the same effect.
2120471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ addsd(left_reg, right_reg);
2121471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    }
2122471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ jmp(&return_left, Label::kNear);
2123471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
2124471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ bind(&check_nan_left);
2125471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ ucomisd(left_reg, left_reg);  // NaN check.
2126471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ j(parity_even, &return_left, Label::kNear);  // left == NaN.
2127471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ bind(&return_right);
2128471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ movsd(left_reg, right_reg);
2129471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
2130471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ bind(&return_left);
2131471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  }
2132471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org}
2133471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
2134471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
2135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoArithmeticD(LArithmeticD* instr) {
2136169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
2137169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    CpuFeatureScope scope(masm(), SSE2);
2138169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    XMMRegister left = ToDoubleRegister(instr->left());
2139169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    XMMRegister right = ToDoubleRegister(instr->right());
2140169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    XMMRegister result = ToDoubleRegister(instr->result());
2141169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    // Modulo uses a fixed result register.
2142169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    ASSERT(instr->op() == Token::MOD || left.is(result));
2143169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    switch (instr->op()) {
2144169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      case Token::ADD:
2145169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ addsd(left, right);
2146169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        break;
2147169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      case Token::SUB:
2148169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ subsd(left, right);
2149169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        break;
2150169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      case Token::MUL:
2151169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ mulsd(left, right);
2152169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        break;
2153169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      case Token::DIV:
2154169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ divsd(left, right);
2155169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // Don't delete this mov. It may improve performance on some CPUs,
2156169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // when there is a mulsd depending on the result
2157169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ movaps(left, left);
2158169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        break;
2159169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      case Token::MOD: {
2160169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // Pass two doubles as arguments on the stack.
2161169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ PrepareCallCFunction(4, eax);
2162169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ movdbl(Operand(esp, 0 * kDoubleSize), left);
2163169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ movdbl(Operand(esp, 1 * kDoubleSize), right);
2164169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ CallCFunction(
2165169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org            ExternalReference::double_fp_operation(Token::MOD, isolate()),
2166169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org            4);
2167169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
2168169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // Return value is in st(0) on ia32.
2169169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // Store it into the (fixed) result register.
2170169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ sub(Operand(esp), Immediate(kDoubleSize));
2171169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ fstp_d(Operand(esp, 0));
2172169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ movdbl(result, Operand(esp, 0));
2173169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ add(Operand(esp), Immediate(kDoubleSize));
2174169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        break;
2175169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      }
2176169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      default:
2177169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        UNREACHABLE();
2178169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        break;
2179169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    }
2180169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  } else {
2181169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    X87Register left = ToX87Register(instr->left());
2182169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    X87Register right = ToX87Register(instr->right());
2183169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    X87Register result = ToX87Register(instr->result());
2184169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    X87PrepareBinaryOp(left, right, result);
2185169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    switch (instr->op()) {
2186169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      case Token::MUL:
2187169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ fmul_i(1);
2188169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        break;
2189169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      default:
2190169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        UNREACHABLE();
2191169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        break;
2192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2194a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2195a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2196a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2197a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoArithmeticT(LArithmeticT* instr) {
2198ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
2199ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  ASSERT(ToRegister(instr->left()).is(edx));
2200ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  ASSERT(ToRegister(instr->right()).is(eax));
2201a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
2202a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
220340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  BinaryOpStub stub(instr->op(), NO_OVERWRITE);
22048432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2205030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  __ nop();  // Signals no inlined code.
2206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2208a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
220932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.orgint LCodeGen::GetNextEmittedBlock() const {
221077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
221177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    if (!chunk_->GetLabel(i)->HasReplacement()) return i;
2212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return -1;
2214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
22171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<class InstrType>
22181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid LCodeGen::EmitBranch(InstrType instr, Condition cc) {
22191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  int left_block = instr->TrueDestination(chunk_);
2220e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  int right_block = instr->FalseDestination(chunk_);
22211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
222277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  int next_block = GetNextEmittedBlock();
2223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2224e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  if (right_block == left_block || cc == no_condition) {
2225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    EmitGoto(left_block);
2226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (left_block == next_block) {
2227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ j(NegateCondition(cc), chunk_->GetAssemblyLabel(right_block));
2228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (right_block == next_block) {
2229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ j(cc, chunk_->GetAssemblyLabel(left_block));
2230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
2231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ j(cc, chunk_->GetAssemblyLabel(left_block));
2232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ jmp(chunk_->GetAssemblyLabel(right_block));
2233a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2237c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.orgtemplate<class InstrType>
2238c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.orgvoid LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) {
2239c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  int false_block = instr->FalseDestination(chunk_);
2240c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  if (cc == no_condition) {
2241c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    __ jmp(chunk_->GetAssemblyLabel(false_block));
2242c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  } else {
2243c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    __ j(cc, chunk_->GetAssemblyLabel(false_block));
2244c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  }
2245c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org}
2246c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org
2247c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org
2248e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgvoid LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) {
2249e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  Representation r = instr->hydrogen()->value()->representation();
2250e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  if (r.IsSmiOrInteger32() || r.IsDouble()) {
2251e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    EmitBranch(instr, no_condition);
2252e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  } else {
2253e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    ASSERT(r.IsTagged());
2254e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    Register reg = ToRegister(instr->value());
2255e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    HType type = instr->hydrogen()->value()->type();
2256e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    if (type.IsTaggedNumber()) {
2257e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      EmitBranch(instr, no_condition);
2258e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    }
2259e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2260e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
2261e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org           factory()->heap_number_map());
2262e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    EmitBranch(instr, equal);
2263e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  }
2264e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org}
2265e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
2266e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
2267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoBranch(LBranch* instr) {
22684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  Representation r = instr->hydrogen()->value()->representation();
226953ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  if (r.IsSmiOrInteger32()) {
2270b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    ASSERT(!info()->IsStub());
227156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    Register reg = ToRegister(instr->value());
2272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ test(reg, Operand(reg));
22731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    EmitBranch(instr, not_zero);
2274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (r.IsDouble()) {
2275b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    ASSERT(!info()->IsStub());
2276b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    CpuFeatureScope scope(masm(), SSE2);
227756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    XMMRegister reg = ToDoubleRegister(instr->value());
2278fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org    __ xorps(xmm0, xmm0);
2279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ ucomisd(reg, xmm0);
22801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    EmitBranch(instr, not_equal);
2281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
2282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(r.IsTagged());
228356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    Register reg = ToRegister(instr->value());
2284d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    HType type = instr->hydrogen()->value()->type();
2285d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    if (type.IsBoolean()) {
2286b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org      ASSERT(!info()->IsStub());
2287ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      __ cmp(reg, factory()->true_value());
22881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitBranch(instr, equal);
2289d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    } else if (type.IsSmi()) {
2290b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org      ASSERT(!info()->IsStub());
2291d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      __ test(reg, Operand(reg));
22921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitBranch(instr, not_equal);
22931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    } else if (type.IsJSArray()) {
22941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      ASSERT(!info()->IsStub());
22951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitBranch(instr, no_condition);
22961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    } else if (type.IsHeapNumber()) {
22971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      ASSERT(!info()->IsStub());
22981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      CpuFeatureScope scope(masm(), SSE2);
22991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      __ xorps(xmm0, xmm0);
23001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset));
23011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitBranch(instr, not_equal);
23021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    } else if (type.IsString()) {
23031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      ASSERT(!info()->IsStub());
23041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0));
23051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitBranch(instr, not_equal);
2306a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
23077943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
23081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
23097943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
23107943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      if (expected.Contains(ToBooleanStub::UNDEFINED)) {
23117943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        // undefined -> false.
23127943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ cmp(reg, factory()->undefined_value());
23131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ j(equal, instr->FalseLabel(chunk_));
23147943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      }
23157943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      if (expected.Contains(ToBooleanStub::BOOLEAN)) {
23167943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        // true -> true.
23177943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ cmp(reg, factory()->true_value());
23181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ j(equal, instr->TrueLabel(chunk_));
23197943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        // false -> false.
23207943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ cmp(reg, factory()->false_value());
23211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ j(equal, instr->FalseLabel(chunk_));
23227943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      }
23237943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
23247943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        // 'null' -> false.
23257943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ cmp(reg, factory()->null_value());
23261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ j(equal, instr->FalseLabel(chunk_));
23277943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      }
23287943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
23297943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      if (expected.Contains(ToBooleanStub::SMI)) {
23307943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        // Smis: 0 -> false, all other -> true.
23317943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ test(reg, Operand(reg));
23321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ j(equal, instr->FalseLabel(chunk_));
23331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
23347943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      } else if (expected.NeedsMap()) {
23357943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        // If we need a map later and have a Smi -> deopt.
23367943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ test(reg, Immediate(kSmiTagMask));
23377943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        DeoptimizeIf(zero, instr->environment());
23387943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      }
23397943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
23404acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      Register map = no_reg;  // Keep the compiler happy.
23417943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      if (expected.NeedsMap()) {
234256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        map = ToRegister(instr->temp());
23437943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        ASSERT(!map.is(reg));
23447943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ mov(map, FieldOperand(reg, HeapObject::kMapOffset));
23454acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
23464acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org        if (expected.CanBeUndetectable()) {
23474acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org          // Undetectable -> false.
23484acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org          __ test_b(FieldOperand(map, Map::kBitFieldOffset),
23494acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org                    1 << Map::kIsUndetectable);
23501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          __ j(not_zero, instr->FalseLabel(chunk_));
23514acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org        }
23527943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      }
23537943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
23547943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
23557943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        // spec object -> true.
23567943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
23571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ j(above_equal, instr->TrueLabel(chunk_));
23587943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      }
23597943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
23607943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      if (expected.Contains(ToBooleanStub::STRING)) {
23617943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        // String value -> false iff empty.
23627943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        Label not_string;
23637943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
23647943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ j(above_equal, &not_string, Label::kNear);
23657943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0));
23661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ j(not_zero, instr->TrueLabel(chunk_));
23671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ jmp(instr->FalseLabel(chunk_));
23687943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ bind(&not_string);
23697943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      }
23707943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
2371f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      if (expected.Contains(ToBooleanStub::SYMBOL)) {
2372f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        // Symbol value -> true.
2373f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        __ CmpInstanceType(map, SYMBOL_TYPE);
23741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ j(equal, instr->TrueLabel(chunk_));
2375f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      }
2376f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
23777943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
23787943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        // heap number -> false iff +0, -0, or NaN.
23797943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        Label not_heap_number;
23807943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
23817943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org               factory()->heap_number_map());
23827943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ j(not_equal, &not_heap_number, Label::kNear);
2383b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org        if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
2384b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org          CpuFeatureScope scope(masm(), SSE2);
2385b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org          __ xorps(xmm0, xmm0);
2386b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org          __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset));
2387b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org        } else {
2388b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org          __ fldz();
2389b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org          __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset));
2390b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org          __ FCmp();
2391b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org        }
23921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ j(zero, instr->FalseLabel(chunk_));
23931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ jmp(instr->TrueLabel(chunk_));
23947943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org        __ bind(&not_heap_number);
23957943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      }
23967943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
23971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      if (!expected.IsGeneric()) {
23981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        // We've seen something for the first time -> deopt.
23991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        // This can only happen if we are not generic already.
24001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        DeoptimizeIf(no_condition, instr->environment());
24011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      }
2402a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2403a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2404a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2405a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2406a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
240704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgvoid LCodeGen::EmitGoto(int block) {
240832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (!IsNextEmittedBlock(block)) {
24091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block)));
2410a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2411a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2412a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2413a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2414a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoGoto(LGoto* instr) {
241504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  EmitGoto(instr->block_id());
2416a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2417a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2418a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2419a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgCondition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
2420a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Condition cond = no_condition;
2421a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  switch (op) {
2422a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Token::EQ:
2423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Token::EQ_STRICT:
2424a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      cond = equal;
2425a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
2426a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Token::LT:
2427a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      cond = is_unsigned ? below : less;
2428a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
2429a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Token::GT:
2430a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      cond = is_unsigned ? above : greater;
2431a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
2432a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Token::LTE:
2433a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      cond = is_unsigned ? below_equal : less_equal;
2434a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
2435a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Token::GTE:
2436a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      cond = is_unsigned ? above_equal : greater_equal;
2437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
2438a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Token::IN:
2439a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case Token::INSTANCEOF:
2440a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    default:
2441a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      UNREACHABLE();
2442a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return cond;
2444a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2445a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2446a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2447e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgvoid LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
244856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* left = instr->left();
244956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* right = instr->right();
2450394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Condition cc = TokenToCondition(instr->op(), instr->is_double());
2451a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2452394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (left->IsConstantOperand() && right->IsConstantOperand()) {
2453394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // We can statically evaluate the comparison.
2454394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    double left_val = ToDouble(LConstantOperand::cast(left));
2455394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    double right_val = ToDouble(LConstantOperand::cast(right));
24561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    int next_block = EvalComparison(instr->op(), left_val, right_val) ?
24571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2458394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    EmitGoto(next_block);
2459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
2460394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (instr->is_double()) {
2461750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      CpuFeatureScope scope(masm(), SSE2);
2462394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      // Don't base result on EFLAGS when a NaN is involved. Instead
2463394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      // jump to the false block.
2464394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
24651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      __ j(parity_even, instr->FalseLabel(chunk_));
2466394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    } else {
2467394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      if (right->IsConstantOperand()) {
2468fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        __ cmp(ToOperand(left),
2469fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org               ToImmediate(right, instr->hydrogen()->representation()));
2470394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      } else if (left->IsConstantOperand()) {
2471fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        __ cmp(ToOperand(right),
2472fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org               ToImmediate(left, instr->hydrogen()->representation()));
2473394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        // We transposed the operands. Reverse the condition.
2474394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        cc = ReverseCondition(cc);
2475394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      } else {
2476394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        __ cmp(ToRegister(left), ToOperand(right));
2477394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      }
2478394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
24791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    EmitBranch(instr, cc);
2480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2484ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.orgvoid LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
248556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register left = ToRegister(instr->left());
24867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2487b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (instr->right()->IsConstantOperand()) {
2488a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
2489a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ CmpObject(left, right);
2490b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  } else {
2491b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    Operand right = ToOperand(instr->right());
2492a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ cmp(left, right);
2493b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
24941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, equal);
24957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}
24967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
24977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2498c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.orgvoid LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2499c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  if (instr->hydrogen()->representation().IsTagged()) {
2500c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    Register input_reg = ToRegister(instr->object());
2501c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    __ cmp(input_reg, factory()->the_hole_value());
2502c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    EmitBranch(instr, equal);
2503c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    return;
2504c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  }
2505c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org
2506c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  bool use_sse2 = CpuFeatures::IsSupported(SSE2);
2507c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  if (use_sse2) {
2508c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    CpuFeatureScope scope(masm(), SSE2);
2509c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    XMMRegister input_reg = ToDoubleRegister(instr->object());
2510c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    __ ucomisd(input_reg, input_reg);
2511c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    EmitFalseBranch(instr, parity_odd);
2512c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  } else {
2513c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    // Put the value to the top of stack
2514c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    X87Register src = ToX87Register(instr->object());
2515c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    X87LoadForUsage(src);
2516c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    __ fld(0);
2517c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    __ fld(0);
2518c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    __ FCmp();
2519c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    Label ok;
2520c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    __ j(parity_even, &ok);
2521c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    __ fstp(0);
2522c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    EmitFalseBranch(instr, no_condition);
2523c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    __ bind(&ok);
2524c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  }
2525c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org
2526c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org
2527c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  __ sub(esp, Immediate(kDoubleSize));
2528c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  if (use_sse2) {
2529c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    CpuFeatureScope scope(masm(), SSE2);
2530c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    XMMRegister input_reg = ToDoubleRegister(instr->object());
2531c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    __ movdbl(MemOperand(esp, 0), input_reg);
2532c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  } else {
2533c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    __ fstp_d(MemOperand(esp, 0));
2534c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  }
2535c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org
2536c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  __ add(esp, Immediate(kDoubleSize));
2537c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  int offset = sizeof(kHoleNanUpper32);
2538c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  __ cmp(MemOperand(esp, -offset), Immediate(kHoleNanUpper32));
2539c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  EmitBranch(instr, equal);
2540c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org}
2541c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org
2542c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org
25435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgCondition LCodeGen::EmitIsObject(Register input,
25445f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                                 Register temp1,
25455f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                                 Label* is_not_object,
25465f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                                 Label* is_object) {
25477b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  __ JumpIfSmi(input, is_not_object);
25485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
2549ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ cmp(input, isolate()->factory()->null_value());
25505f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  __ j(equal, is_object);
25515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
25525f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  __ mov(temp1, FieldOperand(input, HeapObject::kMapOffset));
25535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Undetectable objects behave like undefined.
25543cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  __ test_b(FieldOperand(temp1, Map::kBitFieldOffset),
25553cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org            1 << Map::kIsUndetectable);
25565f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  __ j(not_zero, is_not_object);
25575f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
25583cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  __ movzx_b(temp1, FieldOperand(temp1, Map::kInstanceTypeOffset));
25593cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  __ cmp(temp1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
25605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  __ j(below, is_not_object);
25613cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  __ cmp(temp1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
25625f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  return below_equal;
25635f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
25645f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
25655f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
25665f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
256756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register reg = ToRegister(instr->value());
256856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register temp = ToRegister(instr->temp());
25695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
25701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Condition true_cond = EmitIsObject(
25711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      reg, temp, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
25725f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
25731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, true_cond);
25745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
25755f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
25765f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
25770ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryCondition LCodeGen::EmitIsString(Register input,
25780ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                 Register temp1,
25791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                 Label* is_not_string,
25801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                 SmiCheck check_needed = INLINE_SMI_CHECK) {
25811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (check_needed == INLINE_SMI_CHECK) {
25821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ JumpIfSmi(input, is_not_string);
25831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
25840ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
25850ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  Condition cond = masm_->IsObjectStringType(input, temp1, temp1);
25860ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
25870ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  return cond;
25880ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry}
25890ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
25900ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
25910ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
259256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register reg = ToRegister(instr->value());
259356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register temp = ToRegister(instr->temp());
25940ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
25951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  SmiCheck check_needed =
25961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      instr->hydrogen()->value()->IsHeapObject()
25971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
25980ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
25991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Condition true_cond = EmitIsString(
26001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      reg, temp, instr->FalseLabel(chunk_), check_needed);
26010ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
26021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, true_cond);
26030ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry}
26040ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
26050ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
2606a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
260756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Operand input = ToOperand(instr->value());
2608a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2609a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ test(input, Immediate(kSmiTagMask));
26101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, zero);
2611a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2612a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2613a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
26147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgvoid LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
261556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register input = ToRegister(instr->value());
261656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register temp = ToRegister(instr->temp());
26177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
26181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!instr->hydrogen()->value()->IsHeapObject()) {
26191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    STATIC_ASSERT(kSmiTag == 0);
26201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ JumpIfSmi(input, instr->FalseLabel(chunk_));
26211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
26227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
26237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ test_b(FieldOperand(temp, Map::kBitFieldOffset),
26247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org            1 << Map::kIsUndetectable);
26251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, not_zero);
26267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}
26277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
26287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
26290ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorrystatic Condition ComputeCompareCondition(Token::Value op) {
26300ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  switch (op) {
26310ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    case Token::EQ_STRICT:
26320ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    case Token::EQ:
26330ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      return equal;
26340ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    case Token::LT:
26350ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      return less;
26360ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    case Token::GT:
26370ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      return greater;
26380ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    case Token::LTE:
26390ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      return less_equal;
26400ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    case Token::GTE:
26410ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      return greater_equal;
26420ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    default:
26430ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      UNREACHABLE();
26440ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      return no_condition;
26450ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  }
26460ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry}
26470ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
26480ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
26490ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
26500ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  Token::Value op = instr->op();
26510ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
26528432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
26530ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  CallCode(ic, RelocInfo::CODE_TARGET, instr);
26540ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
26550ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  Condition condition = ComputeCompareCondition(op);
26560ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  __ test(eax, Operand(eax));
26570ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
26581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, condition);
26590ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry}
26600ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
26610ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
26624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgstatic InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
26630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  InstanceType from = instr->from();
26640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  InstanceType to = instr->to();
2665a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (from == FIRST_TYPE) return to;
2666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(from == to || to == LAST_TYPE);
2667a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return from;
2668a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2669a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2670a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
26714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgstatic Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
26720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  InstanceType from = instr->from();
26730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  InstanceType to = instr->to();
2674a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (from == to) return equal;
2675a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (to == LAST_TYPE) return above_equal;
2676a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (from == FIRST_TYPE) return below_equal;
2677a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UNREACHABLE();
2678a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return equal;
2679a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2680a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
268356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register input = ToRegister(instr->value());
268456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register temp = ToRegister(instr->temp());
2685a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
26861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!instr->hydrogen()->value()->IsHeapObject()) {
26871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ JumpIfSmi(input, instr->FalseLabel(chunk_));
26881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
2689a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
26900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
26911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, BranchCondition(instr->hydrogen()));
2692a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2693a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2694a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
26958f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.orgvoid LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
269656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register input = ToRegister(instr->value());
26978f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  Register result = ToRegister(instr->result());
26988f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
2699c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  __ AssertString(input);
27008f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
27018f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  __ mov(result, FieldOperand(input, String::kHashFieldOffset));
27028f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  __ IndexFromHash(result, result);
27038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org}
27048f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
27058f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
2706a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoHasCachedArrayIndexAndBranch(
2707a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    LHasCachedArrayIndexAndBranch* instr) {
270856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register input = ToRegister(instr->value());
2709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2710a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ test(FieldOperand(input, String::kHashFieldOffset),
2711a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          Immediate(String::kContainsCachedArrayIndexMask));
27121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, equal);
2713a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2714a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2715a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2716a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Branches to a label or falls through with the answer in the z flag.  Trashes
2717f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// the temp registers, but not the input.
2718a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::EmitClassOfTest(Label* is_true,
2719a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                               Label* is_false,
2720a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                               Handle<String>class_name,
2721a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                               Register input,
2722a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                               Register temp,
2723a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                               Register temp2) {
2724a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(!input.is(temp));
2725f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  ASSERT(!input.is(temp2));
2726f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  ASSERT(!temp.is(temp2));
27277b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  __ JumpIfSmi(input, is_false);
2728a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
272959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Function"))) {
2730c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Assuming the following assertions, we can use the same compares to test
2731c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // for both being a function type and being in the object type range.
2732c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
2733c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
2734c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  FIRST_SPEC_OBJECT_TYPE + 1);
2735c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
2736c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  LAST_SPEC_OBJECT_TYPE - 1);
2737c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
2738c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, temp);
2739c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ j(below, is_false);
2740c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ j(equal, is_true);
2741c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ CmpInstanceType(temp, LAST_SPEC_OBJECT_TYPE);
2742c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ j(equal, is_true);
2743a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
2744c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Faster code path to avoid two compares: subtract lower bound from the
2745c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // actual type and do a signed compare with the width of the type range.
2746c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
274756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org    __ movzx_b(temp2, FieldOperand(temp, Map::kInstanceTypeOffset));
2748c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ sub(Operand(temp2), Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
274956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org    __ cmp(Operand(temp2), Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
275056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                                     FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
2751c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ j(above, is_false);
2752a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2753a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2754c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range.
2755a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Check if the constructor in the map is a function.
2756a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(temp, FieldOperand(temp, Map::kConstructorOffset));
2757a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Objects with a non-function constructor have class 'Object'.
2758a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ CmpObjectType(temp, JS_FUNCTION_TYPE, temp2);
275959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Object"))) {
2760a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ j(not_equal, is_true);
2761a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
2762a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ j(not_equal, is_false);
2763a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // temp now contains the constructor function. Grab the
2766a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // instance class name from there.
2767a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(temp, FieldOperand(temp, JSFunction::kSharedFunctionInfoOffset));
2768a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(temp, FieldOperand(temp,
2769a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                            SharedFunctionInfo::kInstanceClassNameOffset));
27704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // The class name we are testing against is internalized since it's a literal.
27714a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // The name in the constructor is internalized because of the way the context
27724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // is booted.  This routine isn't expected to work for random API-created
2773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // classes and it doesn't have to because you can't access it with natives
27744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // syntax.  Since both sides are internalized it is sufficient to use an
27754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // identity comparison.
2776a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ cmp(temp, class_name);
2777a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // End with the answer in the z flag.
2778a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2779a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2780a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
278256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register input = ToRegister(instr->value());
278356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register temp = ToRegister(instr->temp());
278456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register temp2 = ToRegister(instr->temp2());
2785f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
2786a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Handle<String> class_name = instr->hydrogen()->class_name();
2787a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
27881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
27891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      class_name, input, temp, temp2);
2790a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
27911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, equal);
2792a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2794a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2795a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
279656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register reg = ToRegister(instr->value());
2797a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
27981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, equal);
2799a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2800a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2801a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2802a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2803d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  // Object and function are in fixed registers defined by the stub.
2804496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
28055f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  InstanceofStub stub(InstanceofStub::kArgsInRegisters);
28068432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2807a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
280883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label true_value, done;
2809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ test(eax, Operand(eax));
281083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ j(zero, &true_value, Label::kNear);
2811ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ mov(ToRegister(instr->result()), factory()->false_value());
281283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ jmp(&done, Label::kNear);
2813a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&true_value);
2814ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ mov(ToRegister(instr->result()), factory()->true_value());
2815a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&done);
2816a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2817a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2818a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2819d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.orgvoid LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2820d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  class DeferredInstanceOfKnownGlobal: public LDeferredCode {
2821d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org   public:
2822d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
2823d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                  LInstanceOfKnownGlobal* instr)
2824d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
2825d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    virtual void Generate() {
282627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_);
2827d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    }
2828c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    virtual LInstruction* instr() { return instr_; }
2829d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    Label* map_check() { return &map_check_; }
2830d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org   private:
2831d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    LInstanceOfKnownGlobal* instr_;
2832d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    Label map_check_;
2833d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  };
2834d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
2835d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  DeferredInstanceOfKnownGlobal* deferred;
28367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2837d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
2838d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  Label done, false_result;
283956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register object = ToRegister(instr->value());
284056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register temp = ToRegister(instr->temp());
2841d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
284249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // A Smi is not an instance of anything.
28437b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  __ JumpIfSmi(object, &false_result);
2844d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
284549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // This is the inlined call site instanceof cache. The two occurences of the
2846d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  // hole value will be patched to the last map/result pair generated by the
2847d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  // instanceof stub.
284883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label cache_miss;
284956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register map = ToRegister(instr->temp());
2850d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  __ mov(map, FieldOperand(object, HeapObject::kMapOffset));
2851d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  __ bind(deferred->map_check());  // Label for calculating code patching.
285241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Handle<Cell> cache_cell = factory()->NewCell(factory()->the_hole_value());
285341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  __ cmp(map, Operand::ForCell(cache_cell));  // Patched to cached map.
28547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ j(not_equal, &cache_miss, Label::kNear);
2855ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ mov(eax, factory()->the_hole_value());  // Patched to either true or false.
2856d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  __ jmp(&done);
2857d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
285849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // The inlined call site cache did not match. Check for null and string
285949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // before calling the deferred code.
2860d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  __ bind(&cache_miss);
286149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // Null is not an instance of anything.
2862ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ cmp(object, factory()->null_value());
2863d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  __ j(equal, &false_result);
2864d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
2865d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  // String values are not instances of anything.
2866d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  Condition is_string = masm_->IsObjectStringType(object, temp, temp);
2867d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  __ j(is_string, &false_result);
2868d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
2869d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  // Go to the deferred code.
2870d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  __ jmp(deferred->entry());
2871d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
2872d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  __ bind(&false_result);
2873ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ mov(ToRegister(instr->result()), factory()->false_value());
2874d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
2875d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  // Here result has either true or false. Deferred code also produces true or
2876d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  // false object.
2877d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  __ bind(deferred->exit());
2878d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  __ bind(&done);
2879d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org}
2880d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
2881d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
288227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
288327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                               Label* map_check) {
288444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  PushSafepointRegistersScope scope(this);
2885d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
2886d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  InstanceofStub::Flags flags = InstanceofStub::kNoFlags;
2887d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  flags = static_cast<InstanceofStub::Flags>(
2888d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      flags | InstanceofStub::kArgsInRegisters);
2889d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  flags = static_cast<InstanceofStub::Flags>(
2890d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      flags | InstanceofStub::kCallSiteInlineCheck);
2891d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  flags = static_cast<InstanceofStub::Flags>(
2892d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      flags | InstanceofStub::kReturnTrueFalseObject);
2893d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  InstanceofStub stub(flags);
2894d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
289544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // Get the temp register reserved by the instruction. This needs to be a
289644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // register which is pushed last by PushSafepointRegisters as top of the
289744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // stack is used to pass the offset to the location of the map check to
289844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // the stub.
289956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register temp = ToRegister(instr->temp());
290044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0);
290164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ LoadHeapObject(InstanceofStub::right(), instr->function());
2902ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  static const int kAdditionalDelta = 13;
2903d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
2904d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  __ mov(temp, Immediate(delta));
29053a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  __ StoreToSafepointRegisterSlot(temp, temp);
29068432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCodeGeneric(stub.GetCode(isolate()),
290744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                  RelocInfo::CODE_TARGET,
290844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                  instr,
290944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                  RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
29101044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // Get the deoptimization index of the LLazyBailout-environment that
29111044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // corresponds to this instruction.
29121044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
291327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
291427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
2915d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  // Put the result value into the eax slot and restore all registers.
29163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  __ StoreToSafepointRegisterSlot(eax, eax);
2917d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org}
2918d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
2919d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
292071fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgvoid LCodeGen::DoInstanceSize(LInstanceSize* instr) {
292171fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  Register object = ToRegister(instr->object());
292271fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  Register result = ToRegister(instr->result());
292371fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  __ mov(result, FieldOperand(object, HeapObject::kMapOffset));
292471fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  __ movzx_b(result, FieldOperand(result, Map::kInstanceSizeOffset));
292571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org}
292671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
292771fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
2928a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCmpT(LCmpT* instr) {
2929a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Token::Value op = instr->op();
2930a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
29318432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
2932ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET, instr);
2933a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2934a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Condition condition = ComputeCompareCondition(op);
293583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label true_value, done;
2936a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ test(eax, Operand(eax));
293783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ j(condition, &true_value, Label::kNear);
2938ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ mov(ToRegister(instr->result()), factory()->false_value());
293983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ jmp(&done, Label::kNear);
2940a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&true_value);
2941ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ mov(ToRegister(instr->result()), factory()->true_value());
2942a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&done);
2943a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
2944a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2945a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
29466e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgvoid LCodeGen::EmitReturn(LReturn* instr, bool dynamic_frame_alignment) {
29476e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  int extra_value_count = dynamic_frame_alignment ? 2 : 1;
29486e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
29496e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  if (instr->has_constant_parameter_count()) {
29506e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    int parameter_count = ToInteger32(instr->constant_parameter_count());
29516e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    if (dynamic_frame_alignment && FLAG_debug_code) {
29526e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      __ cmp(Operand(esp,
29536e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org                     (parameter_count + extra_value_count) * kPointerSize),
29546e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org             Immediate(kAlignmentZapValue));
2955594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      __ Assert(equal, kExpectedAlignmentMarker);
29566e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    }
29576e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    __ Ret((parameter_count + extra_value_count) * kPointerSize, ecx);
29586e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  } else {
29596e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    Register reg = ToRegister(instr->parameter_count());
2960ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    // The argument count parameter is a smi
2961ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    __ SmiUntag(reg);
29626e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    Register return_addr_reg = reg.is(ecx) ? ebx : ecx;
29636e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    if (dynamic_frame_alignment && FLAG_debug_code) {
29646e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      ASSERT(extra_value_count == 2);
29656e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      __ cmp(Operand(esp, reg, times_pointer_size,
29666e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org                     extra_value_count * kPointerSize),
29676e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org             Immediate(kAlignmentZapValue));
2968594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      __ Assert(equal, kExpectedAlignmentMarker);
29696e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    }
29706e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
29716e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    // emit code to restore stack based on instr->parameter_count()
29726e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    __ pop(return_addr_reg);  // save return address
29736e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    if (dynamic_frame_alignment) {
29746e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      __ inc(reg);  // 1 more for alignment
29756e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    }
29766e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    __ shl(reg, kPointerSizeLog2);
29776e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    __ add(esp, reg);
29786e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    __ jmp(return_addr_reg);
29796e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
29806e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org}
29816e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
29826e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
2983a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoReturn(LReturn* instr) {
2984a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (FLAG_trace && info()->IsOptimizing()) {
2985496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    // Preserve the return value on the stack and rely on the runtime call
2986496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    // to return the value in the same register.  We're leaving the code
2987496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    // managed by the register allocator and tearing down the frame, it's
2988496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    // safe to write to the context register.
2989a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ push(eax);
2990496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2991a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ CallRuntime(Runtime::kTraceExit, 1);
2992a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
299394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) {
299494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    ASSERT(NeedsEagerFrame());
2995750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    CpuFeatureScope scope(masm(), SSE2);
299694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    BitVector* doubles = chunk()->allocated_double_registers();
299794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    BitVector::Iterator save_iterator(doubles);
299894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    int count = 0;
299994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    while (!save_iterator.Done()) {
300094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      __ movdbl(XMMRegister::FromAllocationIndex(save_iterator.Current()),
300194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                MemOperand(esp, count * kDoubleSize));
300294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      save_iterator.Advance();
300394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      count++;
300494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    }
300594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  }
30067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (dynamic_frame_alignment_) {
30077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    // Fetch the state of the dynamic frame alignment.
30087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    __ mov(edx, Operand(ebp,
30097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      JavaScriptFrameConstants::kDynamicAlignmentStateOffset));
30107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
30114e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  int no_frame_start = -1;
3012a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (NeedsEagerFrame()) {
3013a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    __ mov(esp, ebp);
3014a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    __ pop(ebp);
30154e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    no_frame_start = masm_->pc_offset();
3016a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
30177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (dynamic_frame_alignment_) {
30187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    Label no_padding;
30197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    __ cmp(edx, Immediate(kNoAlignmentPadding));
30207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    __ j(equal, &no_padding);
30216e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
30226e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    EmitReturn(instr, true);
30237028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    __ bind(&no_padding);
30247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
30256e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
30266e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  EmitReturn(instr, false);
30274e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (no_frame_start != -1) {
30284e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    info()->AddNoFrameRange(no_frame_start, masm_->pc_offset());
30294e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
3030a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3031a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3032a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3033c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgvoid LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
3034a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register result = ToRegister(instr->result());
303541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  __ mov(result, Operand::ForCell(instr->hydrogen()->cell()));
3036c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (instr->hydrogen()->RequiresHoleCheck()) {
3037ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    __ cmp(result, factory()->the_hole_value());
3038a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizeIf(equal, instr->environment());
3039a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
3040a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3041a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3042a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3043c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgvoid LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
3044c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
30451044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  ASSERT(ToRegister(instr->global_object()).is(edx));
3046c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
3047c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3048c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  __ mov(ecx, instr->name());
3049c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET :
3050c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org                                               RelocInfo::CODE_TARGET_CONTEXT;
3051c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
3052ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallCode(ic, mode, instr);
3053c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org}
3054c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3055c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
305674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
3057e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org  Register value = ToRegister(instr->value());
3058b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  Handle<PropertyCell> cell_handle = instr->hydrogen()->cell();
3059378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
3060378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // If the cell we are storing to contains the hole it could have
3061378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // been deleted from the property dictionary. In that case, we need
3062378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // to update the property details in the property dictionary to mark
3063378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // it as no longer deleted. We deoptimize in that case.
3064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (instr->hydrogen()->RequiresHoleCheck()) {
306541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    __ cmp(Operand::ForCell(cell_handle), factory()->the_hole_value());
3066378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    DeoptimizeIf(equal, instr->environment());
3067378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
3068378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
3069378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Store the value.
307041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  __ mov(Operand::ForCell(cell_handle), value);
307164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Cells are always rescanned, so no write barrier here.
3072a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3073a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3074a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
307574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.orgvoid LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) {
307674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
307774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT(ToRegister(instr->global_object()).is(edx));
307874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ASSERT(ToRegister(instr->value()).is(eax));
307974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
308074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ mov(ecx, instr->name());
30811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
308244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      ? isolate()->builtins()->StoreIC_Initialize_Strict()
308344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      : isolate()->builtins()->StoreIC_Initialize();
3084ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
308574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org}
308674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
308774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
3088c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
308983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  Register context = ToRegister(instr->context());
3090c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  Register result = ToRegister(instr->result());
309183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  __ mov(result, ContextOperand(context, instr->slot_index()));
30927ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
309364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (instr->hydrogen()->RequiresHoleCheck()) {
309464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ cmp(result, factory()->the_hole_value());
30957ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    if (instr->hydrogen()->DeoptimizesOnHole()) {
30967ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      DeoptimizeIf(equal, instr->environment());
30977ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    } else {
30987ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      Label is_not_hole;
30997ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      __ j(not_equal, &is_not_hole, Label::kNear);
31007ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      __ mov(result, factory()->undefined_value());
31017ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      __ bind(&is_not_hole);
31027ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    }
310364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
310483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org}
310583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
310683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
310783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgvoid LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
310883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  Register context = ToRegister(instr->context());
310983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  Register value = ToRegister(instr->value());
31107ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
31117ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org  Label skip_assignment;
31127ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
311364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Operand target = ContextOperand(context, instr->slot_index());
311464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (instr->hydrogen()->RequiresHoleCheck()) {
311564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ cmp(target, factory()->the_hole_value());
31167ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    if (instr->hydrogen()->DeoptimizesOnHole()) {
31177ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      DeoptimizeIf(equal, instr->environment());
31187ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    } else {
31197ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      __ j(not_equal, &skip_assignment, Label::kNear);
31207ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    }
312164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
31227ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
312364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ mov(target, value);
3124394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (instr->hydrogen()->NeedsWriteBarrier()) {
3125394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    SmiCheck check_needed =
31261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        instr->hydrogen()->value()->IsHeapObject()
31271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org            ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
312856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    Register temp = ToRegister(instr->temp());
312983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    int offset = Context::SlotOffset(instr->slot_index());
3130394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    __ RecordWriteContextSlot(context,
3131394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                              offset,
3132394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                              value,
3133394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                              temp,
3134750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                              GetSaveFPRegsMode(),
3135394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                              EMIT_REMEMBERED_SET,
3136394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                              check_needed);
313783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  }
31387ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
31397ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org  __ bind(&skip_assignment);
3140c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org}
3141c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
3142c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
3143a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
314453ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  HObjectAccess access = instr->hydrogen()->access();
314553ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  int offset = access.offset();
3146d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
3147d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (access.IsExternalMemory()) {
3148d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    Register result = ToRegister(instr->result());
3149d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    if (instr->object()->IsConstantOperand()) {
3150d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      ExternalReference external_reference = ToExternalReference(
3151d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          LConstantOperand::cast(instr->object()));
3152d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      __ mov(result, MemOperand::StaticVariable(external_reference));
3153d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    } else {
3154d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      __ mov(result, MemOperand(ToRegister(instr->object()), offset));
3155d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    }
3156d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return;
3157d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
3158d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
31597979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  Register object = ToRegister(instr->object());
316057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  if (FLAG_track_double_fields &&
316157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      instr->hydrogen()->representation().IsDouble()) {
3162f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (CpuFeatures::IsSupported(SSE2)) {
3163f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      CpuFeatureScope scope(masm(), SSE2);
3164f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      XMMRegister result = ToDoubleRegister(instr->result());
316557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      __ movdbl(result, FieldOperand(object, offset));
3166f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    } else {
3167169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset));
3168f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    }
316957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    return;
317057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
317157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
317257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Register result = ToRegister(instr->result());
317353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  if (access.IsInobject()) {
317457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ mov(result, FieldOperand(object, offset));
317557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  } else {
317657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
317757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ mov(result, FieldOperand(result, offset));
3178a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
3179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3180a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3181a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
318264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid LCodeGen::EmitPushTaggedOperand(LOperand* operand) {
318364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  ASSERT(!operand->IsDoubleRegister());
318464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (operand->IsConstantOperand()) {
318564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    Handle<Object> object = ToHandle(LConstantOperand::cast(operand));
318679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    AllowDeferredHandleDereference smi_check;
318764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    if (object->IsSmi()) {
318864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      __ Push(Handle<Smi>::cast(object));
318964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    } else {
319064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      __ PushHeapObject(Handle<HeapObject>::cast(object));
319164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    }
319264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  } else if (operand->IsRegister()) {
319364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ push(ToRegister(operand));
319464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  } else {
319564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ push(ToOperand(operand));
31967979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  }
31977979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org}
31987979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
31997979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
3200a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
3201496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
32021044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  ASSERT(ToRegister(instr->object()).is(edx));
3203a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
3204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(ecx, instr->name());
32067979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
3207ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET, instr);
3208a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3209a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
32119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgvoid LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
32129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  Register function = ToRegister(instr->function());
321356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register temp = ToRegister(instr->temp());
32149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  Register result = ToRegister(instr->result());
32159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
32169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  // Check that the function really is a function.
32179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  __ CmpObjectType(function, JS_FUNCTION_TYPE, result);
32189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  DeoptimizeIf(not_equal, instr->environment());
32199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
32209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  // Check whether the function has an instance prototype.
322183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label non_instance;
32229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  __ test_b(FieldOperand(result, Map::kBitFieldOffset),
32239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            1 << Map::kHasNonInstancePrototype);
322483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ j(not_zero, &non_instance, Label::kNear);
32259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
32269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  // Get the prototype or initial map from the function.
32279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  __ mov(result,
32289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
32299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
32309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  // Check that the function has a prototype or an initial map.
3231ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ cmp(Operand(result), Immediate(factory()->the_hole_value()));
32329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  DeoptimizeIf(equal, instr->environment());
32339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
32349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  // If the function does not have an initial map, we're done.
323583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label done;
32369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  __ CmpObjectType(result, MAP_TYPE, temp);
323783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ j(not_equal, &done, Label::kNear);
32389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
32399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  // Get the prototype from the initial map.
32409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  __ mov(result, FieldOperand(result, Map::kPrototypeOffset));
324183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ jmp(&done, Label::kNear);
32429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
32439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  // Non-instance prototype: Fetch prototype from constructor field
32449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  // in the function's map.
32459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  __ bind(&non_instance);
32469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  __ mov(result, FieldOperand(result, Map::kConstructorOffset));
32479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
32489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  // All done.
32499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  __ bind(&done);
32509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
32519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
32529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
32534d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.orgvoid LCodeGen::DoLoadExternalArrayPointer(
32544d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    LLoadExternalArrayPointer* instr) {
3255496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  Register result = ToRegister(instr->result());
325656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register input = ToRegister(instr->object());
32574d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  __ mov(result, FieldOperand(input,
32584d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org                              ExternalArray::kExternalPointerOffset));
3259496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
3260496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
3261496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
3262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register arguments = ToRegister(instr->arguments());
3264a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register result = ToRegister(instr->result());
326577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (instr->length()->IsConstantOperand() &&
326677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      instr->index()->IsConstantOperand()) {
326777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
326877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
326977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    int index = (const_length - const_index) + 1;
327077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    __ mov(result, Operand(arguments, index * kPointerSize));
327177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  } else {
327277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    Register length = ToRegister(instr->length());
327377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    Operand index = ToOperand(instr->index());
327477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    // There are two words between the frame pointer and the last argument.
327577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    // Subtracting from length accounts for one of them add one more.
327677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    __ sub(length, index);
327777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    __ mov(result, Operand(arguments, length, times_4, kPointerSize));
327877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  }
3279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3282e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3283e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  ElementsKind elements_kind = instr->elements_kind();
3284eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  LOperand* key = instr->key();
3285eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  if (!key->IsConstantOperand() &&
3286eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org      ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
3287eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org                                  elements_kind)) {
3288eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org    __ SmiUntag(ToRegister(key));
3289e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
3290e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Operand operand(BuildFastArrayOperand(
3291e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      instr->elements(),
3292eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org      key,
3293e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      instr->hydrogen()->key()->representation(),
3294e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      elements_kind,
3295e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      0,
3296e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      instr->additional_index()));
3297e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3298a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (CpuFeatures::IsSupported(SSE2)) {
3299750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      CpuFeatureScope scope(masm(), SSE2);
3300a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      XMMRegister result(ToDoubleRegister(instr->result()));
3301a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ movss(result, operand);
3302a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ cvtss2sd(result, result);
3303a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    } else {
3304169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand);
3305a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
3306e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3307a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (CpuFeatures::IsSupported(SSE2)) {
3308750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      CpuFeatureScope scope(masm(), SSE2);
3309a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ movdbl(ToDoubleRegister(instr->result()), operand);
3310a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    } else {
3311169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      X87Mov(ToX87Register(instr->result()), operand);
3312a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
3313e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  } else {
3314e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    Register result(ToRegister(instr->result()));
3315e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    switch (elements_kind) {
3316e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case EXTERNAL_BYTE_ELEMENTS:
3317e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        __ movsx_b(result, operand);
3318e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        break;
3319e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case EXTERNAL_PIXEL_ELEMENTS:
3320e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3321e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        __ movzx_b(result, operand);
3322e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        break;
3323e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case EXTERNAL_SHORT_ELEMENTS:
3324e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        __ movsx_w(result, operand);
3325e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        break;
3326e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3327e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        __ movzx_w(result, operand);
3328e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        break;
3329e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case EXTERNAL_INT_ELEMENTS:
3330e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        __ mov(result, operand);
3331e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        break;
3332e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3333e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        __ mov(result, operand);
3334e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3335e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          __ test(result, Operand(result));
3336e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          DeoptimizeIf(negative, instr->environment());
3337e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        }
3338e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        break;
3339e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case EXTERNAL_FLOAT_ELEMENTS:
3340e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case EXTERNAL_DOUBLE_ELEMENTS:
3341e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case FAST_SMI_ELEMENTS:
3342e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case FAST_ELEMENTS:
3343e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case FAST_DOUBLE_ELEMENTS:
3344e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case FAST_HOLEY_SMI_ELEMENTS:
3345e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case FAST_HOLEY_ELEMENTS:
3346e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case FAST_HOLEY_DOUBLE_ELEMENTS:
3347e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case DICTIONARY_ELEMENTS:
3348e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case NON_STRICT_ARGUMENTS_ELEMENTS:
3349e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        UNREACHABLE();
3350e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        break;
33517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    }
335283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
335383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
335483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
335583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
3356a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
3357830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (instr->hydrogen()->RequiresHoleCheck()) {
3358830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
3359830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        sizeof(kHoleNanLower32);
3360830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    Operand hole_check_operand = BuildFastArrayOperand(
3361830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        instr->elements(), instr->key(),
3362304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org        instr->hydrogen()->key()->representation(),
3363830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        FAST_DOUBLE_ELEMENTS,
3364830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        offset,
3365830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        instr->additional_index());
3366830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
3367830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    DeoptimizeIf(equal, instr->environment());
3368830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  }
3369717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
3370717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  Operand double_load_operand = BuildFastArrayOperand(
33710e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org      instr->elements(),
33720e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org      instr->key(),
3373304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      instr->hydrogen()->key()->representation(),
33740e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org      FAST_DOUBLE_ELEMENTS,
33750e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org      FixedDoubleArray::kHeaderSize - kHeapObjectTag,
33760e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org      instr->additional_index());
3377a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (CpuFeatures::IsSupported(SSE2)) {
3378750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    CpuFeatureScope scope(masm(), SSE2);
3379a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    XMMRegister result = ToDoubleRegister(instr->result());
3380a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    __ movdbl(result, double_load_operand);
3381a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  } else {
3382169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    X87Mov(ToX87Register(instr->result()), double_load_operand);
3383a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
3384717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org}
3385717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
3386717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
3387e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3388e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Register result = ToRegister(instr->result());
3389e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
3390e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // Load the result.
3391e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  __ mov(result,
3392e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org         BuildFastArrayOperand(instr->elements(),
3393e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                               instr->key(),
3394e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                               instr->hydrogen()->key()->representation(),
3395e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                               FAST_ELEMENTS,
3396e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                               FixedArray::kHeaderSize - kHeapObjectTag,
3397e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                               instr->additional_index()));
3398e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
3399e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // Check for the hole value.
3400e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (instr->hydrogen()->RequiresHoleCheck()) {
3401e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3402e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      __ test(result, Immediate(kSmiTagMask));
3403e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      DeoptimizeIf(not_equal, instr->environment());
3404e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    } else {
3405e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      __ cmp(result, factory()->the_hole_value());
3406e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      DeoptimizeIf(equal, instr->environment());
3407e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    }
3408e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
3409e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
3410e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
3411e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
3412e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3413e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (instr->is_external()) {
3414e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    DoLoadKeyedExternalArray(instr);
3415e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  } else if (instr->hydrogen()->representation().IsDouble()) {
3416e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    DoLoadKeyedFixedDoubleArray(instr);
3417e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  } else {
3418e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    DoLoadKeyedFixedArray(instr);
3419e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
3420e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
3421e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
3422e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
3423717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.orgOperand LCodeGen::BuildFastArrayOperand(
3424b645116853c677aca8a316381b87441ba6004f67danno@chromium.org    LOperand* elements_pointer,
34256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    LOperand* key,
3426304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    Representation key_representation,
342783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    ElementsKind elements_kind,
34280e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org    uint32_t offset,
34290e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org    uint32_t additional_index) {
3430b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  Register elements_pointer_reg = ToRegister(elements_pointer);
34314e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  int element_shift_size = ElementsKindToShiftSize(elements_kind);
34324e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  int shift_size = element_shift_size;
343383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (key->IsConstantOperand()) {
343483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    int constant_value = ToInteger32(LConstantOperand::cast(key));
343583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (constant_value & 0xF0000000) {
3436594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Abort(kArrayIndexConstantValueTooBig);
343783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
3438b645116853c677aca8a316381b87441ba6004f67danno@chromium.org    return Operand(elements_pointer_reg,
34390e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org                   ((constant_value + additional_index) << shift_size)
34400e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org                       + offset);
344183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
3442068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    // Take the tag bit into account while computing the shift size.
3443a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (key_representation.IsSmi() && (shift_size >= 1)) {
3444068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      shift_size -= kSmiTagSize;
3445068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    }
344683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
34470e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org    return Operand(elements_pointer_reg,
34480e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org                   ToRegister(key),
34490e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org                   scale_factor,
34504e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org                   offset + (additional_index << element_shift_size));
345183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
3452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3453a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3454a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3455a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3456496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
3457a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->object()).is(edx));
34581044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  ASSERT(ToRegister(instr->key()).is(ecx));
3459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
34607979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
3461ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET, instr);
3462a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3463a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3464a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
3466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register result = ToRegister(instr->result());
3467a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
346828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  if (instr->hydrogen()->from_inlined()) {
346928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ lea(result, Operand(esp, -2 * kPointerSize));
347028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  } else {
347128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    // Check for arguments adapter frame.
347228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    Label done, adapted;
347328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
347428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ mov(result, Operand(result, StandardFrameConstants::kContextOffset));
347528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ cmp(Operand(result),
347628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org           Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
347728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ j(equal, &adapted, Label::kNear);
347828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
347928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    // No arguments adaptor frame.
348028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ mov(result, Operand(ebp));
348128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ jmp(&done, Label::kNear);
3482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
348328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    // Arguments adaptor frame present.
348428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ bind(&adapted);
348528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
3486b2a1c078e6f552a66c1426482a3d007b7ea7af7ddanno@chromium.org
348728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    // Result is the frame pointer for the frame if not adapted and for the real
348828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    // frame below the adaptor frame if adapted.
348928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ bind(&done);
349028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  }
3491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3493a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
349556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Operand elem = ToOperand(instr->elements());
3496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register result = ToRegister(instr->result());
3497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
349883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label done;
3499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3500d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  // If no arguments adaptor frame the number of arguments is fixed.
3501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ cmp(ebp, elem);
3502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(result, Immediate(scope()->num_parameters()));
350383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ j(equal, &done, Label::kNear);
3504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Arguments adaptor frame present. Get argument length from there.
3506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
3507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(result, Operand(result,
3508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                         ArgumentsAdaptorFrameConstants::kLengthOffset));
3509a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ SmiUntag(result);
3510a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3511d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  // Argument length is in result register.
3512a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&done);
3513a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3514a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3516154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgvoid LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register receiver = ToRegister(instr->receiver());
3518496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  Register function = ToRegister(instr->function());
351956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register scratch = ToRegister(instr->temp());
3520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3521d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  // If the receiver is null or undefined, we have to pass the global
3522d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  // object as a receiver to normal functions. Values have to be
3523d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  // passed unchanged to builtins and strict-mode functions.
352483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label global_object, receiver_ok;
3525d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
3526d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  // Do not transform the receiver to object for strict mode
3527d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  // functions.
3528d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  __ mov(scratch,
3529d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org         FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
3530d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  __ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset),
3531d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org            1 << SharedFunctionInfo::kStrictModeBitWithinByte);
3532412fa510dce700c25e3ff85ee85dd32dd6cb6b87danno@chromium.org  __ j(not_equal, &receiver_ok);  // A near jump is not sufficient here!
3533d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
3534d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  // Do not transform the receiver to object for builtins.
3535d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset),
3536d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org            1 << SharedFunctionInfo::kNativeBitWithinByte);
3537412fa510dce700c25e3ff85ee85dd32dd6cb6b87danno@chromium.org  __ j(not_equal, &receiver_ok);
3538d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
3539d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  // Normal function. Replace undefined or null with global receiver.
3540ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ cmp(receiver, factory()->null_value());
354183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ j(equal, &global_object, Label::kNear);
3542ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ cmp(receiver, factory()->undefined_value());
354383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ j(equal, &global_object, Label::kNear);
3544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3545496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  // The receiver should be a JS object.
3546496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  __ test(receiver, Immediate(kSmiTagMask));
3547496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  DeoptimizeIf(equal, instr->environment());
3548d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch);
3549496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  DeoptimizeIf(below, instr->environment());
355083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ jmp(&receiver_ok, Label::kNear);
3551496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
3552496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  __ bind(&global_object);
3553496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  // TODO(kmillikin): We have a hydrogen value for the global object.  See
3554496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  // if it's better to use it than to explicitly fetch it from the context
3555496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  // here.
3556496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  __ mov(receiver, Operand(ebp, StandardFrameConstants::kContextOffset));
355746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  __ mov(receiver, ContextOperand(receiver, Context::GLOBAL_OBJECT_INDEX));
3558d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  __ mov(receiver,
3559d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org         FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
3560496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  __ bind(&receiver_ok);
3561154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org}
3562154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org
3563154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org
3564154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgvoid LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3565154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  Register receiver = ToRegister(instr->receiver());
3566154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  Register function = ToRegister(instr->function());
3567154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  Register length = ToRegister(instr->length());
3568154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  Register elements = ToRegister(instr->elements());
3569154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  ASSERT(receiver.is(eax));  // Used for parameter count.
3570154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  ASSERT(function.is(edi));  // Required by InvokeFunction.
3571154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
3572a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3573a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Copy the arguments to this function possibly from the
3574a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // adaptor frame below it.
3575a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const uint32_t kArgumentsLimit = 1 * KB;
3576a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ cmp(length, kArgumentsLimit);
3577a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DeoptimizeIf(above, instr->environment());
3578a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ push(receiver);
3580a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(receiver, length);
3581a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3582a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Loop through the arguments pushing them onto the execution
3583a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // stack.
358483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label invoke, loop;
3585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // length is a small non-negative integer, due to the test above.
3586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ test(length, Operand(length));
358783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ j(zero, &invoke, Label::kNear);
3588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&loop);
3589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize));
3590a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ dec(length);
3591a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ j(not_zero, &loop);
3592a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3593a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Invoke the function.
3594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&invoke);
35951044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  ASSERT(instr->HasPointerMap());
359631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  LPointerMap* pointers = instr->pointer_map();
359731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  RecordPosition(pointers->position());
359827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  SafepointGenerator safepoint_generator(
359927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      this, pointers, Safepoint::kLazyDeopt);
3600160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ParameterCount actual(eax);
3601d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  __ InvokeFunction(function, actual, CALL_FUNCTION,
3602d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org                    safepoint_generator, CALL_AS_METHOD);
3603a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3604a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3605a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
36064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid LCodeGen::DoDebugBreak(LDebugBreak* instr) {
36074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  __ int3();
36084e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org}
36094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
36104e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
3611a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoPushArgument(LPushArgument* instr) {
361256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* argument = instr->value();
361364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  EmitPushTaggedOperand(argument);
3614a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3615a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3616a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
361728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.orgvoid LCodeGen::DoDrop(LDrop* instr) {
361828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  __ Drop(instr->count());
361928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org}
362028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
362128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
3622d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.orgvoid LCodeGen::DoThisFunction(LThisFunction* instr) {
3623d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  Register result = ToRegister(instr->result());
36245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  __ mov(result, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
3625d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org}
3626d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
3627d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
362883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgvoid LCodeGen::DoContext(LContext* instr) {
362983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  Register result = ToRegister(instr->result());
36304cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (info()->IsOptimizing()) {
36314cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    __ mov(result, Operand(ebp, StandardFrameConstants::kContextOffset));
36324cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  } else {
36334cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    // If there is no frame, the context must be in esi.
36344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    ASSERT(result.is(esi));
36354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
363683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org}
363783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
363883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
363983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgvoid LCodeGen::DoOuterContext(LOuterContext* instr) {
364083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  Register context = ToRegister(instr->context());
364183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  Register result = ToRegister(instr->result());
36426d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  __ mov(result,
36436d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org         Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
364483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org}
364583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
364683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
364756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.orgvoid LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
364856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
364956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ push(esi);  // The context is the first argument.
365056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ push(Immediate(instr->hydrogen()->pairs()));
365156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags())));
365256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  CallRuntime(Runtime::kDeclareGlobals, 3, instr);
365356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org}
365456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
365556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
3656a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoGlobalObject(LGlobalObject* instr) {
365783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  Register context = ToRegister(instr->context());
3658a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register result = ToRegister(instr->result());
365946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  __ mov(result,
366046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org         Operand(context, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
3661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3663a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3664a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
366583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  Register global = ToRegister(instr->global());
3666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register result = ToRegister(instr->result());
366783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  __ mov(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset));
3668a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3669a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3670a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3671a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::CallKnownFunction(Handle<JSFunction> function,
367232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                                 int formal_parameter_count,
3673a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                 int arity,
367440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                 LInstruction* instr,
3675fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                                 CallKind call_kind,
3676fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                                 EDIState edi_state) {
367732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  bool dont_adapt_arguments =
367832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
367932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  bool can_invoke_directly =
368032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      dont_adapt_arguments || formal_parameter_count == arity;
3681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LPointerMap* pointers = instr->pointer_map();
3683a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  RecordPosition(pointers->position());
3684a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
36852efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  if (can_invoke_directly) {
3686fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    if (edi_state == EDI_UNINITIALIZED) {
3687fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org      __ LoadHeapObject(edi, function);
3688fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    }
36892efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
3690b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    // Change context.
3691b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
36922efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
36932efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    // Set eax to arguments count if adaption is not needed. Assumes that eax
36942efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    // is available to write to at this point.
369532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    if (dont_adapt_arguments) {
36962efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org      __ mov(eax, arity);
36972efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    }
36982efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
36992efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    // Invoke function directly.
37002efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    __ SetCallKind(ecx, call_kind);
370132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    if (function.is_identical_to(info()->closure())) {
37022efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org      __ CallSelf();
37032efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    } else {
37042efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org      __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset));
37052efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    }
37062efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3707a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
37082efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    // We need to adapt arguments.
37092efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    SafepointGenerator generator(
37102efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org        this, pointers, Safepoint::kLazyDeopt);
37112efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    ParameterCount count(arity);
371232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    ParameterCount expected(formal_parameter_count);
371332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ InvokeFunction(
371432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org        function, expected, count, CALL_FUNCTION, generator, call_kind);
3715a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
3716a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3717a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3718a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3719a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
3720a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
372132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  CallKnownFunction(instr->hydrogen()->function(),
372232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                    instr->hydrogen()->formal_parameter_count(),
372340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                    instr->arity(),
372440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                    instr,
3725fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    CALL_AS_METHOD,
3726fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    EDI_UNINITIALIZED);
3727a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3728a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3729a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3730e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3731ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  Register input_reg = ToRegister(instr->value());
3732a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
3733ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org         factory()->heap_number_map());
3734a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DeoptimizeIf(not_equal, instr->environment());
3735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3736fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  Label slow, allocated, done;
3737a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register tmp = input_reg.is(eax) ? ecx : eax;
3738a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx;
3739a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3740a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Preserve the value of all registers.
374144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  PushSafepointRegistersScope scope(this);
3742a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3743a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset));
37440a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // Check the sign of the argument. If the argument is positive, just
37450a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // return it. We do not need to patch the stack since |input| and
37460a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // |result| are the same register and |input| will be restored
37470a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // unchanged by popping safepoint registers.
3748a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ test(tmp, Immediate(HeapNumber::kSignMask));
3749fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  __ j(zero, &done);
3750a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3751a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ AllocateHeapNumber(tmp, tmp2, no_reg, &slow);
3752fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  __ jmp(&allocated, Label::kNear);
3753a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3754a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Slow case: Call the runtime system to do the number allocation.
3755a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&slow);
3756ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0,
3757ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org                          instr, instr->context());
3758a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Set the pointer to the new heap number in tmp.
3759a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (!tmp.is(eax)) __ mov(tmp, eax);
3760a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Restore input_reg after call to runtime.
37613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  __ LoadFromSafepointRegisterSlot(input_reg, input_reg);
3762a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3763a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&allocated);
3764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kExponentOffset));
3765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ and_(tmp2, ~HeapNumber::kSignMask);
3766a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(FieldOperand(tmp, HeapNumber::kExponentOffset), tmp2);
3767a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kMantissaOffset));
3768a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(FieldOperand(tmp, HeapNumber::kMantissaOffset), tmp2);
37693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  __ StoreToSafepointRegisterSlot(input_reg, tmp);
3770a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
37710a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  __ bind(&done);
3772a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3774a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3775e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3776ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  Register input_reg = ToRegister(instr->value());
37770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  __ test(input_reg, Operand(input_reg));
37780a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  Label is_positive;
3779fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  __ j(not_sign, &is_positive, Label::kNear);
3780fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  __ neg(input_reg);  // Sets flags.
37810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  DeoptimizeIf(negative, instr->environment());
37820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  __ bind(&is_positive);
37830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org}
37840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
37850a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
3786e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathAbs(LMathAbs* instr) {
3787a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Class for deferred case.
3788a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3789a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org   public:
3790e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3791a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
3792a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    virtual void Generate() {
3793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3794a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
3795c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    virtual LInstruction* instr() { return instr_; }
3796a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org   private:
3797e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    LMathAbs* instr_;
3798a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
3799a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3800ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  ASSERT(instr->value()->Equals(instr->result()));
3801a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Representation r = instr->hydrogen()->value()->representation();
3802a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3803750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope scope(masm(), SSE2);
3804a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (r.IsDouble()) {
3805a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    XMMRegister  scratch = xmm0;
3806ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    XMMRegister input_reg = ToDoubleRegister(instr->value());
3807fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org    __ xorps(scratch, scratch);
3808a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ subsd(scratch, input_reg);
3809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ pand(input_reg, scratch);
3810594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else if (r.IsSmiOrInteger32()) {
38110a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    EmitIntegerMathAbs(instr);
3812a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {  // Tagged case.
3813a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeferredMathAbsTaggedHeapNumber* deferred =
38147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3815ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    Register input_reg = ToRegister(instr->value());
3816a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Smi check.
38177b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    __ JumpIfNotSmi(input_reg, deferred->entry());
38180a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    EmitIntegerMathAbs(instr);
3819a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ bind(deferred->exit());
3820a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
3821a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3822a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3823a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3824e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathFloor(LMathFloor* instr) {
3825750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope scope(masm(), SSE2);
3826a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  XMMRegister xmm_scratch = xmm0;
3827a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register output_reg = ToRegister(instr->result());
3828ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  XMMRegister input_reg = ToDoubleRegister(instr->value());
3829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
38304acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  if (CpuFeatures::IsSupported(SSE4_1)) {
3831750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    CpuFeatureScope scope(masm(), SSE4_1);
38324acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
38334acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      // Deoptimize on negative zero.
38344acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      Label non_zero;
38354acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ xorps(xmm_scratch, xmm_scratch);  // Zero the register.
38364acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ ucomisd(input_reg, xmm_scratch);
38374acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ j(not_equal, &non_zero, Label::kNear);
38384acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ movmskpd(output_reg, input_reg);
38394acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ test(output_reg, Immediate(1));
38404acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      DeoptimizeIf(not_zero, instr->environment());
38414acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ bind(&non_zero);
38424acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    }
38434acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown);
38444acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    __ cvttsd2si(output_reg, Operand(xmm_scratch));
38454acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    // Overflow is signalled with minint.
38464acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    __ cmp(output_reg, 0x80000000u);
38474acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    DeoptimizeIf(equal, instr->environment());
3848a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
38497a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org    Label negative_sign, done;
3850212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    // Deoptimize on unordered.
38514acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    __ xorps(xmm_scratch, xmm_scratch);  // Zero the register.
38524acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    __ ucomisd(input_reg, xmm_scratch);
3853212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    DeoptimizeIf(parity_even, instr->environment());
3854212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    __ j(below, &negative_sign, Label::kNear);
3855a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
38564acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
38574acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      // Check for negative zero.
38584acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      Label positive_sign;
38594acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ j(above, &positive_sign, Label::kNear);
38604acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ movmskpd(output_reg, input_reg);
38614acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ test(output_reg, Immediate(1));
38624acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      DeoptimizeIf(not_zero, instr->environment());
38634acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ Set(output_reg, Immediate(0));
38644acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ jmp(&done, Label::kNear);
38654acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ bind(&positive_sign);
38664acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    }
3867a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
38684acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    // Use truncating instruction (OK because input is positive).
38694acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    __ cvttsd2si(output_reg, Operand(input_reg));
38704acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    // Overflow is signalled with minint.
38714acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    __ cmp(output_reg, 0x80000000u);
38724acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    DeoptimizeIf(equal, instr->environment());
3873212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    __ jmp(&done, Label::kNear);
3874212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
38757a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org    // Non-zero negative reaches here.
3876212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    __ bind(&negative_sign);
38777a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org    // Truncate, then compare and compensate.
3878212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    __ cvttsd2si(output_reg, Operand(input_reg));
3879212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    __ cvtsi2sd(xmm_scratch, output_reg);
3880212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    __ ucomisd(input_reg, xmm_scratch);
3881212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    __ j(equal, &done, Label::kNear);
3882212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    __ sub(output_reg, Immediate(1));
3883212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    DeoptimizeIf(overflow, instr->environment());
3884212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
38854acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    __ bind(&done);
38864acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
38874acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org}
3888a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3889e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
38904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid LCodeGen::DoMathRound(LMathRound* instr) {
3891750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope scope(masm(), SSE2);
3892a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register output_reg = ToRegister(instr->result());
3893ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  XMMRegister input_reg = ToDoubleRegister(instr->value());
38948432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  XMMRegister xmm_scratch = xmm0;
38954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  XMMRegister input_temp = ToDoubleRegister(instr->temp());
3896a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ExternalReference one_half = ExternalReference::address_of_one_half();
38978432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  ExternalReference minus_one_half =
38988432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      ExternalReference::address_of_minus_one_half();
38998432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
39004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Label done, round_to_zero, below_one_half, do_not_compensate;
3901a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ movdbl(xmm_scratch, Operand::StaticVariable(one_half));
39024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ ucomisd(xmm_scratch, input_reg);
39034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ j(above, &below_one_half);
39044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
39054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x).
39064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ addsd(xmm_scratch, input_reg);
39074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ cvttsd2si(output_reg, Operand(xmm_scratch));
39084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Overflow is signalled with minint.
39094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ cmp(output_reg, 0x80000000u);
39104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ RecordComment("D2I conversion overflow");
39114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  DeoptimizeIf(equal, instr->environment());
39124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ jmp(&done);
3913a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
39144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ bind(&below_one_half);
39154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ movdbl(xmm_scratch, Operand::StaticVariable(minus_one_half));
39164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ ucomisd(xmm_scratch, input_reg);
39174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ j(below_equal, &round_to_zero);
39184a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
39194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then
39204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // compare and compensate.
39214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ movsd(input_temp, input_reg);  // Do not alter input_reg.
39224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ subsd(input_temp, xmm_scratch);
39234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ cvttsd2si(output_reg, Operand(input_temp));
39244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Catch minint due to overflow, and to prevent overflow when compensating.
39254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ cmp(output_reg, 0x80000000u);
39264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ RecordComment("D2I conversion overflow");
39274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  DeoptimizeIf(equal, instr->environment());
39288432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
39294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ cvtsi2sd(xmm_scratch, output_reg);
39304a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ ucomisd(xmm_scratch, input_temp);
39314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ j(equal, &done);
39324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ sub(output_reg, Immediate(1));
39334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // No overflow because we already ruled out minint.
39344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ jmp(&done);
39358432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
39364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ bind(&round_to_zero);
39374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if
39384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // we can ignore the difference between a result of -0 and +0.
39394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
39404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // If the sign is positive, we return +0.
39414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    __ movmskpd(output_reg, input_reg);
39424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    __ test(output_reg, Immediate(1));
39434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    __ RecordComment("Minus zero");
39444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    DeoptimizeIf(not_zero, instr->environment());
3945160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  }
39464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ Set(output_reg, Immediate(0));
39474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ bind(&done);
3948a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3949a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3950a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3951e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3952750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope scope(masm(), SSE2);
3953ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  XMMRegister input_reg = ToDoubleRegister(instr->value());
3954a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3955a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ sqrtsd(input_reg, input_reg);
3956a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3957a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3958a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
395964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3960750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope scope(masm(), SSE2);
39615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  XMMRegister xmm_scratch = xmm0;
3962ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  XMMRegister input_reg = ToDoubleRegister(instr->value());
396364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Register scratch = ToRegister(instr->temp());
39645f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
396564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
396664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Note that according to ECMA-262 15.8.2.13:
396764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Math.pow(-Infinity, 0.5) == Infinity
396864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Math.sqrt(-Infinity) == NaN
396964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Label done, sqrt;
397064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Check base for -Infinity.  According to IEEE-754, single-precision
397164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // -Infinity has the highest 9 bits set and the lowest 23 bits cleared.
397264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ mov(scratch, 0xFF800000);
397364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ movd(xmm_scratch, scratch);
397464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ cvtss2sd(xmm_scratch, xmm_scratch);
397564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ ucomisd(input_reg, xmm_scratch);
397664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Comparing -Infinity with NaN results in "unordered", which sets the
397764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // zero flag as if both were equal.  However, it also sets the carry flag.
397864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ j(not_equal, &sqrt, Label::kNear);
397964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ j(carry, &sqrt, Label::kNear);
398064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // If input is -Infinity, return Infinity.
398164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ xorps(input_reg, input_reg);
398264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ subsd(input_reg, xmm_scratch);
398364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ jmp(&done, Label::kNear);
398464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
398564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Square root.
398664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&sqrt);
3987fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  __ xorps(xmm_scratch, xmm_scratch);
398831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  __ addsd(input_reg, xmm_scratch);  // Convert -0 to +0.
39895f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  __ sqrtsd(input_reg, input_reg);
399064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&done);
39915f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
39925f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
39935f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
39945f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid LCodeGen::DoPower(LPower* instr) {
39955f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  Representation exponent_type = instr->hydrogen()->right()->representation();
399664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Having marked this as a call, we can use any registers.
399764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Just make sure that the input/output registers are the expected ones.
399856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  ASSERT(!instr->right()->IsDoubleRegister() ||
399956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org         ToDoubleRegister(instr->right()).is(xmm1));
400056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  ASSERT(!instr->right()->IsRegister() ||
400156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org         ToRegister(instr->right()).is(eax));
400256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  ASSERT(ToDoubleRegister(instr->left()).is(xmm2));
400364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
400464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
400553ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  if (exponent_type.IsSmi()) {
400653ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org    MathPowStub stub(MathPowStub::TAGGED);
400753ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org    __ CallStub(&stub);
400853ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  } else if (exponent_type.IsTagged()) {
400964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    Label no_deopt;
401064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ JumpIfSmi(eax, &no_deopt);
401164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx);
401264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    DeoptimizeIf(not_equal, instr->environment());
401364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ bind(&no_deopt);
401464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    MathPowStub stub(MathPowStub::TAGGED);
401564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ CallStub(&stub);
40165f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  } else if (exponent_type.IsInteger32()) {
401764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    MathPowStub stub(MathPowStub::INTEGER);
401864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ CallStub(&stub);
40195f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  } else {
402064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    ASSERT(exponent_type.IsDouble());
402164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    MathPowStub stub(MathPowStub::DOUBLE);
402264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ CallStub(&stub);
40235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  }
40245f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
40255f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
40265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4027f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid LCodeGen::DoRandom(LRandom* instr) {
4028bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  class DeferredDoRandom: public LDeferredCode {
4029bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com   public:
4030bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
4031bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        : LDeferredCode(codegen), instr_(instr) { }
4032bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    virtual void Generate() { codegen()->DoDeferredRandom(instr_); }
4033bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    virtual LInstruction* instr() { return instr_; }
4034bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com   private:
4035bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    LRandom* instr_;
4036bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  };
4037bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
40387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
4039bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
4040750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope scope(masm(), SSE2);
4041f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Having marked this instruction as a call we can use any
4042f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // registers.
4043f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
404456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  ASSERT(ToRegister(instr->global_object()).is(eax));
4045bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Assert that the register size is indeed the size of each seed.
4046bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  static const int kSeedSize = sizeof(uint32_t);
4047bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  STATIC_ASSERT(kPointerSize == kSeedSize);
4048f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
404946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  __ mov(eax, FieldOperand(eax, GlobalObject::kNativeContextOffset));
4050bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  static const int kRandomSeedOffset =
4051bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
4052bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ mov(ebx, FieldOperand(eax, kRandomSeedOffset));
405346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // ebx: FixedArray of the native context's random seeds
4054bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
4055bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Load state[0].
4056bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ mov(ecx, FieldOperand(ebx, ByteArray::kHeaderSize));
4057bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // If state[0] == 0, call runtime to initialize seeds.
4058bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ test(ecx, ecx);
4059bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ j(zero, deferred->entry());
4060bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Load state[1].
4061bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ mov(eax, FieldOperand(ebx, ByteArray::kHeaderSize + kSeedSize));
4062bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // ecx: state[0]
4063bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // eax: state[1]
4064bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
4065bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16)
4066bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ movzx_w(edx, ecx);
4067bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ imul(edx, edx, 18273);
4068bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ shr(ecx, 16);
4069bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ add(ecx, edx);
4070bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Save state[0].
4071bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ mov(FieldOperand(ebx, ByteArray::kHeaderSize), ecx);
4072bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
4073bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16)
4074bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ movzx_w(edx, eax);
4075bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ imul(edx, edx, 36969);
4076bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ shr(eax, 16);
4077bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ add(eax, edx);
4078bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Save state[1].
4079bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ mov(FieldOperand(ebx, ByteArray::kHeaderSize + kSeedSize), eax);
4080bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
4081bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF)
4082bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ shl(ecx, 14);
4083bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ and_(eax, Immediate(0x3FFFF));
4084bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ add(eax, ecx);
4085f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
4086bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ bind(deferred->exit());
4087f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Convert 32 random bits in eax to 0.(32 random bits) in a double
4088f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // by computing:
4089f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
4090f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  __ mov(ebx, Immediate(0x49800000));  // 1.0 x 2^20 as single.
4091f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  __ movd(xmm2, ebx);
4092f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  __ movd(xmm1, eax);
4093f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  __ cvtss2sd(xmm2, xmm2);
4094f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  __ xorps(xmm1, xmm2);
4095f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  __ subsd(xmm1, xmm2);
4096f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
4097f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
4098f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
4099bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.comvoid LCodeGen::DoDeferredRandom(LRandom* instr) {
4100bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ PrepareCallCFunction(1, ebx);
4101bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ mov(Operand(esp, 0), eax);
4102bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
4103bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Return value is in eax.
4104bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com}
4105bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
4106bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
4107e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathLog(LMathLog* instr) {
4108750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope scope(masm(), SSE2);
4109ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  ASSERT(instr->value()->Equals(instr->result()));
4110ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  XMMRegister input_reg = ToDoubleRegister(instr->value());
411183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label positive, done, zero;
4112fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  __ xorps(xmm0, xmm0);
411374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ ucomisd(input_reg, xmm0);
411483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ j(above, &positive, Label::kNear);
411583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ j(equal, &zero, Label::kNear);
411684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  ExternalReference nan =
411784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      ExternalReference::address_of_canonical_non_hole_nan();
411874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ movdbl(input_reg, Operand::StaticVariable(nan));
411983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ jmp(&done, Label::kNear);
412074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ bind(&zero);
412174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ push(Immediate(0xFFF00000));
412274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ push(Immediate(0));
412374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ movdbl(input_reg, Operand(esp, 0));
412474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ add(Operand(esp), Immediate(kDoubleSize));
412583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ jmp(&done, Label::kNear);
412674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ bind(&positive);
412774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ fldln2();
412874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ sub(Operand(esp), Immediate(kDoubleSize));
412974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ movdbl(Operand(esp, 0), input_reg);
413074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ fld_d(Operand(esp, 0));
413174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ fyl2x();
413274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ fstp_d(Operand(esp, 0));
413374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ movdbl(input_reg, Operand(esp, 0));
413474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ add(Operand(esp), Immediate(kDoubleSize));
413574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  __ bind(&done);
4136023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org}
4137023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
4138023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
41391f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgvoid LCodeGen::DoMathExp(LMathExp* instr) {
4140750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope scope(masm(), SSE2);
41411f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  XMMRegister input = ToDoubleRegister(instr->value());
41421f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  XMMRegister result = ToDoubleRegister(instr->result());
41431f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  Register temp1 = ToRegister(instr->temp1());
41441f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  Register temp2 = ToRegister(instr->temp2());
41451f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org
41461f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  MathExpGenerator::EmitMathExp(masm(), input, result, xmm0, temp1, temp2);
41471f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org}
41481f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org
41491f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org
4150e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathTan(LMathTan* instr) {
41511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
4152594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Set the context register to a GC-safe fake value. Clobbering it is
4153594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // OK because this instruction is marked as a call.
4154594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  __ Set(esi, Immediate(0));
41551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  TranscendentalCacheStub stub(TranscendentalCache::TAN,
41561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                               TranscendentalCacheStub::UNTAGGED);
41578432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
41581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org}
41591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
41601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
4161e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathCos(LMathCos* instr) {
4162023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
4163594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Set the context register to a GC-safe fake value. Clobbering it is
4164594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // OK because this instruction is marked as a call.
4165594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  __ Set(esi, Immediate(0));
4166023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  TranscendentalCacheStub stub(TranscendentalCache::COS,
4167023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org                               TranscendentalCacheStub::UNTAGGED);
41688432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4169023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org}
4170023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
4171023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
4172e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathSin(LMathSin* instr) {
4173023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
4174594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Set the context register to a GC-safe fake value. Clobbering it is
4175594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // OK because this instruction is marked as a call.
4176594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  __ Set(esi, Immediate(0));
4177023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  TranscendentalCacheStub stub(TranscendentalCache::SIN,
4178023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org                               TranscendentalCacheStub::UNTAGGED);
41798432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
41805f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
41815f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
41825f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4183160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgvoid LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
4184160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
4185160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(ToRegister(instr->function()).is(edi));
4186160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(instr->HasPointerMap());
4187fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org
418832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  Handle<JSFunction> known_function = instr->hydrogen()->known_function();
418932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (known_function.is_null()) {
4190fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    LPointerMap* pointers = instr->pointer_map();
4191fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    RecordPosition(pointers->position());
4192fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    SafepointGenerator generator(
4193fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org        this, pointers, Safepoint::kLazyDeopt);
4194fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    ParameterCount count(instr->arity());
4195fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
4196fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org  } else {
419732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    CallKnownFunction(known_function,
419832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                      instr->hydrogen()->formal_parameter_count(),
4199fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                      instr->arity(),
4200fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                      instr,
4201fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                      CALL_AS_METHOD,
4202fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                      EDI_CONTAINS_TARGET);
4203fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org  }
4204160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org}
4205160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org
4206160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org
4207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallKeyed(LCallKeyed* instr) {
4208496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
4209496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(ToRegister(instr->key()).is(ecx));
4210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
4211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int arity = instr->arity();
421334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Handle<Code> ic =
421434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      isolate()->stub_cache()->ComputeKeyedCallInitialize(arity);
4215ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET, instr);
4216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallNamed(LCallNamed* instr) {
4220496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
4221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
4222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int arity = instr->arity();
422440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
422540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  Handle<Code> ic =
422634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
4227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(ecx, instr->name());
4228ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallCode(ic, mode, instr);
4229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallFunction(LCallFunction* instr) {
4233496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
4234c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  ASSERT(ToRegister(instr->function()).is(edi));
4235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
4236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int arity = instr->arity();
4238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS);
42398432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4240a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4241a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4242a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4243a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallGlobal(LCallGlobal* instr) {
4244496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
4245a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
4246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4247a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int arity = instr->arity();
424840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
424940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  Handle<Code> ic =
425034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
4251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(ecx, instr->name());
4252ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallCode(ic, mode, instr);
4253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4256a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
4257a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
425832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  CallKnownFunction(instr->hydrogen()->target(),
425932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                    instr->hydrogen()->formal_parameter_count(),
4260fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    instr->arity(),
4261fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    instr,
4262fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    CALL_AS_FUNCTION,
4263fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    EDI_UNINITIALIZED);
4264a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4266a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallNew(LCallNew* instr) {
4268496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
4269496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(ToRegister(instr->constructor()).is(edi));
4270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
4271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
42721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // No cell in ebx for construct type feedback in optimized code
42731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<Object> undefined_value(isolate()->factory()->undefined_value());
42741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  __ mov(ebx, Immediate(undefined_value));
4275fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
4276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ Set(eax, Immediate(instr->arity()));
42778432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
42814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid LCodeGen::DoCallNewArray(LCallNewArray* instr) {
42824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
42834a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(ToRegister(instr->constructor()).is(edi));
42844a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ASSERT(ToRegister(instr->result()).is(eax));
42854a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
42864a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ Set(eax, Immediate(instr->arity()));
4287ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  __ mov(ebx, instr->hydrogen()->property_cell());
428857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  ElementsKind kind = instr->hydrogen()->elements_kind();
42891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  AllocationSiteOverrideMode override_mode =
4290bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
42911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          ? DISABLE_ALLOCATION_SITES
42921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          : DONT_OVERRIDE;
42931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ContextCheckMode context_mode = CONTEXT_CHECK_NOT_REQUIRED;
4294d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
4295ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if (instr->arity() == 0) {
42961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    ArrayNoArgumentConstructorStub stub(kind, context_mode, override_mode);
4297ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4298ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  } else if (instr->arity() == 1) {
429941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    Label done;
430041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (IsFastPackedElementsKind(kind)) {
430141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Label packed_case;
430241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      // We might need a change here
430341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      // look at the first argument
430441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      __ mov(ecx, Operand(esp, 0));
430541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      __ test(ecx, ecx);
430641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      __ j(zero, &packed_case);
430741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
430841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      ElementsKind holey_kind = GetHoleyElementsKind(kind);
43091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      ArraySingleArgumentConstructorStub stub(holey_kind, context_mode,
43101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                              override_mode);
431141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
431241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      __ jmp(&done);
431341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      __ bind(&packed_case);
431441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    }
431541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
43161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    ArraySingleArgumentConstructorStub stub(kind, context_mode, override_mode);
4317ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
431841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    __ bind(&done);
4319ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  } else {
43201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode);
4321ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4322ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
43234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
43244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
43254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
4326a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCallRuntime(LCallRuntime* instr) {
4327ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallRuntime(instr->function(), instr->arity(), instr);
4328a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4329a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
43312bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
43322bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  Register result = ToRegister(instr->result());
43332bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  Register base = ToRegister(instr->base_object());
43342bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  __ lea(result, Operand(base, instr->offset()));
43352bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org}
43362bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
43372bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
4338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
4339f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  Representation representation = instr->representation();
4340f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
434153ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  HObjectAccess access = instr->hydrogen()->access();
434253ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  int offset = access.offset();
4343a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4344d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (access.IsExternalMemory()) {
4345d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4346d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    MemOperand operand = instr->object()->IsConstantOperand()
4347d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        ? MemOperand::StaticVariable(
4348d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            ToExternalReference(LConstantOperand::cast(instr->object())))
4349d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        : MemOperand(ToRegister(instr->object()), offset);
4350d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    if (instr->value()->IsConstantOperand()) {
4351d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4352d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      __ mov(operand, Immediate(ToInteger32(operand_value)));
4353d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    } else {
4354d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      Register value = ToRegister(instr->value());
4355d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      __ mov(operand, value);
4356d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    }
4357d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return;
4358d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
4359d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
4360d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Register object = ToRegister(instr->object());
436157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Handle<Map> transition = instr->transition();
436257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
4363f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (FLAG_track_fields && representation.IsSmi()) {
4364f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (instr->value()->IsConstantOperand()) {
4365f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4366a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      if (!IsSmi(operand_value)) {
4367f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org        DeoptimizeIf(no_condition, instr->environment());
4368f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      }
4369f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    }
4370906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
4371906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    if (instr->value()->IsConstantOperand()) {
4372906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4373906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      if (IsInteger32(operand_value)) {
4374906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org        DeoptimizeIf(no_condition, instr->environment());
4375906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      }
4376906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    } else {
4377906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      if (!instr->hydrogen()->value()->type().IsHeapObject()) {
4378906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org        Register value = ToRegister(instr->value());
4379906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org        __ test(value, Immediate(kSmiTagMask));
4380906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org        DeoptimizeIf(zero, instr->environment());
4381906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      }
4382906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    }
438357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  } else if (FLAG_track_double_fields && representation.IsDouble()) {
438457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    ASSERT(transition.is_null());
438553ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org    ASSERT(access.IsInobject());
438657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
438757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    if (CpuFeatures::IsSupported(SSE2)) {
438857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      CpuFeatureScope scope(masm(), SSE2);
438957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      XMMRegister value = ToDoubleRegister(instr->value());
439057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      __ movdbl(FieldOperand(object, offset), value);
439157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    } else {
4392169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      X87Register value = ToX87Register(instr->value());
4393169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      X87Mov(FieldOperand(object, offset), value);
439457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    }
439557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    return;
4396f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
4397f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
4398f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (!transition.is_null()) {
439937141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org    if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
4400f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      __ mov(FieldOperand(object, HeapObject::kMapOffset), transition);
440137141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org    } else {
440256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      Register temp = ToRegister(instr->temp());
440356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      Register temp_map = ToRegister(instr->temp_map());
4404f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      __ mov(temp_map, transition);
440537141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org      __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map);
440637141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org      // Update the write barrier for the map field.
440737141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org      __ RecordWriteField(object,
440837141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org                          HeapObject::kMapOffset,
440937141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org                          temp_map,
441037141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org                          temp,
4411750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                          GetSaveFPRegsMode(),
441237141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org                          OMIT_REMEMBERED_SET,
441337141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org                          OMIT_SMI_CHECK);
441437141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org    }
4415a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4416a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4417a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Do the store.
4418394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  SmiCheck check_needed =
44191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      instr->hydrogen()->value()->IsHeapObject()
44201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
442177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
442277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  Register write_register = object;
442353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  if (!access.IsInobject()) {
442477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    write_register = ToRegister(instr->temp());
4425d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    __ mov(write_register, FieldOperand(object, JSObject::kPropertiesOffset));
442677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  }
442777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
442877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (instr->value()->IsConstantOperand()) {
442977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4430a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (operand_value->IsRegister()) {
443132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      __ mov(FieldOperand(write_register, offset), ToRegister(operand_value));
443277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    } else {
443332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      Handle<Object> handle_value = ToHandle(operand_value);
443457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
443532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      __ mov(FieldOperand(write_register, offset), handle_value);
4436a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
4437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
443877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    __ mov(FieldOperand(write_register, offset), ToRegister(instr->value()));
443977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  }
444077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
444177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (instr->hydrogen()->NeedsWriteBarrier()) {
444277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    Register value = ToRegister(instr->value());
444353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org    Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object;
444477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    // Update the write barrier for the object for in-object properties.
444577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    __ RecordWriteField(write_register,
444677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org                        offset,
444777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org                        value,
444877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org                        temp,
444977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org                        GetSaveFPRegsMode(),
445077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org                        EMIT_REMEMBERED_SET,
445177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org                        check_needed);
4452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4453a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4454a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4455a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4456a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4457496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
4458a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->object()).is(edx));
4459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->value()).is(eax));
4460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(ecx, instr->name());
44621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
44637979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org      ? isolate()->builtins()->StoreIC_Initialize_Strict()
44647979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org      : isolate()->builtins()->StoreIC_Initialize();
4465ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET, instr);
4466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4467a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4468a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4469fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgvoid LCodeGen::ApplyCheckIf(Condition cc, LBoundsCheck* check) {
4470fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (FLAG_debug_code && check->hydrogen()->skip_check()) {
4471fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    Label done;
4472fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    __ j(NegateCondition(cc), &done, Label::kNear);
4473fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    __ int3();
4474fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    __ bind(&done);
4475fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  } else {
4476fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    DeoptimizeIf(cc, check->environment());
4477fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
4478fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org}
4479fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
4480fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
4481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4482fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (instr->hydrogen()->skip_check() && !FLAG_debug_code) return;
44837c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
4484b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  if (instr->index()->IsConstantOperand()) {
4485fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    Immediate immediate =
4486fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        ToImmediate(LConstantOperand::cast(instr->index()),
4487fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                    instr->hydrogen()->length()->representation());
4488fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    __ cmp(ToOperand(instr->length()), immediate);
4489fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    Condition condition =
4490fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        instr->hydrogen()->allow_equality() ? below : below_equal;
4491fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    ApplyCheckIf(condition, instr);
4492b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  } else {
4493b645116853c677aca8a316381b87441ba6004f67danno@chromium.org    __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
4494fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    Condition condition =
4495fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        instr->hydrogen()->allow_equality() ? above : above_equal;
4496fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    ApplyCheckIf(condition, instr);
4497b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  }
4498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4501e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
450283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  ElementsKind elements_kind = instr->elements_kind();
4503eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  LOperand* key = instr->key();
4504eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  if (!key->IsConstantOperand() &&
4505eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org      ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
4506eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org                                  elements_kind)) {
4507eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org    __ SmiUntag(ToRegister(key));
4508304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  }
4509304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  Operand operand(BuildFastArrayOperand(
4510e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      instr->elements(),
4511eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org      key,
4512304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      instr->hydrogen()->key()->representation(),
4513304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      elements_kind,
4514304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      0,
4515304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      instr->additional_index()));
451683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
4517e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
4518e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      CpuFeatureScope scope(masm(), SSE2);
4519e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
4520e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ movss(operand, xmm0);
4521e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    } else {
4522e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ fld(0);
4523e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ fstp_s(operand);
4524e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
452583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
4526e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
4527e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      CpuFeatureScope scope(masm(), SSE2);
4528e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ movdbl(operand, ToDoubleRegister(instr->value()));
4529e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    } else {
4530169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      X87Mov(operand, ToX87Register(instr->value()));
4531e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
45327979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  } else {
45337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org    Register value = ToRegister(instr->value());
45346d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    switch (elements_kind) {
453583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      case EXTERNAL_PIXEL_ELEMENTS:
453683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
453783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      case EXTERNAL_BYTE_ELEMENTS:
453883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        __ mov_b(operand, value);
45397979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org        break;
454083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      case EXTERNAL_SHORT_ELEMENTS:
454183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
454283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        __ mov_w(operand, value);
45437979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org        break;
454483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      case EXTERNAL_INT_ELEMENTS:
454583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      case EXTERNAL_UNSIGNED_INT_ELEMENTS:
454683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        __ mov(operand, value);
45477979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org        break;
454883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      case EXTERNAL_FLOAT_ELEMENTS:
454983e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      case EXTERNAL_DOUBLE_ELEMENTS:
4550830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_SMI_ELEMENTS:
455183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      case FAST_ELEMENTS:
455283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      case FAST_DOUBLE_ELEMENTS:
4553830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_HOLEY_SMI_ELEMENTS:
4554830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_HOLEY_ELEMENTS:
4555830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_HOLEY_DOUBLE_ELEMENTS:
455683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      case DICTIONARY_ELEMENTS:
455783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      case NON_STRICT_ARGUMENTS_ELEMENTS:
45587979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org        UNREACHABLE();
45597979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org        break;
45607979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org    }
45613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
45623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
45633a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
45643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
4565e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4566e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ExternalReference canonical_nan_reference =
4567e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      ExternalReference::address_of_canonical_non_hole_nan();
4568e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Operand double_store_operand = BuildFastArrayOperand(
4569e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      instr->elements(),
4570e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      instr->key(),
4571e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      instr->hydrogen()->key()->representation(),
4572e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      FAST_DOUBLE_ELEMENTS,
4573e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      FixedDoubleArray::kHeaderSize - kHeapObjectTag,
4574e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      instr->additional_index());
4575e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4576e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
4577e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatureScope scope(masm(), SSE2);
4578e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    XMMRegister value = ToDoubleRegister(instr->value());
4579e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4580e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (instr->NeedsCanonicalization()) {
4581e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      Label have_value;
4582e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4583e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ ucomisd(value, value);
4584e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ j(parity_odd, &have_value);  // NaN.
4585e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4586e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ movdbl(value, Operand::StaticVariable(canonical_nan_reference));
4587e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ bind(&have_value);
4588e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
4589e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4590e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ movdbl(double_store_operand, value);
4591e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  } else {
4592e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Can't use SSE2 in the serializer
4593e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (instr->hydrogen()->IsConstantHoleStore()) {
4594e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      // This means we should store the (double) hole. No floating point
4595e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      // registers required.
4596e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      double nan_double = FixedDoubleArray::hole_nan_as_double();
4597e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      uint64_t int_val = BitCast<uint64_t, double>(nan_double);
4598e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      int32_t lower = static_cast<int32_t>(int_val);
4599e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
4600e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4601e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ mov(double_store_operand, Immediate(lower));
4602e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      Operand double_store_operand2 = BuildFastArrayOperand(
4603e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          instr->elements(),
4604e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          instr->key(),
4605e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          instr->hydrogen()->key()->representation(),
4606e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          FAST_DOUBLE_ELEMENTS,
4607e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          FixedDoubleArray::kHeaderSize - kHeapObjectTag + kPointerSize,
4608e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          instr->additional_index());
4609e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ mov(double_store_operand2, Immediate(upper));
4610e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    } else {
4611e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      Label no_special_nan_handling;
4612169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      X87Register value = ToX87Register(instr->value());
4613169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      X87Fxch(value);
4614e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4615e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      if (instr->NeedsCanonicalization()) {
4616e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ fld(0);
4617e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ fld(0);
4618e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ FCmp();
4619e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4620e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ j(parity_odd, &no_special_nan_handling);
4621e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ sub(esp, Immediate(kDoubleSize));
4622e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ fst_d(MemOperand(esp, 0));
4623e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ cmp(MemOperand(esp, sizeof(kHoleNanLower32)),
4624e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org               Immediate(kHoleNanUpper32));
4625e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ add(esp, Immediate(kDoubleSize));
4626e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        Label canonicalize;
4627e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ j(not_equal, &canonicalize);
4628e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ jmp(&no_special_nan_handling);
4629e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ bind(&canonicalize);
4630e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ fstp(0);
4631e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        __ fld_d(Operand::StaticVariable(canonical_nan_reference));
4632e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      }
4633e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4634e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ bind(&no_special_nan_handling);
4635e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ fst_d(double_store_operand);
4636e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
4637e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
4638e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
4639e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
4640e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
4641e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4642e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Register elements = ToRegister(instr->elements());
4643a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
4644a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
46450e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org  Operand operand = BuildFastArrayOperand(
4646e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      instr->elements(),
46470e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org      instr->key(),
4648304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      instr->hydrogen()->key()->representation(),
46490e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org      FAST_ELEMENTS,
46500e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org      FixedArray::kHeaderSize - kHeapObjectTag,
46510e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org      instr->additional_index());
465277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (instr->value()->IsRegister()) {
465377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    __ mov(operand, ToRegister(instr->value()));
465477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  } else {
465577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4656fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    if (IsSmi(operand_value)) {
4657fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      Immediate immediate = ToImmediate(operand_value, Representation::Smi());
4658fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      __ mov(operand, immediate);
465977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    } else {
4660fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      ASSERT(!IsInteger32(operand_value));
466177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      Handle<Object> handle_value = ToHandle(operand_value);
466277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      __ mov(operand, handle_value);
466377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    }
466477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  }
4665a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (instr->hydrogen()->NeedsWriteBarrier()) {
466777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    ASSERT(instr->value()->IsRegister());
466877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    Register value = ToRegister(instr->value());
46690e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org    ASSERT(!instr->key()->IsConstantOperand());
4670394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    SmiCheck check_needed =
46711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        instr->hydrogen()->value()->IsHeapObject()
46721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4673a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Compute address of modified element and store it into key register.
46740e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org    __ lea(key, operand);
4675394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    __ RecordWrite(elements,
4676394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                   key,
4677394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                   value,
4678750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                   GetSaveFPRegsMode(),
4679394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                   EMIT_REMEMBERED_SET,
4680394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                   check_needed);
4681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4683a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4684a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4685e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4686e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // By cases...external, fast-double, fast
4687e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (instr->is_external()) {
4688e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    DoStoreKeyedExternalArray(instr);
4689e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4690e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    DoStoreKeyedFixedDoubleArray(instr);
4691e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  } else {
4692e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    DoStoreKeyedFixedArray(instr);
469328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  }
4694717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org}
4695717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
4696717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
4697a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
4698496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
4699a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->object()).is(edx));
4700a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->key()).is(ecx));
4701a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(ToRegister(instr->value()).is(eax));
4702a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
47031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
47047979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org      ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
47057979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org      : isolate()->builtins()->KeyedStoreIC_Initialize();
4706ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET, instr);
4707a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4708a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
471094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
471194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  Register object = ToRegister(instr->object());
471294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  Register temp = ToRegister(instr->temp());
4713ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  __ TestJSArrayForAllocationMemento(object, temp);
471494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  DeoptimizeIf(equal, instr->environment());
471594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
471694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
471794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
4718394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4719394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Register object_reg = ToRegister(instr->object());
4720394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
4721394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Map> from_map = instr->original_map();
4722394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Map> to_map = instr->transitioned_map();
4723003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  ElementsKind from_kind = instr->from_kind();
4724003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  ElementsKind to_kind = instr->to_kind();
4725394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
4726394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Label not_applicable;
47277028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  bool is_simple_map_transition =
47287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      IsSimpleMapChangeTransition(from_kind, to_kind);
47297028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Label::Distance branch_distance =
47307028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      is_simple_map_transition ? Label::kNear : Label::kFar;
4731394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map);
47327028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  __ j(not_equal, &not_applicable, branch_distance);
47337028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (is_simple_map_transition) {
473494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    Register new_map_reg = ToRegister(instr->new_map_temp());
47357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    Handle<Map> map = instr->hydrogen()->transitioned_map();
47367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    __ mov(FieldOperand(object_reg, HeapObject::kMapOffset),
47377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org           Immediate(map));
4738394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // Write barrier.
473956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT_NE(instr->temp(), NULL);
47407028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    __ RecordWriteForMap(object_reg, to_map, new_map_reg,
474156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org                         ToRegister(instr->temp()),
47427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                         kDontSaveFPRegs);
4743d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  } else {
474494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    PushSafepointRegistersScope scope(this);
474594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    if (!object_reg.is(eax)) {
474694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      __ push(object_reg);
474794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    }
474894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    LoadContextFromDeferred(instr->context());
474994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    if (!object_reg.is(eax)) {
475094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      __ pop(eax);
475194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    }
475294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    __ mov(ebx, to_map);
475394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    TransitionElementsKindStub stub(from_kind, to_kind);
475494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    __ CallStub(&stub);
475594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    RecordSafepointWithRegisters(
475694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4757394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
4758394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&not_applicable);
4759394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
4760394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
4761394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
47620a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgvoid LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
47630a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  class DeferredStringCharCodeAt: public LDeferredCode {
47640a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org   public:
47650a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
47660a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
47670a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); }
4768c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    virtual LInstruction* instr() { return instr_; }
47690a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org   private:
47700a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    LStringCharCodeAt* instr_;
47710a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  };
47720a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
47730a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  DeferredStringCharCodeAt* deferred =
47747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      new(zone()) DeferredStringCharCodeAt(this, instr);
47750a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
47760ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  StringCharLoadGenerator::Generate(masm(),
47770ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                    factory(),
47780ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                    ToRegister(instr->string()),
47790ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                    ToRegister(instr->index()),
47800ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                    ToRegister(instr->result()),
47810ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                    deferred->entry());
47820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  __ bind(deferred->exit());
47830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org}
47840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
47850a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
47860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgvoid LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
47870a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  Register string = ToRegister(instr->string());
47880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  Register result = ToRegister(instr->result());
47890a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
47900a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // TODO(3095996): Get rid of this. For now, we need to make the
47910a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // result register contain a valid pointer because it is already
47920a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // contained in the register pointer map.
47930a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  __ Set(result, Immediate(0));
47940a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
479544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  PushSafepointRegistersScope scope(this);
47960a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  __ push(string);
47970a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // Push the index as a smi. This is safe because of the checks in
47980a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // DoStringCharCodeAt above.
47990a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
48000a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  if (instr->index()->IsConstantOperand()) {
4801fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    Immediate immediate = ToImmediate(LConstantOperand::cast(instr->index()),
4802fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                                      Representation::Smi());
4803fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    __ push(immediate);
48040a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  } else {
48050a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    Register index = ToRegister(instr->index());
48060a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    __ SmiTag(index);
48070a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    __ push(index);
48080a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  }
4809ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2,
4810ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org                          instr, instr->context());
4811c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  __ AssertSmi(eax);
48120a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  __ SmiUntag(eax);
48133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  __ StoreToSafepointRegisterSlot(result, eax);
48140a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org}
48150a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
48160a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
4817b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.orgvoid LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4818b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  class DeferredStringCharFromCode: public LDeferredCode {
4819b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org   public:
4820b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
4821b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
4822b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); }
4823c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    virtual LInstruction* instr() { return instr_; }
4824b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org   private:
4825b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    LStringCharFromCode* instr_;
4826b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  };
4827b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
4828b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  DeferredStringCharFromCode* deferred =
48297028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      new(zone()) DeferredStringCharFromCode(this, instr);
4830b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
4831b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
4832b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  Register char_code = ToRegister(instr->char_code());
4833b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  Register result = ToRegister(instr->result());
4834b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  ASSERT(!char_code.is(result));
4835b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
483659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  __ cmp(char_code, String::kMaxOneByteCharCode);
4837b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  __ j(above, deferred->entry());
4838ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ Set(result, Immediate(factory()->single_character_string_cache()));
4839b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  __ mov(result, FieldOperand(result,
4840b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org                              char_code, times_pointer_size,
4841b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org                              FixedArray::kHeaderSize));
4842ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ cmp(result, factory()->undefined_value());
4843b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  __ j(equal, deferred->entry());
4844b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  __ bind(deferred->exit());
4845b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org}
4846b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
4847b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
4848b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.orgvoid LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
4849b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  Register char_code = ToRegister(instr->char_code());
4850b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  Register result = ToRegister(instr->result());
4851b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
4852b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // TODO(3095996): Get rid of this. For now, we need to make the
4853b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // result register contain a valid pointer because it is already
4854b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // contained in the register pointer map.
4855b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  __ Set(result, Immediate(0));
4856b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
485744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  PushSafepointRegistersScope scope(this);
4858b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  __ SmiTag(char_code);
4859b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  __ push(char_code);
4860ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
4861b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  __ StoreToSafepointRegisterSlot(result, eax);
4862b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org}
4863b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
4864b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
4865160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgvoid LCodeGen::DoStringAdd(LStringAdd* instr) {
486664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  EmitPushTaggedOperand(instr->left());
486764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  EmitPushTaggedOperand(instr->right());
4868ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  StringAddStub stub(instr->hydrogen()->flags());
48698432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4870160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org}
4871160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org
4872160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org
4873a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4874a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (CpuFeatures::IsSupported(SSE2)) {
4875750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    CpuFeatureScope scope(masm(), SSE2);
4876a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    LOperand* input = instr->value();
4877a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ASSERT(input->IsRegister() || input->IsStackSlot());
4878a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    LOperand* output = instr->result();
4879a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ASSERT(output->IsDoubleRegister());
4880a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
4881a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  } else {
4882a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    UNREACHABLE();
4883a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
4884a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4885a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4886a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4887a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
4888a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register input = ToRegister(instr->value());
4889a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  __ SmiTag(input);
4890a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  if (!instr->hydrogen()->value()->HasRange() ||
4891a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      !instr->hydrogen()->value()->range()->IsInSmiRange()) {
4892a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    DeoptimizeIf(overflow, instr->environment());
4893a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
4894a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org}
4895a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
4896a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
489746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4898750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope scope(masm(), SSE2);
489956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* input = instr->value();
490046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  LOperand* output = instr->result();
490156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* temp = instr->temp();
490246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
490346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  __ LoadUint32(ToDoubleRegister(output),
490446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                ToRegister(input),
490546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                ToDoubleRegister(temp));
490646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org}
490746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
490846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
4909a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4910a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class DeferredNumberTagI: public LDeferredCode {
4911a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org   public:
4912a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4913a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
491446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    virtual void Generate() {
491556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      codegen()->DoDeferredNumberTagI(instr_, instr_->value(), SIGNED_INT32);
491646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    }
4917c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    virtual LInstruction* instr() { return instr_; }
4918a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org   private:
4919a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    LNumberTagI* instr_;
4920a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
4921a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
492256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* input = instr->value();
4923a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(input->IsRegister() && input->Equals(instr->result()));
4924a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register reg = ToRegister(input);
4925a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
49267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4927a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ SmiTag(reg);
4928a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ j(overflow, deferred->entry());
4929a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(deferred->exit());
4930a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4931a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4932a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
493346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid LCodeGen::DoNumberTagU(LNumberTagU* instr) {
493446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  class DeferredNumberTagU: public LDeferredCode {
493546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org   public:
493646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
493746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
493846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    virtual void Generate() {
493956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      codegen()->DoDeferredNumberTagI(instr_, instr_->value(), UNSIGNED_INT32);
494046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    }
494146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    virtual LInstruction* instr() { return instr_; }
494246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org   private:
494346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    LNumberTagU* instr_;
494446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  };
494546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
494656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* input = instr->value();
494746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  ASSERT(input->IsRegister() && input->Equals(instr->result()));
494846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Register reg = ToRegister(input);
494946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
495046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
495146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  __ cmp(reg, Immediate(Smi::kMaxValue));
495246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  __ j(above, deferred->entry());
495346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  __ SmiTag(reg);
495446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  __ bind(deferred->exit());
495546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org}
495646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
495746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
495846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
495946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                                    LOperand* value,
496046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                                    IntegerSignedness signedness) {
4961a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Label slow;
496246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Register reg = ToRegister(value);
4963a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register tmp = reg.is(eax) ? ecx : eax;
4964a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4965a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Preserve the value of all registers.
496644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  PushSafepointRegistersScope scope(this);
4967a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
496883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label done;
496946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
497046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (signedness == SIGNED_INT32) {
497146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // There was overflow, so bits 30 and 31 of the original integer
497246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // disagree. Try to allocate a heap number in new space and store
497346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // the value in there. If that fails, call the runtime system.
497446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    __ SmiUntag(reg);
497546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    __ xor_(reg, 0x80000000);
4976a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (CpuFeatures::IsSupported(SSE2)) {
4977750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      CpuFeatureScope feature_scope(masm(), SSE2);
4978a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ cvtsi2sd(xmm0, Operand(reg));
4979a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    } else {
4980a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ push(reg);
4981a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ fild_s(Operand(esp, 0));
4982a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ pop(reg);
4983a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
498446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  } else {
4985a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (CpuFeatures::IsSupported(SSE2)) {
4986750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      CpuFeatureScope feature_scope(masm(), SSE2);
49871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      __ LoadUint32(xmm0, reg,
49881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                    ToDoubleRegister(LNumberTagU::cast(instr)->temp()));
4989a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    } else {
4990068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      // There's no fild variant for unsigned values, so zero-extend to a 64-bit
4991068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      // int manually.
4992068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      __ push(Immediate(0));
4993068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      __ push(reg);
4994068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      __ fild_d(Operand(esp, 0));
4995068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      __ pop(reg);
4996068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      __ pop(reg);
4997a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
499846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
499946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
5000a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (FLAG_inline_new) {
5001a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ AllocateHeapNumber(reg, tmp, no_reg, &slow);
500283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    __ jmp(&done, Label::kNear);
5003a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
5004a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5005a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Slow case: Call the runtime system to do the number allocation.
5006a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&slow);
5007a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5008a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // TODO(3095996): Put a valid pointer value in the stack slot where the result
5009a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // register is stored, as this register is in the pointer map, but contains an
5010a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // integer value.
50113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  __ StoreToSafepointRegisterSlot(reg, Immediate(0));
5012ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // NumberTagI and NumberTagD use the context from the frame, rather than
5013ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // the environment's HContext or HInlinedContext value.
5014ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // They only call Runtime::kAllocateHeapNumber.
5015ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // The corresponding HChange instructions are added in a phase that does
5016ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // not have easy access to the local context.
5017ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
5018ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
5019ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  RecordSafepointWithRegisters(
502027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
5021a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (!reg.is(eax)) __ mov(reg, eax);
5022a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5023a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Done. Put the value in xmm0 into the value of the allocated heap
5024a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // number.
5025a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&done);
5026a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (CpuFeatures::IsSupported(SSE2)) {
5027750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    CpuFeatureScope feature_scope(masm(), SSE2);
5028a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0);
5029a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  } else {
5030a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset));
5031a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
50323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  __ StoreToSafepointRegisterSlot(reg, reg);
5033a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5034a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5035a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5036a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoNumberTagD(LNumberTagD* instr) {
5037a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class DeferredNumberTagD: public LDeferredCode {
5038a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org   public:
5039a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
5040a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
5041a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
5042c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    virtual LInstruction* instr() { return instr_; }
5043a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org   private:
5044a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    LNumberTagD* instr_;
5045a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
5046a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5047a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register reg = ToRegister(instr->result());
5048a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5049169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  bool use_sse2 = CpuFeatures::IsSupported(SSE2);
5050169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (!use_sse2) {
5051169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    // Put the value to the top of stack
5052169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    X87Register src = ToX87Register(instr->value());
5053169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    X87LoadForUsage(src);
5054169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
5055169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
50567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
5057a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (FLAG_inline_new) {
5058068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    Register tmp = ToRegister(instr->temp());
5059a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry());
5060a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
5061a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ jmp(deferred->entry());
5062a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
5063a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(deferred->exit());
5064169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (use_sse2) {
5065750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    CpuFeatureScope scope(masm(), SSE2);
5066a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    XMMRegister input_reg = ToDoubleRegister(instr->value());
5067a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
5068a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  } else {
5069169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset));
5070a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
5071a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5072a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5073a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5074a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
5075a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // TODO(3095996): Get rid of this. For now, we need to make the
5076a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // result register contain a valid pointer because it is already
5077a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // contained in the register pointer map.
5078a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register reg = ToRegister(instr->result());
5079a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ Set(reg, Immediate(0));
5080a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
508144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  PushSafepointRegistersScope scope(this);
5082ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // NumberTagI and NumberTagD use the context from the frame, rather than
5083ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // the environment's HContext or HInlinedContext value.
5084ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // They only call Runtime::kAllocateHeapNumber.
5085ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // The corresponding HChange instructions are added in a phase that does
5086ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // not have easy access to the local context.
5087ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
5088ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
508927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  RecordSafepointWithRegisters(
509027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
50913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  __ StoreToSafepointRegisterSlot(reg, eax);
5092a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5093a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5094a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5095a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoSmiTag(LSmiTag* instr) {
509656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* input = instr->value();
5097a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(input->IsRegister() && input->Equals(instr->result()));
5098a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
5099a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ SmiTag(ToRegister(input));
5100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoSmiUntag(LSmiUntag* instr) {
510456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* input = instr->value();
5105a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register result = ToRegister(input);
5106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(input->IsRegister() && input->Equals(instr->result()));
5107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (instr->needs_check()) {
5108a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ test(result, Immediate(kSmiTagMask));
5109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizeIf(not_zero, instr->environment());
51107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  } else {
5111a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ AssertSmi(result);
5112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
5113a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  __ SmiUntag(result);
5114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5117e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::EmitNumberUntagDNoSSE2(Register input_reg,
5118e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                      Register temp_reg,
5119169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                                      X87Register res_reg,
5120c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org                                      bool can_convert_undefined_to_nan,
5121e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                      bool deoptimize_on_minus_zero,
5122e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                      LEnvironment* env,
5123e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                      NumberUntagDMode mode) {
5124e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Label load_smi, done;
5125e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5126169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  X87PrepareToWrite(res_reg);
5127c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
5128e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Smi check.
5129e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ JumpIfSmi(input_reg, &load_smi, Label::kNear);
5130e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5131e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Heap number map check.
5132e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5133e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org           factory()->heap_number_map());
5134c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    if (!can_convert_undefined_to_nan) {
5135e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      DeoptimizeIf(not_equal, env);
5136e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    } else {
5137c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      Label heap_number, convert;
5138e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ j(equal, &heap_number, Label::kNear);
5139e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5140c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      // Convert undefined (or hole) to NaN.
5141e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ cmp(input_reg, factory()->undefined_value());
5142e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      DeoptimizeIf(not_equal, env);
5143e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5144c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      __ bind(&convert);
5145e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      ExternalReference nan =
5146e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          ExternalReference::address_of_canonical_non_hole_nan();
5147e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ fld_d(Operand::StaticVariable(nan));
5148e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ jmp(&done, Label::kNear);
5149c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
5150e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ bind(&heap_number);
5151e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
5152e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Heap number to x87 conversion.
5153e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
5154e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (deoptimize_on_minus_zero) {
5155e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ fldz();
5156e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ FCmp();
5157e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
5158e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ j(not_zero, &done, Label::kNear);
5159e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5160e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      // Use general purpose registers to check if we have -0.0
5161e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ mov(temp_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset));
5162e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ test(temp_reg, Immediate(HeapNumber::kSignMask));
5163e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ j(zero, &done, Label::kNear);
5164e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5165e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      // Pop FPU stack before deoptimizing.
5166e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ fstp(0);
5167e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      DeoptimizeIf(not_zero, env);
5168e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
5169e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ jmp(&done, Label::kNear);
5170e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  } else {
5171e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
5172e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
5173e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5174e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&load_smi);
5175e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ SmiUntag(input_reg);  // Untag smi before converting to float.
5176e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ push(input_reg);
5177e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ fild_s(Operand(esp, 0));
5178e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ pop(input_reg);
5179e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ SmiTag(input_reg);  // Retag smi.
5180e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&done);
5181169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  X87CommitWrite(res_reg);
5182e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
5183e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5184e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::EmitNumberUntagD(Register input_reg,
5186f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                                Register temp_reg,
5187a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                XMMRegister result_reg,
5188c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org                                bool can_convert_undefined_to_nan,
5189f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                                bool deoptimize_on_minus_zero,
519094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                                LEnvironment* env,
519194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                                NumberUntagDMode mode) {
51926d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Label load_smi, done;
5193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5194c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
519594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    // Smi check.
519694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    __ JumpIfSmi(input_reg, &load_smi, Label::kNear);
5197a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
519894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    // Heap number map check.
519994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
520094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org           factory()->heap_number_map());
5201c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    if (!can_convert_undefined_to_nan) {
520294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      DeoptimizeIf(not_equal, env);
520394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    } else {
5204c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      Label heap_number, convert;
520594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      __ j(equal, &heap_number, Label::kNear);
5206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5207c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      // Convert undefined (and hole) to NaN.
520894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      __ cmp(input_reg, factory()->undefined_value());
520994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      DeoptimizeIf(not_equal, env);
5210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5211c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      __ bind(&convert);
521294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      ExternalReference nan =
521394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org          ExternalReference::address_of_canonical_non_hole_nan();
521494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      __ movdbl(result_reg, Operand::StaticVariable(nan));
521594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      __ jmp(&done, Label::kNear);
5216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
521794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      __ bind(&heap_number);
521894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    }
521994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    // Heap number to XMM conversion.
522094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
522194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    if (deoptimize_on_minus_zero) {
522294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      XMMRegister xmm_scratch = xmm0;
522394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      __ xorps(xmm_scratch, xmm_scratch);
522494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      __ ucomisd(result_reg, xmm_scratch);
522594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      __ j(not_zero, &done, Label::kNear);
522694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      __ movmskpd(temp_reg, result_reg);
522794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      __ test_b(temp_reg, 1);
522894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      DeoptimizeIf(not_zero, env);
522994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    }
523094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    __ jmp(&done, Label::kNear);
523194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  } else {
523294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
5233f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  }
5234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Smi to XMM conversion
5236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&load_smi);
5237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ SmiUntag(input_reg);  // Untag smi before converting to float.
5238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ cvtsi2sd(result_reg, Operand(input_reg));
5239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ SmiTag(input_reg);  // Retag smi.
5240a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&done);
5241a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5242a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5243a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5244a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
524583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label done, heap_number;
524656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register input_reg = ToRegister(instr->value());
5247a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5248a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Heap number map check.
5249a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5250ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org         factory()->heap_number_map());
5251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (instr->truncating()) {
525383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    __ j(equal, &heap_number, Label::kNear);
5254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Check for undefined. Undefined is converted to zero for truncating
5255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // conversions.
5256ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    __ cmp(input_reg, factory()->undefined_value());
5257fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    __ RecordComment("Deferred TaggedToI: cannot truncate");
5258a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizeIf(not_equal, instr->environment());
5259a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ mov(input_reg, 0);
526083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    __ jmp(&done, Label::kNear);
5261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ bind(&heap_number);
5263c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    if (CpuFeatures::IsSupported(SSE3)) {
5264750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      CpuFeatureScope scope(masm(), SSE3);
526583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Label convert;
5266a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Use more powerful conversion when sse3 is available.
5267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Load x87 register with heap number.
5268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
5269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Get exponent alone and check for too-big exponent.
5270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset));
5271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ and_(input_reg, HeapNumber::kExponentMask);
5272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      const uint32_t kTooBigExponent =
5273a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
5274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ cmp(Operand(input_reg), Immediate(kTooBigExponent));
527583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      __ j(less, &convert, Label::kNear);
5276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Pop FPU stack before deoptimizing.
52771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      __ fstp(0);
5278fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      __ RecordComment("Deferred TaggedToI: exponent too big");
5279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      DeoptimizeIf(no_condition, instr->environment());
5280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Reserve space for 64 bit answer.
5282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ bind(&convert);
5283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ sub(Operand(esp), Immediate(kDoubleSize));
5284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Do conversion, which cannot fail because we checked the exponent.
5285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ fisttp_d(Operand(esp, 0));
5286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ mov(input_reg, Operand(esp, 0));  // Low word of answer is the result.
5287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ add(Operand(esp), Immediate(kDoubleSize));
5288e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    } else if (CpuFeatures::IsSupported(SSE2)) {
5289750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      CpuFeatureScope scope(masm(), SSE2);
529056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
5291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
5292a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ cvttsd2si(input_reg, Operand(xmm0));
5293a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ cmp(input_reg, 0x80000000u);
5294a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ j(not_equal, &done);
5295a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Check if the input was 0x8000000 (kMinInt).
5296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // If no, then we got an overflow and we deoptimize.
5297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ExternalReference min_int = ExternalReference::address_of_min_int();
5298a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ movdbl(xmm_temp, Operand::StaticVariable(min_int));
5299a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ ucomisd(xmm_temp, xmm0);
5300a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      DeoptimizeIf(not_equal, instr->environment());
5301a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      DeoptimizeIf(parity_even, instr->environment());  // NaN.
5302e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    } else {
5303e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      UNREACHABLE();
5304a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
5305a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  } else if (CpuFeatures::IsSupported(SSE2)) {
5306750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    CpuFeatureScope scope(masm(), SSE2);
5307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Deoptimize if we don't have a heap number.
5308fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    __ RecordComment("Deferred TaggedToI: not a heap number");
5309a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizeIf(not_equal, instr->environment());
5310a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
531156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
5312a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
5313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ cvttsd2si(input_reg, Operand(xmm0));
5314a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ cvtsi2sd(xmm_temp, Operand(input_reg));
5315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ ucomisd(xmm0, xmm_temp);
5316fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    __ RecordComment("Deferred TaggedToI: lost precision");
5317a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizeIf(not_equal, instr->environment());
5318fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    __ RecordComment("Deferred TaggedToI: NaN");
5319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizeIf(parity_even, instr->environment());  // NaN.
5320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5321a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ test(input_reg, Operand(input_reg));
5322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ j(not_zero, &done);
5323a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ movmskpd(input_reg, xmm0);
5324a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ and_(input_reg, 1);
5325fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      __ RecordComment("Deferred TaggedToI: minus zero");
5326a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      DeoptimizeIf(not_zero, instr->environment());
5327a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
5328a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  } else {
5329a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    UNREACHABLE();
5330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
5331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&done);
5332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5333a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5334a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5335a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoTaggedToI(LTaggedToI* instr) {
5336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  class DeferredTaggedToI: public LDeferredCode {
5337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   public:
5338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
5339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        : LDeferredCode(codegen), instr_(instr) { }
5340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
5341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    virtual LInstruction* instr() { return instr_; }
5342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   private:
5343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    LTaggedToI* instr_;
5344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  };
5345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
534656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* input = instr->value();
5347a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(input->IsRegister());
5348a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register input_reg = ToRegister(input);
5349e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(input_reg.is(ToRegister(instr->result())));
5350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
53517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
5352a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
53537b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  __ JumpIfNotSmi(input_reg, deferred->entry());
5354e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ SmiUntag(input_reg);
5355e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(deferred->exit());
5356e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
5357a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5358a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5359e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoDeferredTaggedToINoSSE2(LTaggedToINoSSE2* instr) {
5360e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Label done, heap_number;
5361e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Register result_reg = ToRegister(instr->result());
5362e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Register input_reg = ToRegister(instr->value());
5363e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5364e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Heap number map check.
5365e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5366e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org         factory()->heap_number_map());
5367b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  if (instr->truncating()) {
5368b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    __ j(equal, &heap_number, Label::kNear);
5369b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    // Check for undefined. Undefined is converted to zero for truncating
5370b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    // conversions.
5371b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    __ cmp(input_reg, factory()->undefined_value());
5372b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    __ RecordComment("Deferred TaggedToI: cannot truncate");
5373b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    DeoptimizeIf(not_equal, instr->environment());
5374b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    __ xor_(result_reg, result_reg);
5375b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    __ jmp(&done, Label::kFar);
5376b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    __ bind(&heap_number);
5377b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  } else {
5378b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    // Deoptimize if we don't have a heap number.
5379b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    DeoptimizeIf(not_equal, instr->environment());
5380b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  }
5381e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5382e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Surprisingly, all of this crazy bit manipulation is considerably
5383e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // faster than using the built-in x86 CPU conversion functions (about 6x).
5384e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Label right_exponent, adjust_bias, zero_result;
5385e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Register scratch = ToRegister(instr->scratch());
5386e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Register scratch2 = ToRegister(instr->scratch2());
5387e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Get exponent word.
5388e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(scratch, FieldOperand(input_reg, HeapNumber::kExponentOffset));
5389e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Get exponent alone in scratch2.
5390e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(scratch2, scratch);
5391e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ and_(scratch2, HeapNumber::kExponentMask);
5392e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ shr(scratch2, HeapNumber::kExponentShift);
5393e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (instr->truncating()) {
5394e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ j(zero, &zero_result);
5395e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  } else {
5396e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ j(not_zero, &adjust_bias);
5397e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ test(scratch, Immediate(HeapNumber::kMantissaMask));
5398e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    DeoptimizeIf(not_zero, instr->environment());
5399e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ cmp(FieldOperand(input_reg, HeapNumber::kMantissaOffset), Immediate(0));
5400e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    DeoptimizeIf(not_equal, instr->environment());
5401e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ bind(&adjust_bias);
5402e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
5403e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ sub(scratch2, Immediate(HeapNumber::kExponentBias));
5404e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!instr->truncating()) {
5405e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    DeoptimizeIf(negative, instr->environment());
5406e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  } else {
5407e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ j(negative, &zero_result);
5408e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
5409e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5410e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Get the second half of the double. For some exponents we don't
5411e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // actually need this because the bits get shifted out again, but
5412e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // it's probably slower to test than just to do it.
5413e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Register scratch3 = ToRegister(instr->scratch3());
5414e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(scratch3, FieldOperand(input_reg, HeapNumber::kMantissaOffset));
5415e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ xor_(result_reg, result_reg);
5416e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5417e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const uint32_t non_int32_exponent = 31;
5418e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ cmp(scratch2, Immediate(non_int32_exponent));
5419e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // If we have a match of the int32 exponent then skip some logic.
5420e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ j(equal, &right_exponent, Label::kNear);
5421e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // If the number doesn't find in an int32, deopt.
5422e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  DeoptimizeIf(greater, instr->environment());
5423e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5424e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Exponent word in scratch, exponent in scratch2.  We know that 0 <= exponent
5425e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // < 31.
5426e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(result_reg, Immediate(31));
5427e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ sub(result_reg, scratch2);
5428e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5429e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&right_exponent);
5430e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5431e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Save off exponent for negative check later.
5432e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(scratch2, scratch);
5433e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5434e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Here result_reg is the shift, scratch is the exponent word.
5435e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Get the top bits of the mantissa.
5436e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ and_(scratch, HeapNumber::kMantissaMask);
5437e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Put back the implicit 1.
5438e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ or_(scratch, 1 << HeapNumber::kExponentShift);
5439e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Shift up the mantissa bits to take up the space the exponent used to
5440e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // take. We have kExponentShift + 1 significant bits int he low end of the
5441e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // word.  Shift them to the top bits.
5442e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 1;
5443e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ shl(scratch, shift_distance);
5444e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!instr->truncating()) {
5445e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // If not truncating, a non-zero value in the bottom 22 bits means a
5446e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // non-integral value --> trigger a deopt.
5447e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ test(scratch3, Immediate((1 << (32 - shift_distance)) - 1));
5448e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    DeoptimizeIf(not_equal, instr->environment());
5449e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
5450e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Shift down 22 bits to get the most significant 10 bits or the low
5451e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // mantissa word.
5452e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ shr(scratch3, 32 - shift_distance);
5453e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ or_(scratch3, scratch);
5454e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!instr->truncating()) {
5455e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // If truncating, a non-zero value in the bits that will be shifted away
5456e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // when adjusting the exponent means rounding --> deopt.
5457e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ mov(scratch, 0x1);
5458e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    ASSERT(result_reg.is(ecx));
5459e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ shl_cl(scratch);
5460e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ dec(scratch);
5461e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ test(scratch3, scratch);
5462e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    DeoptimizeIf(not_equal, instr->environment());
5463e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
5464e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Move down according to the exponent.
5465e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(result_reg.is(ecx));
5466e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ shr_cl(scratch3);
5467e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Now the unsigned 32-bit answer is in scratch3.  We need to move it to
5468e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // result_reg and we may need to fix the sign.
5469e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Label negative_result;
5470e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ xor_(result_reg, result_reg);
5471e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ cmp(scratch2, result_reg);
5472e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ j(less, &negative_result, Label::kNear);
5473e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ cmp(scratch3, result_reg);
5474e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(result_reg, scratch3);
5475e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // If the result is > MAX_INT, result doesn't fit in signed 32-bit --> deopt.
5476e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  DeoptimizeIf(less, instr->environment());
5477e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ jmp(&done, Label::kNear);
5478e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&zero_result);
5479e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ xor_(result_reg, result_reg);
5480e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ jmp(&done, Label::kNear);
5481e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&negative_result);
5482e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ sub(result_reg, scratch3);
5483e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!instr->truncating()) {
5484e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // -0.0 triggers a deopt.
5485e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    DeoptimizeIf(zero, instr->environment());
5486e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
5487e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // If the negative subtraction overflows into a positive number, there was an
5488e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // overflow --> deopt.
5489e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  DeoptimizeIf(positive, instr->environment());
5490e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&done);
5491e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
5492e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5493e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5494e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoTaggedToINoSSE2(LTaggedToINoSSE2* instr) {
5495e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  class DeferredTaggedToINoSSE2: public LDeferredCode {
5496e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org   public:
5497e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    DeferredTaggedToINoSSE2(LCodeGen* codegen, LTaggedToINoSSE2* instr)
5498e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
5499e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    virtual void Generate() { codegen()->DoDeferredTaggedToINoSSE2(instr_); }
5500e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    virtual LInstruction* instr() { return instr_; }
5501e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org   private:
5502e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    LTaggedToINoSSE2* instr_;
5503e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  };
5504e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5505e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  LOperand* input = instr->value();
5506e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(input->IsRegister());
5507e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Register input_reg = ToRegister(input);
5508e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(input_reg.is(ToRegister(instr->result())));
5509e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5510e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  DeferredTaggedToINoSSE2* deferred =
5511e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      new(zone()) DeferredTaggedToINoSSE2(this, instr);
5512e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5513e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Smi check.
5514e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ JumpIfNotSmi(input_reg, deferred->entry());
5515e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ SmiUntag(input_reg);  // Untag smi.
5516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(deferred->exit());
5517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
552156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* input = instr->value();
5522a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(input->IsRegister());
552356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* temp = instr->temp();
5524f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  ASSERT(temp == NULL || temp->IsRegister());
5525a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LOperand* result = instr->result();
5526a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(result->IsDoubleRegister());
5527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5528e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Register input_reg = ToRegister(input);
5529e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool deoptimize_on_minus_zero =
5530e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      instr->hydrogen()->deoptimize_on_minus_zero();
5531e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Register temp_reg = deoptimize_on_minus_zero ? ToRegister(temp) : no_reg;
5532e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5533e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  HValue* value = instr->hydrogen()->value();
5534c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  NumberUntagDMode mode = value->representation().IsSmi()
5535c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org      ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED;
553694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
5537e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (CpuFeatures::IsSupported(SSE2)) {
5538e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CpuFeatureScope scope(masm(), SSE2);
5539e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    XMMRegister result_reg = ToDoubleRegister(result);
5540a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    EmitNumberUntagD(input_reg,
5541a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                     temp_reg,
5542a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                     result_reg,
5543c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org                     instr->hydrogen()->can_convert_undefined_to_nan(),
5544a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                     deoptimize_on_minus_zero,
554594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                     instr->environment(),
554694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                     mode);
5547a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  } else {
5548e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    EmitNumberUntagDNoSSE2(input_reg,
5549e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                           temp_reg,
5550169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                           ToX87Register(instr->result()),
5551c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org                           instr->hydrogen()->can_convert_undefined_to_nan(),
5552e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                           deoptimize_on_minus_zero,
5553e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                           instr->environment(),
5554e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                           mode);
5555a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
5556a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5557a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5558a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5559a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoDoubleToI(LDoubleToI* instr) {
556056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* input = instr->value();
5561a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(input->IsDoubleRegister());
5562a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LOperand* result = instr->result();
5563a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(result->IsRegister());
5564750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope scope(masm(), SSE2);
5565a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  XMMRegister input_reg = ToDoubleRegister(input);
5567a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register result_reg = ToRegister(result);
5568a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5569169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  __ cvttsd2si(result_reg, Operand(input_reg));
5570169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
5571a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (instr->truncating()) {
5572a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Performs a truncating conversion of a floating point number as used by
5573a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // the JS bitwise operations.
5574169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    Label fast_case_succeeded;
5575a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ cmp(result_reg, 0x80000000u);
5576169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ j(not_equal, &fast_case_succeeded);
5577169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ sub(esp, Immediate(kDoubleSize));
5578169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ movdbl(MemOperand(esp, 0), input_reg);
5579169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    DoubleToIStub stub(esp, result_reg, 0, true);
5580169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
5581169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ add(esp, Immediate(kDoubleSize));
5582169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    __ bind(&fast_case_succeeded);
5583a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
558483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Label done;
5585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ cvtsi2sd(xmm0, Operand(result_reg));
5586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ ucomisd(xmm0, input_reg);
5587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizeIf(not_equal, instr->environment());
5588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizeIf(parity_even, instr->environment());  // NaN.
5589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5590a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // The integer converted back is equal to the original. We
5591a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // only have to test if we got -0 as an input.
5592a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ test(result_reg, Operand(result_reg));
559383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      __ j(not_zero, &done, Label::kNear);
5594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ movmskpd(result_reg, input_reg);
5595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Bit 0 contains the sign of the double in input_reg.
5596a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // If input was positive, we are ok and return 0, otherwise
5597a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // deoptimize.
5598a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      __ and_(result_reg, 1);
5599a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      DeoptimizeIf(not_zero, instr->environment());
5600a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
5601a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ bind(&done);
5602a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
5603a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5604a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5605a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5606a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5607a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  LOperand* input = instr->value();
5608a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(input->IsDoubleRegister());
5609a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  LOperand* result = instr->result();
5610a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(result->IsRegister());
5611a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  CpuFeatureScope scope(masm(), SSE2);
5612a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5613a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  XMMRegister input_reg = ToDoubleRegister(input);
5614a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register result_reg = ToRegister(result);
5615a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5616a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Label done;
5617a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  __ cvttsd2si(result_reg, Operand(input_reg));
5618a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  __ cvtsi2sd(xmm0, Operand(result_reg));
5619a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  __ ucomisd(xmm0, input_reg);
5620a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  DeoptimizeIf(not_equal, instr->environment());
5621a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  DeoptimizeIf(parity_even, instr->environment());  // NaN.
5622a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5623a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5624a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // The integer converted back is equal to the original. We
5625a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // only have to test if we got -0 as an input.
5626a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ test(result_reg, Operand(result_reg));
5627a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ j(not_zero, &done, Label::kNear);
5628a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ movmskpd(result_reg, input_reg);
5629a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // Bit 0 contains the sign of the double in input_reg.
5630a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // If input was positive, we are ok and return 0, otherwise
5631a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // deoptimize.
5632a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ and_(result_reg, 1);
5633a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    DeoptimizeIf(not_zero, instr->environment());
5634a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ bind(&done);
5635a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
5636a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  __ SmiTag(result_reg);
5637a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  DeoptimizeIf(overflow, instr->environment());
5638a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org}
5639a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5640a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5641a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCheckSmi(LCheckSmi* instr) {
564256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* input = instr->value();
56434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  __ test(ToOperand(input), Immediate(kSmiTagMask));
5644badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  DeoptimizeIf(not_zero, instr->environment());
5645badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org}
5646badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
5647badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
5648badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
56491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!instr->hydrogen()->value()->IsHeapObject()) {
56501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    LOperand* input = instr->value();
56511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ test(ToOperand(input), Immediate(kSmiTagMask));
56521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    DeoptimizeIf(zero, instr->environment());
56531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
5654a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5655a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5656a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5657a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
565856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register input = ToRegister(instr->value());
565956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register temp = ToRegister(instr->temp());
5660a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
5662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
566383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (instr->hydrogen()->is_interval_check()) {
566483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    InstanceType first;
566583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    InstanceType last;
566683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    instr->hydrogen()->GetCheckInterval(&first, &last);
566783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
56680a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
56690a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org            static_cast<int8_t>(first));
567083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
567183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // If there is only one type in the interval check for equality.
567283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (first == last) {
567383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      DeoptimizeIf(not_equal, instr->environment());
567483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else {
567583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      DeoptimizeIf(below, instr->environment());
567683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      // Omit check for the last type.
567783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      if (last != LAST_TYPE) {
567883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
567983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                static_cast<int8_t>(last));
568083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        DeoptimizeIf(above, instr->environment());
568183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      }
568283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
568383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
568483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    uint8_t mask;
568583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    uint8_t tag;
568683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
568783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
568883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (IsPowerOf2(mask)) {
568983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      ASSERT(tag == 0 || IsPowerOf2(tag));
569083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      __ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), mask);
569183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      DeoptimizeIf(tag == 0 ? not_zero : zero, instr->environment());
569283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else {
569383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
569483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      __ and_(temp, mask);
569556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org      __ cmp(temp, tag);
569683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      DeoptimizeIf(not_equal, instr->environment());
5697a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
5698a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
5699a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5700a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5701a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5702a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoCheckFunction(LCheckFunction* instr) {
5703c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<JSFunction> target = instr->hydrogen()->target();
5704003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  if (instr->hydrogen()->target_in_new_space()) {
5705c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register reg = ToRegister(instr->value());
570641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    Handle<Cell> cell = isolate()->factory()->NewCell(target);
570741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    __ cmp(reg, Operand::ForCell(cell));
5708c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
5709c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Operand operand = ToOperand(instr->value());
571064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ cmp(operand, target);
5711c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
5712a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DeoptimizeIf(not_equal, instr->environment());
5713a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5714a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5715a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5716594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5717594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  {
5718594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    PushSafepointRegistersScope scope(this);
5719594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ push(object);
5720594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ xor_(esi, esi);
5721594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ CallRuntimeSaveDoubles(Runtime::kMigrateInstance);
5722594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    RecordSafepointWithRegisters(
5723594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
5724594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
5725594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ test(eax, Immediate(kSmiTagMask));
5726594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
5727594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  DeoptimizeIf(zero, instr->environment());
5728f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
5729f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
5730f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
57311456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5732594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  class DeferredCheckMaps: public LDeferredCode {
5733594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org   public:
5734594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
5735594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        : LDeferredCode(codegen), instr_(instr), object_(object) {
5736594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      SetExit(check_maps());
5737594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
5738594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    virtual void Generate() {
5739594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      codegen()->DoDeferredInstanceMigration(instr_, object_);
5740594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
5741594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Label* check_maps() { return &check_maps_; }
5742594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    virtual LInstruction* instr() { return instr_; }
5743594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org   private:
5744594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    LCheckMaps* instr_;
5745594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Label check_maps_;
5746594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Register object_;
5747594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  };
5748594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
5749c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (instr->hydrogen()->CanOmitMapChecks()) return;
5750594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
575156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* input = instr->value();
5752a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(input->IsRegister());
5753a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Register reg = ToRegister(input);
57541456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
5755abafe3dbcc62abc040625a8356be42bbd0cf7608danno@chromium.org  SmallMapList* map_set = instr->hydrogen()->map_set();
5756594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
5757594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  DeferredCheckMaps* deferred = NULL;
5758594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (instr->hydrogen()->has_migration_target()) {
5759594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
5760594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ bind(deferred->check_maps());
5761594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
5762594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
5763594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Label success;
57641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  for (int i = 0; i < map_set->length() - 1; i++) {
57651456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    Handle<Map> map = map_set->at(i);
5766a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ CompareMap(reg, map, &success);
57671456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    __ j(equal, &success);
57681456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  }
5769594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
57701456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  Handle<Map> map = map_set->last();
5771594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  __ CompareMap(reg, map, &success);
5772594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (instr->hydrogen()->has_migration_target()) {
5773594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ j(not_equal, deferred->entry());
5774594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else {
5775594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    DeoptimizeIf(not_equal, instr->environment());
5776594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
5777594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
57781456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  __ bind(&success);
5779a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5780a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5782c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5783750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope scope(masm(), SSE2);
5784c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
5785c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  Register result_reg = ToRegister(instr->result());
5786c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ ClampDoubleToUint8(value_reg, xmm0, result_reg);
5787c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org}
5788c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
5789c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
5790c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5791c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  ASSERT(instr->unclamped()->Equals(instr->result()));
5792c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  Register value_reg = ToRegister(instr->result());
5793c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ ClampUint8(value_reg);
5794c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org}
5795c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
5796c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
5797c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5798750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope scope(masm(), SSE2);
5799a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
5800c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  ASSERT(instr->unclamped()->Equals(instr->result()));
5801c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  Register input_reg = ToRegister(instr->unclamped());
5802c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  Label is_smi, done, heap_number;
5803c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
5804c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ JumpIfSmi(input_reg, &is_smi);
5805c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
5806c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Check for heap number
5807c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5808c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org         factory()->heap_number_map());
5809c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ j(equal, &heap_number, Label::kNear);
5810c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
5811c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Check for undefined. Undefined is converted to zero for clamping
5812c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // conversions.
5813c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ cmp(input_reg, factory()->undefined_value());
5814c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  DeoptimizeIf(not_equal, instr->environment());
5815c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ mov(input_reg, 0);
5816c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ jmp(&done, Label::kNear);
5817c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
5818c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Heap number
5819c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ bind(&heap_number);
5820c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
5821c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ ClampDoubleToUint8(xmm0, xmm1, input_reg);
5822c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ jmp(&done, Label::kNear);
5823c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
5824c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // smi
5825c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ bind(&is_smi);
5826c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ SmiUntag(input_reg);
5827c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ ClampUint8(input_reg);
5828e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&done);
5829e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
5830e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5831e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5832e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoClampTToUint8NoSSE2(LClampTToUint8NoSSE2* instr) {
5833e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Register input_reg = ToRegister(instr->unclamped());
5834e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Register result_reg = ToRegister(instr->result());
5835e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Register scratch = ToRegister(instr->scratch());
5836e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Register scratch2 = ToRegister(instr->scratch2());
5837e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Register scratch3 = ToRegister(instr->scratch3());
5838e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Label is_smi, done, heap_number, valid_exponent,
5839e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      largest_value, zero_result, maybe_nan_or_infinity;
5840c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
5841e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ JumpIfSmi(input_reg, &is_smi);
5842e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5843e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Check for heap number
5844e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5845e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org         factory()->heap_number_map());
5846e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ j(equal, &heap_number, Label::kFar);
5847e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5848e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Check for undefined. Undefined is converted to zero for clamping
5849e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // conversions.
5850e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ cmp(input_reg, factory()->undefined_value());
5851e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  DeoptimizeIf(not_equal, instr->environment());
5852e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ jmp(&zero_result);
5853e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5854e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Heap number
5855e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&heap_number);
5856e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5857e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Surprisingly, all of the hand-crafted bit-manipulations below are much
5858e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // faster than the x86 FPU built-in instruction, especially since "banker's
5859e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // rounding" would be additionally very expensive
5860e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5861e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Get exponent word.
5862e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(scratch, FieldOperand(input_reg, HeapNumber::kExponentOffset));
5863e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(scratch3, FieldOperand(input_reg, HeapNumber::kMantissaOffset));
5864e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5865e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Test for negative values --> clamp to zero
5866e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ test(scratch, scratch);
5867e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ j(negative, &zero_result);
5868e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5869e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Get exponent alone in scratch2.
5870e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(scratch2, scratch);
5871e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ and_(scratch2, HeapNumber::kExponentMask);
5872e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ shr(scratch2, HeapNumber::kExponentShift);
5873e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ j(zero, &zero_result);
5874e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ sub(scratch2, Immediate(HeapNumber::kExponentBias - 1));
5875e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ j(negative, &zero_result);
5876e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5877e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const uint32_t non_int8_exponent = 7;
5878e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ cmp(scratch2, Immediate(non_int8_exponent + 1));
5879e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // If the exponent is too big, check for special values.
5880e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ j(greater, &maybe_nan_or_infinity, Label::kNear);
5881e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5882e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&valid_exponent);
5883e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Exponent word in scratch, exponent in scratch2. We know that 0 <= exponent
5884e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // < 7. The shift bias is the number of bits to shift the mantissa such that
5885e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // with an exponent of 7 such the that top-most one is in bit 30, allowing
5886e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // detection the rounding overflow of a 255.5 to 256 (bit 31 goes from 0 to
5887e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // 1).
5888e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  int shift_bias = (30 - HeapNumber::kExponentShift) - 7 - 1;
5889e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ lea(result_reg, MemOperand(scratch2, shift_bias));
5890e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Here result_reg (ecx) is the shift, scratch is the exponent word.  Get the
5891e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // top bits of the mantissa.
5892e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ and_(scratch, HeapNumber::kMantissaMask);
5893e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Put back the implicit 1 of the mantissa
5894e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ or_(scratch, 1 << HeapNumber::kExponentShift);
5895e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Shift up to round
5896e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ shl_cl(scratch);
5897e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Use "banker's rounding" to spec: If fractional part of number is 0.5, then
5898e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // use the bit in the "ones" place and add it to the "halves" place, which has
5899e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // the effect of rounding to even.
5900e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(scratch2, scratch);
5901e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const uint32_t one_half_bit_shift = 30 - sizeof(uint8_t) * 8;
5902e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  const uint32_t one_bit_shift = one_half_bit_shift + 1;
5903e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ and_(scratch2, Immediate((1 << one_bit_shift) - 1));
5904e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ cmp(scratch2, Immediate(1 << one_half_bit_shift));
5905e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Label no_round;
5906e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ j(less, &no_round);
5907e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Label round_up;
5908e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(scratch2, Immediate(1 << one_half_bit_shift));
5909e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ j(greater, &round_up);
5910e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ test(scratch3, scratch3);
5911e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ j(not_zero, &round_up);
5912e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(scratch2, scratch);
5913e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ and_(scratch2, Immediate(1 << one_bit_shift));
5914e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ shr(scratch2, 1);
5915e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&round_up);
5916e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ add(scratch, scratch2);
5917e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ j(overflow, &largest_value);
5918e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&no_round);
5919e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ shr(scratch, 23);
5920e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(result_reg, scratch);
5921e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ jmp(&done, Label::kNear);
5922e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5923e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&maybe_nan_or_infinity);
5924e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Check for NaN/Infinity, all other values map to 255
5925e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ cmp(scratch2, Immediate(HeapNumber::kInfinityOrNanExponent + 1));
5926e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ j(not_equal, &largest_value, Label::kNear);
5927e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5928e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Check for NaN, which differs from Infinity in that at least one mantissa
5929e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // bit is set.
5930e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ and_(scratch, HeapNumber::kMantissaMask);
5931e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ or_(scratch, FieldOperand(input_reg, HeapNumber::kMantissaOffset));
5932e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ j(not_zero, &zero_result);  // M!=0 --> NaN
5933e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Infinity -> Fall through to map to 255.
5934e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5935e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&largest_value);
5936e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(result_reg, Immediate(255));
5937e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ jmp(&done, Label::kNear);
5938e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5939e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&zero_result);
5940e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ xor_(result_reg, result_reg);
5941e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ jmp(&done);
5942e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5943e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // smi
5944e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&is_smi);
5945e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!input_reg.is(result_reg)) {
5946e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ mov(result_reg, input_reg);
5947e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
5948e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ SmiUntag(result_reg);
5949e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ ClampUint8(result_reg);
5950c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ bind(&done);
5951c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org}
5952c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
5953c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
595494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::DoAllocate(LAllocate* instr) {
595594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  class DeferredAllocate: public LDeferredCode {
595694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org   public:
595794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
595894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
595994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    virtual void Generate() { codegen()->DoDeferredAllocate(instr_); }
596094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    virtual LInstruction* instr() { return instr_; }
596194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org   private:
596294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    LAllocate* instr_;
596394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  };
596494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
596594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  DeferredAllocate* deferred =
596694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      new(zone()) DeferredAllocate(this, instr);
596794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
596894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  Register result = ToRegister(instr->result());
596994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  Register temp = ToRegister(instr->temp());
597094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
597171fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  // Allocate memory for the object.
597271fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  AllocationFlags flags = TAG_OBJECT;
597371fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  if (instr->hydrogen()->MustAllocateDoubleAligned()) {
597471fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org    flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT);
597571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  }
5976d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5977d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5978d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5979e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE);
5980d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5981d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5982c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE);
5983e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
5984c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
598571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  if (instr->size()->IsConstantOperand()) {
598671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org    int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
59872bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    __ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
598894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  } else {
598971fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org    Register size = ToRegister(instr->size());
5990f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    __ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
599194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  }
599294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
599394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  __ bind(deferred->exit());
5994c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
5995c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (instr->hydrogen()->MustPrefillWithFiller()) {
5996c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    if (instr->size()->IsConstantOperand()) {
5997c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5998c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      __ mov(temp, (size / kPointerSize) - 1);
5999c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    } else {
6000c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      temp = ToRegister(instr->size());
6001c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      __ shr(temp, kPointerSizeLog2);
6002c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      __ dec(temp);
6003c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    }
6004c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    Label loop;
6005c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    __ bind(&loop);
6006c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    __ mov(FieldOperand(result, temp, times_pointer_size, 0),
6007c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org        isolate()->factory()->one_pointer_filler_map());
6008c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    __ dec(temp);
6009c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    __ j(not_zero, &loop);
6010c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  }
601194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
601294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
601394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
601494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LCodeGen::DoDeferredAllocate(LAllocate* instr) {
601594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  Register result = ToRegister(instr->result());
601694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
601794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  // TODO(3095996): Get rid of this. For now, we need to make the
601894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  // result register contain a valid pointer because it is already
601994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  // contained in the register pointer map.
6020f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  __ mov(result, Immediate(Smi::FromInt(0)));
6021f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
6022f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  PushSafepointRegistersScope scope(this);
6023f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (instr->size()->IsRegister()) {
6024f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    Register size = ToRegister(instr->size());
6025f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    ASSERT(!size.is(result));
6026f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    __ SmiTag(ToRegister(instr->size()));
6027f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    __ push(size);
6028f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  } else {
6029f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
6030f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    __ push(Immediate(Smi::FromInt(size)));
603194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  }
6032f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
6033d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
6034d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
6035d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
6036e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CallRuntimeFromDeferred(
6037e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        Runtime::kAllocateInOldPointerSpace, 1, instr, instr->context());
6038d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
6039d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
6040c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    CallRuntimeFromDeferred(
6041c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org        Runtime::kAllocateInOldDataSpace, 1, instr, instr->context());
6042e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  } else {
6043e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CallRuntimeFromDeferred(
6044e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        Runtime::kAllocateInNewSpace, 1, instr, instr->context());
6045e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
6046967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  __ StoreToSafepointRegisterSlot(result, eax);
6047967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org}
6048967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
6049967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
6050ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid LCodeGen::DoToFastProperties(LToFastProperties* instr) {
605156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  ASSERT(ToRegister(instr->value()).is(eax));
6052ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ push(eax);
6053ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallRuntime(Runtime::kToFastProperties, 1, instr);
6054ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
6055ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
6056ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
6057a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
6058ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
605983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label materialized;
6060a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Registers will be used as follows:
6061a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // ecx = literals array.
6062a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // ebx = regexp literal.
6063a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // eax = regexp literal clone.
6064ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // esi = context.
60659c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org  int literal_offset =
60669c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org      FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
60679c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org  __ LoadHeapObject(ecx, instr->hydrogen()->literals());
6068a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(ebx, FieldOperand(ecx, literal_offset));
6069ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  __ cmp(ebx, factory()->undefined_value());
607083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ j(not_equal, &materialized, Label::kNear);
6071a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6072a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Create regexp literal using runtime function
6073a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Result will be in eax.
6074a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ push(ecx);
6075a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
6076a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ push(Immediate(instr->hydrogen()->pattern()));
6077a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ push(Immediate(instr->hydrogen()->flags()));
6078ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
6079a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ mov(ebx, eax);
6080a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6081a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&materialized);
6082a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
6083a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Label allocated, runtime_allocate;
60842bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  __ Allocate(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT);
6085a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ jmp(&allocated);
6086a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6087a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&runtime_allocate);
6088a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ push(ebx);
6089a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ push(Immediate(Smi::FromInt(size)));
6090ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
6091a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ pop(ebx);
6092a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6093a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  __ bind(&allocated);
6094a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Copy the content into the newly allocated memory.
6095a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // (Unroll copy loop once for better throughput).
6096a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) {
6097a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ mov(edx, FieldOperand(ebx, i));
6098a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ mov(ecx, FieldOperand(ebx, i + kPointerSize));
6099a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ mov(FieldOperand(eax, i), edx);
6100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ mov(FieldOperand(eax, i + kPointerSize), ecx);
6101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
6102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if ((size % (2 * kPointerSize)) != 0) {
6103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ mov(edx, FieldOperand(ebx, size - kPointerSize));
6104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ mov(FieldOperand(eax, size - kPointerSize), edx);
6105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
6106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
6110ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  ASSERT(ToRegister(instr->context()).is(esi));
6111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Use the fast case closure allocation code that allocates in new
6112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // space for nested functions that don't need literals cloning.
611383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  bool pretenure = instr->hydrogen()->pretenure();
611432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (!pretenure && instr->hydrogen()->has_no_literals()) {
611532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    FastNewClosureStub stub(instr->hydrogen()->language_mode(),
611632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                            instr->hydrogen()->is_generator());
611732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ push(Immediate(instr->hydrogen()->shared_info()));
61188432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
6119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
6120be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    __ push(esi);
612132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ push(Immediate(instr->hydrogen()->shared_info()));
612232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ push(Immediate(pretenure ? factory()->true_value()
612332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                                : factory()->false_value()));
6124ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    CallRuntime(Runtime::kNewClosure, 3, instr);
6125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
6126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoTypeof(LTypeof* instr) {
613056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  LOperand* input = instr->value();
613164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  EmitPushTaggedOperand(input);
6132ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CallRuntime(Runtime::kTypeof, 1, instr);
6133a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6134a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
613756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register input = ToRegister(instr->value());
6138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6139394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Condition final_branch_condition =
61401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitTypeofIs(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
61411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          input, instr->type_literal());
6142394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (final_branch_condition != no_condition) {
61431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    EmitBranch(instr, final_branch_condition);
6144394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
6145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6146a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6147a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6148a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgCondition LCodeGen::EmitTypeofIs(Label* true_label,
6149a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                 Label* false_label,
6150a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                 Register input,
6151a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                 Handle<String> type_name) {
6152a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Condition final_branch_condition = no_condition;
61534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (type_name->Equals(heap()->number_string())) {
61548f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    __ JumpIfSmi(input, true_label);
6155a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ cmp(FieldOperand(input, HeapObject::kMapOffset),
6156ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org           factory()->heap_number_map());
6157a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    final_branch_condition = equal;
6158a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
61594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } else if (type_name->Equals(heap()->string_string())) {
61608f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    __ JumpIfSmi(input, false_label);
61618f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input);
61628f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    __ j(above_equal, false_label);
6163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ test_b(FieldOperand(input, Map::kBitFieldOffset),
6164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org              1 << Map::kIsUndetectable);
61658f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    final_branch_condition = zero;
6166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6167f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  } else if (type_name->Equals(heap()->symbol_string())) {
6168f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    __ JumpIfSmi(input, false_label);
6169f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    __ CmpObjectType(input, SYMBOL_TYPE, input);
6170f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    final_branch_condition = equal;
6171f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
61724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } else if (type_name->Equals(heap()->boolean_string())) {
6173ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    __ cmp(input, factory()->true_value());
6174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ j(equal, true_label);
6175ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    __ cmp(input, factory()->false_value());
6176a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    final_branch_condition = equal;
6177a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
61784a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) {
61794acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    __ cmp(input, factory()->null_value());
61804acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    final_branch_condition = equal;
61814acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
61824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } else if (type_name->Equals(heap()->undefined_string())) {
6183ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    __ cmp(input, factory()->undefined_value());
6184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ j(equal, true_label);
61858f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    __ JumpIfSmi(input, false_label);
6186a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Check for undetectable objects => true.
6187a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ mov(input, FieldOperand(input, HeapObject::kMapOffset));
6188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ test_b(FieldOperand(input, Map::kBitFieldOffset),
6189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org              1 << Map::kIsUndetectable);
6190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    final_branch_condition = not_zero;
6191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
61924a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } else if (type_name->Equals(heap()->function_string())) {
6193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
61948f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    __ JumpIfSmi(input, false_label);
6195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ CmpObjectType(input, JS_FUNCTION_TYPE, input);
6196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ j(equal, true_label);
6197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE);
6198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    final_branch_condition = equal;
6199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
62004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } else if (type_name->Equals(heap()->object_string())) {
62018f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    __ JumpIfSmi(input, false_label);
62024acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    if (!FLAG_harmony_typeof) {
62034acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ cmp(input, factory()->null_value());
62044acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      __ j(equal, true_label);
62054acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    }
6206f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input);
62078f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    __ j(below, false_label);
6208d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org    __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
6209d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org    __ j(above, false_label);
6210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Check for undetectable objects => false.
6211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ test_b(FieldOperand(input, Map::kBitFieldOffset),
6212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org              1 << Map::kIsUndetectable);
62138f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    final_branch_condition = zero;
6214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
6216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    __ jmp(false_label);
6217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
6218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return final_branch_condition;
6219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6220a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6222d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.comvoid LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
622356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  Register temp = ToRegister(instr->temp());
6224d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
6225d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  EmitIsConstructCall(temp);
62261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, equal);
6227d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com}
6228d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
6229d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
6230d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.comvoid LCodeGen::EmitIsConstructCall(Register temp) {
6231d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  // Get the frame pointer for the calling frame.
6232d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  __ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
6233d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
6234d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  // Skip the arguments adaptor frame if it exists.
623583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Label check_frame_marker;
6236d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  __ cmp(Operand(temp, StandardFrameConstants::kContextOffset),
6237d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com         Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
623883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  __ j(not_equal, &check_frame_marker, Label::kNear);
6239d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  __ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset));
6240d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
6241d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  // Check the marker in the calling frame.
6242d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  __ bind(&check_frame_marker);
6243d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  __ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset),
6244d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com         Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
6245d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com}
6246d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
6247d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
624827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgvoid LCodeGen::EnsureSpaceForLazyDeopt() {
6249a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (!info()->IsStub()) {
6250a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // Ensure that we have enough space after the previous lazy-bailout
6251a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // instruction for patching the code here.
6252a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    int current_pc = masm()->pc_offset();
6253a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    int patch_size = Deoptimizer::patch_size();
6254a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (current_pc < last_lazy_deopt_pc_ + patch_size) {
6255a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc;
6256a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      __ Nop(padding_size);
6257a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
625827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  }
62591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  last_lazy_deopt_pc_ = masm()->pc_offset();
626027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org}
626127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
626227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
6263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoLazyBailout(LLazyBailout* instr) {
626427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  EnsureSpaceForLazyDeopt();
626527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  ASSERT(instr->HasEnvironment());
626627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  LEnvironment* env = instr->environment();
626727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
626827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
6269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoDeoptimize(LDeoptimize* instr) {
6273c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  Deoptimizer::BailoutType type = instr->hydrogen()->type();
6274c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
6275c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // needed return address), even though the implementation of LAZY and EAGER is
6276c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // now identical. When LAZY is eventually completely folded into EAGER, remove
6277c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // the special case below.
6278c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (info()->IsStub() && type == Deoptimizer::EAGER) {
6279c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    type = Deoptimizer::LAZY;
6280c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  }
6281594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
6282c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  DeoptimizeIf(no_condition, instr->environment(), type);
6283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
628646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgvoid LCodeGen::DoDummyUse(LDummyUse* instr) {
628746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  // Nothing to see here, move on!
628846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org}
628946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
629046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
629104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgvoid LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
629227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  PushSafepointRegistersScope scope(this);
629327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
629427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  __ CallRuntimeSaveDoubles(Runtime::kStackGuard);
629527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  RecordSafepointWithLazyDeopt(
629627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
629727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  ASSERT(instr->HasEnvironment());
629827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  LEnvironment* env = instr->environment();
629927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
630004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org}
630104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
630204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
6303a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoStackCheck(LStackCheck* instr) {
630404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  class DeferredStackCheck: public LDeferredCode {
630504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org   public:
630604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
630704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
630804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
6309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    virtual LInstruction* instr() { return instr_; }
631004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org   private:
631104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    LStackCheck* instr_;
631204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  };
6313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
631427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  ASSERT(instr->HasEnvironment());
631527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  LEnvironment* env = instr->environment();
631627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  // There is no LLazyBailout instruction for stack-checks. We have to
631727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  // prepare for lazy deoptimization explicitly here.
631804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  if (instr->hydrogen()->is_function_entry()) {
631904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    // Perform stack overflow check.
632004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    Label done;
632104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    ExternalReference stack_limit =
632204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org        ExternalReference::address_of_stack_limit(isolate());
632304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    __ cmp(esp, Operand::StaticVariable(stack_limit));
632404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    __ j(above_equal, &done, Label::kNear);
632504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
6326ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    ASSERT(instr->context()->IsRegister());
6327ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    ASSERT(ToRegister(instr->context()).is(esi));
632804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    StackCheckStub stub;
63298432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
633027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    EnsureSpaceForLazyDeopt();
633104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    __ bind(&done);
633227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
633327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
633404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  } else {
633504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    ASSERT(instr->hydrogen()->is_backwards_branch());
633604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    // Perform stack overflow check if this goto needs it before jumping.
633704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    DeferredStackCheck* deferred_stack_check =
63387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        new(zone()) DeferredStackCheck(this, instr);
633904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    ExternalReference stack_limit =
634004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org        ExternalReference::address_of_stack_limit(isolate());
634104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    __ cmp(esp, Operand::StaticVariable(stack_limit));
634204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    __ j(below, deferred_stack_check->entry());
634327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    EnsureSpaceForLazyDeopt();
634404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    __ bind(instr->done_label());
634504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    deferred_stack_check->SetExit(instr->done_label());
634627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
634727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    // Don't record a deoptimization index for the safepoint here.
634827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    // This will be done explicitly when emitting call and the safepoint in
634927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    // the deferred code.
635004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  }
6351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6352a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6354a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid LCodeGen::DoOsrEntry(LOsrEntry* instr) {
6355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // This is a pseudo-instruction that ensures that the environment here is
6356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // properly registered for deoptimization and records the assembler's PC
6357a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // offset.
6358a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  LEnvironment* environment = instr->environment();
6359a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6360a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // If the environment were already registered, we would have no way of
6361a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // backpatching it with the spill slot operands.
6362a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(!environment->HasBeenRegistered());
636327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
63641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
63651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Normally we record the first unknown OSR value as the entrypoint to the OSR
63661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // code, but if there were none, record the entrypoint here.
63671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (osr_pc_offset_ == -1) osr_pc_offset_ = masm()->pc_offset();
6368a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6370a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6371be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
6372be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ cmp(eax, isolate()->factory()->undefined_value());
6373be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  DeoptimizeIf(equal, instr->environment());
6374be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6375be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ cmp(eax, isolate()->factory()->null_value());
6376be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  DeoptimizeIf(equal, instr->environment());
6377be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6378be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ test(eax, Immediate(kSmiTagMask));
6379be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  DeoptimizeIf(zero, instr->environment());
6380be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6381be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
6382be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ CmpObjectType(eax, LAST_JS_PROXY_TYPE, ecx);
6383be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  DeoptimizeIf(below_equal, instr->environment());
6384be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6385be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Label use_cache, call_runtime;
6386be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ CheckEnumCache(&call_runtime);
6387be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6388be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));
6389be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ jmp(&use_cache, Label::kNear);
6390be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6391be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // Get the set of properties to enumerate.
6392be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ bind(&call_runtime);
6393be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ push(eax);
6394be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
6395be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6396be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
6397be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org         isolate()->factory()->meta_map());
6398be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  DeoptimizeIf(not_equal, instr->environment());
6399be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ bind(&use_cache);
6400be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org}
6401be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6402be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6403be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
6404be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Register map = ToRegister(instr->map());
6405be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Register result = ToRegister(instr->result());
6406355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  Label load_cache, done;
6407355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  __ EnumLength(result, map);
6408355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  __ cmp(result, Immediate(Smi::FromInt(0)));
6409355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  __ j(not_equal, &load_cache);
6410355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  __ mov(result, isolate()->factory()->empty_fixed_array());
6411355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  __ jmp(&done);
6412355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
6413355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  __ bind(&load_cache);
6414be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ LoadInstanceDescriptors(map, result);
6415be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ mov(result,
6416304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org         FieldOperand(result, DescriptorArray::kEnumCacheOffset));
6417be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ mov(result,
6418be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org         FieldOperand(result, FixedArray::SizeFor(instr->idx())));
6419355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  __ bind(&done);
6420be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ test(result, result);
6421be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  DeoptimizeIf(equal, instr->environment());
6422be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org}
6423be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6424be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6425be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
6426be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Register object = ToRegister(instr->value());
6427be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ cmp(ToRegister(instr->map()),
6428be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org         FieldOperand(object, HeapObject::kMapOffset));
6429be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  DeoptimizeIf(not_equal, instr->environment());
6430be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org}
6431be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6432be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6433be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
6434be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Register object = ToRegister(instr->object());
6435be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Register index = ToRegister(instr->index());
6436be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6437be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Label out_of_object, done;
6438be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ cmp(index, Immediate(0));
6439be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ j(less, &out_of_object);
6440be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ mov(object, FieldOperand(object,
6441be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                              index,
6442be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                              times_half_pointer_size,
6443be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                              JSObject::kHeaderSize));
6444be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ jmp(&done, Label::kNear);
6445be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6446be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ bind(&out_of_object);
6447be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ mov(object, FieldOperand(object, JSObject::kPropertiesOffset));
6448be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ neg(index);
6449be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // Index is now equal to out of object property index plus 1.
6450be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ mov(object, FieldOperand(object,
6451be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                              index,
6452be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                              times_half_pointer_size,
6453be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                              FixedArray::kHeaderSize - kPointerSize));
6454be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  __ bind(&done);
6455be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org}
6456be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6457be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6458a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#undef __
6459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} }  // namespace v8::internal
6461c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
6462c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#endif  // V8_TARGET_ARCH_IA32
6463