1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved.
2c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// Redistribution and use in source and binary forms, with or without
3c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// modification, are permitted provided that the following conditions are
4c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// met:
5c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org//
6c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org//     * Redistributions of source code must retain the above copyright
7c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org//       notice, this list of conditions and the following disclaimer.
8c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org//     * Redistributions in binary form must reproduce the above
9c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org//       copyright notice, this list of conditions and the following
10c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org//       disclaimer in the documentation and/or other materials provided
11c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org//       with the distribution.
12c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org//     * Neither the name of Google Inc. nor the names of its
13c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org//       contributors may be used to endorse or promote products derived
14c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org//       from this software without specific prior written permission.
15c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org//
16c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
28c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#include "v8.h"
29c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
30c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#include "mips/lithium-codegen-mips.h"
31c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#include "mips/lithium-gap-resolver-mips.h"
32c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#include "code-stubs.h"
33c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#include "stub-cache.h"
34c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
35c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgnamespace v8 {
36c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgnamespace internal {
37c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
38c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
39c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgclass SafepointGenerator : public CallWrapper {
40c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org public:
41c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  SafepointGenerator(LCodeGen* codegen,
42c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                     LPointerMap* pointers,
430ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                     Safepoint::DeoptMode mode)
44c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      : codegen_(codegen),
45c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        pointers_(pointers),
460ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry        deopt_mode_(mode) { }
47c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  virtual ~SafepointGenerator() { }
48c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
490ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  virtual void BeforeCall(int call_size) const { }
50c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
51c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  virtual void AfterCall() const {
520ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    codegen_->RecordSafepoint(pointers_, deopt_mode_);
53c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
54c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
55c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org private:
56c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LCodeGen* codegen_;
57c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LPointerMap* pointers_;
580ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  Safepoint::DeoptMode deopt_mode_;
59c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org};
60c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
61c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
62c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#define __ masm()->
63c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
64c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool LCodeGen::GenerateCode() {
651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  LPhase phase("Z_Code generation", chunk());
66c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(is_unused());
67c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  status_ = GENERATING;
68c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
69c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Open a frame scope to indicate that there is a frame on the stack.  The
70c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // NONE indicates that the scope shouldn't actually generate code to set up
71c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // the frame (that is done in GeneratePrologue).
72c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  FrameScope frame_scope(masm_, StackFrame::NONE);
73c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
74c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return GeneratePrologue() &&
75c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      GenerateBody() &&
76c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      GenerateDeferredCode() &&
7759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      GenerateDeoptJumpTable() &&
78c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      GenerateSafepointTable();
79c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
80c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
81c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
82c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::FinishCode(Handle<Code> code) {
83c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(is_done());
84c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  code->set_stack_slots(GetStackSlotCount());
85c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
866ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  if (FLAG_weak_embedded_maps_in_optimized_code) {
876ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org    RegisterDependentCodeForEmbeddedMaps(code);
886ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  }
89c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  PopulateDeoptimizationData(code);
901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  info()->CommitDependencies(code);
91c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
92c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
93c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
94594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LChunkBuilder::Abort(BailoutReason reason) {
9546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  info()->set_bailout_reason(reason);
96c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  status_ = ABORTED;
97c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
98c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
99c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
100c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::Comment(const char* format, ...) {
101c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (!FLAG_code_comments) return;
102c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  char buffer[4 * KB];
103c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  StringBuilder builder(buffer, ARRAY_SIZE(buffer));
104c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  va_list arguments;
105c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  va_start(arguments, format);
106c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  builder.AddFormattedList(format, arguments);
107c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  va_end(arguments);
108c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
109c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Copy the string before recording it in the assembler to avoid
110c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // issues when the stack allocated buffer goes out of scope.
111c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  size_t length = builder.position();
112c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Vector<char> copy = Vector<char>::New(length + 1);
113e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  OS::MemCopy(copy.start(), builder.Finalize(), copy.length());
114c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  masm()->RecordComment(copy.start());
115c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
116c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
117c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
118c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool LCodeGen::GeneratePrologue() {
119c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(is_generating());
120c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
12159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (info()->IsOptimizing()) {
12259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    ProfileEntryHookStub::MaybeCallEntryHook(masm_);
123129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
124c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#ifdef DEBUG
12559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    if (strlen(FLAG_stop_at) > 0 &&
12659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
12759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      __ stop("stop_at");
12859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    }
129c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#endif
130c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
13159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // a1: Callee's JS function.
13259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // cp: Callee's context.
13359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // fp: Caller's frame pointer.
13459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // lr: Caller's pc.
13559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
13659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // Strict mode functions and builtins need to replace the receiver
13759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // with undefined when called as functions (without an explicit
13859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // receiver object). r5 is zero for method calls and non-zero for
13959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // function calls.
14059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    if (!info_->is_classic_mode() || info_->is_native()) {
14159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      Label ok;
14259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      __ Branch(&ok, eq, t1, Operand(zero_reg));
14359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
14459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      int receiver_offset = scope()->num_parameters() * kPointerSize;
14559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
14659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      __ sw(a2, MemOperand(sp, receiver_offset));
14759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      __ bind(&ok);
14859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    }
149c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
150c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
15183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  info()->set_prologue_offset(masm_->pc_offset());
15259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (NeedsEagerFrame()) {
1537c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    if (info()->IsStub()) {
1547c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ Push(ra, fp, cp);
1557c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ Push(Smi::FromInt(StackFrame::STUB));
1567c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      // Adjust FP to point to saved FP.
1577c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ Addu(fp, sp, Operand(2 * kPointerSize));
1587c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    } else {
1597c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      // The following three instructions must remain together and unmodified
1607c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      // for code aging to work properly.
1617c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ Push(ra, fp, cp, a1);
162ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      // Add unused nop to ensure prologue sequence is identical for
1637c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      // full-codegen and lithium-codegen.
164ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      __ nop(Assembler::CODE_AGE_SEQUENCE_NOP);
1657c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      // Adj. FP to point to saved FP.
1667c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ Addu(fp, sp, Operand(2 * kPointerSize));
1677c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    }
16859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    frame_is_built_ = true;
1694e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    info_->AddNoFrameRange(0, masm_->pc_offset());
17059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
171c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
172c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Reserve space for the stack slots needed by the code.
173c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int slots = GetStackSlotCount();
174c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (slots > 0) {
175c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (FLAG_debug_code) {
1767c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ Subu(sp,  sp, Operand(slots * kPointerSize));
1777c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ push(a0);
1787c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ push(a1);
1797c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ Addu(a0, sp, Operand(slots *  kPointerSize));
1807c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ li(a1, Operand(kSlotsZapValue));
181c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Label loop;
182c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ bind(&loop);
1837c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ Subu(a0, a0, Operand(kPointerSize));
1847c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ sw(a1, MemOperand(a0, 2 * kPointerSize));
1857c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ Branch(&loop, ne, a0, Operand(sp));
1867c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ pop(a1);
1877c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ pop(a0);
188c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
189c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ Subu(sp, sp, Operand(slots * kPointerSize));
190c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
191c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
192c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
193e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (info()->saves_caller_doubles()) {
1947c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    Comment(";;; Save clobbered callee double registers");
1957c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    int count = 0;
1967c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    BitVector* doubles = chunk()->allocated_double_registers();
1977c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    BitVector::Iterator save_iterator(doubles);
1987c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    while (!save_iterator.Done()) {
1997c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ sdc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
2007c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org              MemOperand(sp, count * kDoubleSize));
2017c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      save_iterator.Advance();
2027c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      count++;
2037c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    }
2047c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  }
2057c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
206c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Possibly allocate a local context.
20759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
208c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (heap_slots > 0) {
209c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Comment(";;; Allocate local context");
210c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Argument to NewContext is the function, which is in a1.
211c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ push(a1);
212c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (heap_slots <= FastNewContextStub::kMaximumSlots) {
213c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      FastNewContextStub stub(heap_slots);
214c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ CallStub(&stub);
215c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
216c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ CallRuntime(Runtime::kNewFunctionContext, 1);
217c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
2180ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    RecordSafepoint(Safepoint::kNoLazyDeopt);
219c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Context is returned in both v0 and cp.  It replaces the context
220c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // passed to us.  It's saved in the stack and kept live in cp.
221c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
222c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Copy any necessary parameters into the context.
223c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    int num_parameters = scope()->num_parameters();
224c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    for (int i = 0; i < num_parameters; i++) {
225c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Variable* var = scope()->parameter(i);
226c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      if (var->IsContextSlot()) {
227c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        int parameter_offset = StandardFrameConstants::kCallerSPOffset +
228c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            (num_parameters - 1 - i) * kPointerSize;
229c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Load parameter from stack.
230c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ lw(a0, MemOperand(fp, parameter_offset));
231c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Store it in the context.
232c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        MemOperand target = ContextOperand(cp, var->index());
233c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ sw(a0, target);
234c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Update the write barrier. This clobbers a3 and a0.
235c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ RecordWriteContextSlot(
236c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org            cp, target.offset(), a0, a3, GetRAState(), kSaveFPRegs);
237c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      }
238c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
239c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Comment(";;; End allocate local context");
240c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
241c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
242c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Trace the call.
24359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (FLAG_trace && info()->IsOptimizing()) {
244c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ CallRuntime(Runtime::kTraceEnter, 0);
245c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
246c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return !is_aborted();
247c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
248c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
249c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
250c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool LCodeGen::GenerateBody() {
251c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(is_generating());
252c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool emit_instructions = true;
253c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (current_instruction_ = 0;
254c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org       !is_aborted() && current_instruction_ < instructions_->length();
255c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org       current_instruction_++) {
256c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LInstruction* instr = instructions_->at(current_instruction_);
25732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
25832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    // Don't emit code for basic blocks with a replacement.
259c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (instr->IsLabel()) {
26032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      emit_instructions = !LLabel::cast(instr)->HasReplacement();
261c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
26232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    if (!emit_instructions) continue;
263c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
26432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    if (FLAG_code_comments && instr->HasInterestingComment(this)) {
26532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      Comment(";;; <@%d,#%d> %s",
26632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              current_instruction_,
26732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              instr->hydrogen_value()->id(),
26832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              instr->Mnemonic());
269c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
27032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
271594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    RecordAndUpdatePosition(instr->position());
272594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
27332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    instr->CompileToNative(this);
274c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
2751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EnsureSpaceForLazyDeopt();
2766fe0fda6a144bf4a3991162c622e8745376b755aulan@chromium.org  last_lazy_deopt_pc_ = masm()->pc_offset();
277c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return !is_aborted();
278c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
279c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
280c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
281c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool LCodeGen::GenerateDeferredCode() {
282c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(is_generating());
283c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (deferred_.length() > 0) {
284c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
285c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      LDeferredCode* code = deferred_[i];
286594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
287594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      int pos = instructions_->at(code->instruction_index())->position();
288594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      RecordAndUpdatePosition(pos);
289594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
29032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      Comment(";;; <@%d,#%d> "
29132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              "-------------------- Deferred %s --------------------",
29232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              code->instruction_index(),
29332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              code->instr()->hydrogen_value()->id(),
29432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org              code->instr()->Mnemonic());
295c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ bind(code->entry());
29659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      if (NeedsDeferredFrame()) {
29732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org        Comment(";;; Build frame");
29859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        ASSERT(!frame_is_built_);
29959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        ASSERT(info()->IsStub());
30059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        frame_is_built_ = true;
30159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        __ MultiPush(cp.bit() | fp.bit() | ra.bit());
30259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        __ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
30359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        __ push(scratch0());
30459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        __ Addu(fp, sp, Operand(2 * kPointerSize));
30532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org        Comment(";;; Deferred code");
30659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      }
307c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      code->Generate();
30859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      if (NeedsDeferredFrame()) {
30932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org        Comment(";;; Destroy frame");
31059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        ASSERT(frame_is_built_);
31159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        __ pop(at);
31259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        __ MultiPop(cp.bit() | fp.bit() | ra.bit());
31359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        frame_is_built_ = false;
31459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      }
315c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ jmp(code->exit());
316c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
317c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
318c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Deferred code is the last part of the instruction sequence. Mark
319c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // the generated code as done unless we bailed out.
320c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (!is_aborted()) status_ = DONE;
321c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return !is_aborted();
322c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
323c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
324c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
325c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool LCodeGen::GenerateDeoptJumpTable() {
32659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // Check that the jump table is accessible from everywhere in the function
32759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // code, i.e. that offsets to the table can be encoded in the 16bit signed
32859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // immediate of a branch instruction.
32959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // To simplify we consider the code size from the first instruction to the
33059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // end of the jump table.
33159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (!is_int16((masm()->pc_offset() / Assembler::kInstrSize) +
33259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      deopt_jump_table_.length() * 12)) {
333594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Abort(kGeneratedCodeIsTooLarge);
33459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
33559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
33632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (deopt_jump_table_.length() > 0) {
33732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    Comment(";;; -------------------- Jump table --------------------");
33832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  }
33959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
34059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  Label table_start;
34159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  __ bind(&table_start);
342169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Label needs_frame;
34359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  for (int i = 0; i < deopt_jump_table_.length(); i++) {
34459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    __ bind(&deopt_jump_table_[i].label);
34559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    Address entry = deopt_jump_table_[i].address;
3460410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com    Deoptimizer::BailoutType type = deopt_jump_table_[i].bailout_type;
347876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type);
348068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    if (id == Deoptimizer::kNotDeoptimizationEntry) {
349068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      Comment(";;; jump table entry %d.", i);
350068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    } else {
351068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id);
352068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    }
35359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    __ li(t9, Operand(ExternalReference::ForDeoptEntry(entry)));
35459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    if (deopt_jump_table_[i].needs_frame) {
355169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      if (needs_frame.is_bound()) {
356169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ Branch(&needs_frame);
35759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      } else {
358169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ bind(&needs_frame);
359169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ MultiPush(cp.bit() | fp.bit() | ra.bit());
360169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // This variant of deopt can only be used with stubs. Since we don't
361169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // have a function pointer to install in the stack frame that we're
362169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        // building, install a special marker there instead.
363169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        ASSERT(info()->IsStub());
364169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
365169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ push(scratch0());
366169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        __ Addu(fp, sp, Operand(2 * kPointerSize));
36759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        __ Call(t9);
36859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      }
369169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    } else {
370169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      __ Call(t9);
37159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    }
37259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
37359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  __ RecordComment("]");
37459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
37559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // The deoptimization jump table is the last part of the instruction
37659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // sequence. Mark the generated code as done unless we bailed out.
37759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (!is_aborted()) status_ = DONE;
37859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  return !is_aborted();
379c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
380c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
381c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
382c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool LCodeGen::GenerateSafepointTable() {
383c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(is_done());
384c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  safepoints_.Emit(masm(), GetStackSlotCount());
385c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return !is_aborted();
386c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
387c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
388c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
389c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgRegister LCodeGen::ToRegister(int index) const {
390c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return Register::FromAllocationIndex(index);
391c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
392c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
393c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
394c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgDoubleRegister LCodeGen::ToDoubleRegister(int index) const {
395c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return DoubleRegister::FromAllocationIndex(index);
396c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
397c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
398c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
399c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgRegister LCodeGen::ToRegister(LOperand* op) const {
400c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(op->IsRegister());
401c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return ToRegister(op->index());
402c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
403c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
404c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
405c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgRegister LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) {
406c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (op->IsRegister()) {
407c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    return ToRegister(op->index());
408c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (op->IsConstantOperand()) {
40964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    LConstantOperand* const_op = LConstantOperand::cast(op);
41028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    HConstant* constant = chunk_->LookupConstant(const_op);
41128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    Handle<Object> literal = constant->handle();
41264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    Representation r = chunk_->LookupLiteralRepresentation(const_op);
41364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    if (r.IsInteger32()) {
41464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      ASSERT(literal->IsNumber());
41564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      __ li(scratch, Operand(static_cast<int32_t>(literal->Number())));
41609b3454f8cdcc19655f7e1d6362f8f0216941235palfia@homejinni.com    } else if (r.IsSmi()) {
41709b3454f8cdcc19655f7e1d6362f8f0216941235palfia@homejinni.com      ASSERT(constant->HasSmiValue());
41809b3454f8cdcc19655f7e1d6362f8f0216941235palfia@homejinni.com      __ li(scratch, Operand(Smi::FromInt(constant->Integer32Value())));
41964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    } else if (r.IsDouble()) {
420594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Abort(kEmitLoadRegisterUnsupportedDoubleImmediate);
42164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    } else {
42264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      ASSERT(r.IsTagged());
423fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      __ LoadObject(scratch, literal);
42464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    }
425c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    return scratch;
426c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (op->IsStackSlot() || op->IsArgument()) {
427c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ lw(scratch, ToMemOperand(op));
428c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    return scratch;
429c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
430c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  UNREACHABLE();
431c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return scratch;
432c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
433c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
434c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
435c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgDoubleRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
436c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(op->IsDoubleRegister());
437c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return ToDoubleRegister(op->index());
438c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
439c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
440c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
441c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgDoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
442c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                                FloatRegister flt_scratch,
443c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                                DoubleRegister dbl_scratch) {
444c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (op->IsDoubleRegister()) {
445c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    return ToDoubleRegister(op->index());
446c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (op->IsConstantOperand()) {
447c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LConstantOperand* const_op = LConstantOperand::cast(op);
44828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    HConstant* constant = chunk_->LookupConstant(const_op);
44928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    Handle<Object> literal = constant->handle();
450c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Representation r = chunk_->LookupLiteralRepresentation(const_op);
451c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (r.IsInteger32()) {
452c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ASSERT(literal->IsNumber());
453c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ li(at, Operand(static_cast<int32_t>(literal->Number())));
454c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ mtc1(at, flt_scratch);
455c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ cvt_d_w(dbl_scratch, flt_scratch);
456c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      return dbl_scratch;
457c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else if (r.IsDouble()) {
458594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Abort(kUnsupportedDoubleImmediate);
459c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else if (r.IsTagged()) {
460594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Abort(kUnsupportedTaggedImmediate);
461c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
462c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (op->IsStackSlot() || op->IsArgument()) {
463c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    MemOperand mem_op = ToMemOperand(op);
464c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ ldc1(dbl_scratch, mem_op);
465c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    return dbl_scratch;
466c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
467c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  UNREACHABLE();
468c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return dbl_scratch;
469c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
471c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
472fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.orgHandle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
47328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  HConstant* constant = chunk_->LookupConstant(op);
474a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
47528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  return constant->handle();
476fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org}
477fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
478fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
479fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.orgbool LCodeGen::IsInteger32(LConstantOperand* op) const {
480c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32();
481fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org}
482fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
483fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
484a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgbool LCodeGen::IsSmi(LConstantOperand* op) const {
485a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  return chunk_->LookupLiteralRepresentation(op).IsSmi();
486a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org}
487a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
488a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
489fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgint32_t LCodeGen::ToInteger32(LConstantOperand* op) const {
490fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  return ToRepresentation(op, Representation::Integer32());
491fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org}
492fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
493fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
494fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgint32_t LCodeGen::ToRepresentation(LConstantOperand* op,
495fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                                   const Representation& r) const {
49628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  HConstant* constant = chunk_->LookupConstant(op);
497fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  int32_t value = constant->Integer32Value();
498fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (r.IsInteger32()) return value;
499fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  ASSERT(r.IsSmiOrTagged());
500fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  return reinterpret_cast<int32_t>(Smi::FromInt(value));
501c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
502c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
503c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
504b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgSmi* LCodeGen::ToSmi(LConstantOperand* op) const {
505b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  HConstant* constant = chunk_->LookupConstant(op);
506b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  return Smi::FromInt(constant->Integer32Value());
507b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org}
508b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
509b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
510c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgdouble LCodeGen::ToDouble(LConstantOperand* op) const {
51128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  HConstant* constant = chunk_->LookupConstant(op);
51228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  ASSERT(constant->HasDoubleValue());
51328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  return constant->DoubleValue();
514c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
515c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
516c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
517c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgOperand LCodeGen::ToOperand(LOperand* op) {
518c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (op->IsConstantOperand()) {
519c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LConstantOperand* const_op = LConstantOperand::cast(op);
52028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    HConstant* constant = chunk()->LookupConstant(const_op);
521c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Representation r = chunk_->LookupLiteralRepresentation(const_op);
522fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    if (r.IsSmi()) {
523fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      ASSERT(constant->HasSmiValue());
524fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      return Operand(Smi::FromInt(constant->Integer32Value()));
525fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    } else if (r.IsInteger32()) {
52628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org      ASSERT(constant->HasInteger32Value());
52728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org      return Operand(constant->Integer32Value());
528c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else if (r.IsDouble()) {
529594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Abort(kToOperandUnsupportedDoubleImmediate);
530c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
531c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    ASSERT(r.IsTagged());
53228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    return Operand(constant->handle());
533c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (op->IsRegister()) {
534c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    return Operand(ToRegister(op));
535c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (op->IsDoubleRegister()) {
536594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Abort(kToOperandIsDoubleRegisterUnimplemented);
537c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    return Operand(0);
538c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
539c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Stack slots not implemented, use ToMemOperand instead.
540c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  UNREACHABLE();
541c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return Operand(0);
542c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
543c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
544c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
545c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgMemOperand LCodeGen::ToMemOperand(LOperand* op) const {
546c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!op->IsRegister());
547c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!op->IsDoubleRegister());
548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot());
549ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org  return MemOperand(fp, StackSlotOffset(op->index()));
550c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
551c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
552c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
553c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgMemOperand LCodeGen::ToHighMemOperand(LOperand* op) const {
554c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(op->IsDoubleStackSlot());
555ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org  return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize);
556c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
557c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
558c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
559c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::WriteTranslation(LEnvironment* environment,
560b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                Translation* translation) {
561c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (environment == NULL) return;
562c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
563c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // The translation includes one command per value in the environment.
564b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  int translation_size = environment->translation_size();
565c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // The output frame height does not include the parameters.
566c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int height = translation_size - environment->parameter_count();
567c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
568b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  WriteTranslation(environment->outer(), translation);
56959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  bool has_closure_id = !info()->closure().is_null() &&
57032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      !info()->closure().is_identical_to(environment->closure());
57159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  int closure_id = has_closure_id
5725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      ? DefineDeoptimizationLiteral(environment->closure())
5735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      : Translation::kSelfLiteralId;
5745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
575812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  switch (environment->frame_type()) {
576812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case JS_FUNCTION:
577812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      translation->BeginJSFrame(environment->ast_id(), closure_id, height);
578812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      break;
579812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case JS_CONSTRUCT:
580812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      translation->BeginConstructStubFrame(closure_id, translation_size);
581812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      break;
582de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    case JS_GETTER:
583de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      ASSERT(translation_size == 1);
584de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      ASSERT(height == 0);
585de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      translation->BeginGetterStubFrame(closure_id);
586de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      break;
587471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    case JS_SETTER:
58846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      ASSERT(translation_size == 2);
58946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      ASSERT(height == 0);
59046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      translation->BeginSetterStubFrame(closure_id);
591471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      break;
59259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    case STUB:
59359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      translation->BeginCompiledStubFrame();
59459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      break;
595812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    case ARGUMENTS_ADAPTOR:
596812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
597812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      break;
598fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
59956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
600594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int object_index = 0;
601594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int dematerialized_index = 0;
602c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (int i = 0; i < translation_size; ++i) {
603c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LOperand* value = environment->values()->at(i);
604594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    AddToTranslation(environment,
605594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                     translation,
60678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                     value,
60778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                     environment->HasTaggedValueAt(i),
608594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                     environment->HasUint32ValueAt(i),
609594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                     &object_index,
610594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                     &dematerialized_index);
611c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
612c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
613c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
614c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
615594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::AddToTranslation(LEnvironment* environment,
616594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                Translation* translation,
617c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                LOperand* op,
61878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                bool is_tagged,
619594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                bool is_uint32,
620594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                int* object_index_pointer,
621594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                int* dematerialized_index_pointer) {
622594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (op == LEnvironment::materialization_marker()) {
623594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int object_index = (*object_index_pointer)++;
624594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (environment->ObjectIsDuplicateAt(object_index)) {
625594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      int dupe_of = environment->ObjectDuplicateOfAt(object_index);
626594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      translation->DuplicateObject(dupe_of);
627594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return;
628594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
629594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int object_length = environment->ObjectLengthAt(object_index);
630594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (environment->ObjectIsArgumentsAt(object_index)) {
631594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      translation->BeginArgumentsObject(object_length);
632594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    } else {
633594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      translation->BeginCapturedObject(object_length);
634594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
635594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int dematerialized_index = *dematerialized_index_pointer;
636594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int env_offset = environment->translation_size() + dematerialized_index;
637594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    *dematerialized_index_pointer += object_length;
638594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    for (int i = 0; i < object_length; ++i) {
639594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      LOperand* value = environment->values()->at(env_offset + i);
640594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      AddToTranslation(environment,
641594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       translation,
642594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       value,
643594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       environment->HasTaggedValueAt(env_offset + i),
644594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       environment->HasUint32ValueAt(env_offset + i),
645594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       object_index_pointer,
646594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       dematerialized_index_pointer);
647594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
648594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return;
649594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
650594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
651b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  if (op->IsStackSlot()) {
652c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (is_tagged) {
653c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      translation->StoreStackSlot(op->index());
65478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    } else if (is_uint32) {
65578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      translation->StoreUint32StackSlot(op->index());
656c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
657c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      translation->StoreInt32StackSlot(op->index());
658c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
659c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (op->IsDoubleStackSlot()) {
660c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    translation->StoreDoubleStackSlot(op->index());
661c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (op->IsArgument()) {
662c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    ASSERT(is_tagged);
663c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    int src_index = GetStackSlotCount() + op->index();
664c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    translation->StoreStackSlot(src_index);
665c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (op->IsRegister()) {
666c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register reg = ToRegister(op);
667c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (is_tagged) {
668c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      translation->StoreRegister(reg);
66978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    } else if (is_uint32) {
67078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      translation->StoreUint32Register(reg);
671c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
672c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      translation->StoreInt32Register(reg);
673c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
674c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (op->IsDoubleRegister()) {
675c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DoubleRegister reg = ToDoubleRegister(op);
676c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    translation->StoreDoubleRegister(reg);
677c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (op->IsConstantOperand()) {
67828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op));
67928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    int src_index = DefineDeoptimizationLiteral(constant->handle());
680c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    translation->StoreLiteral(src_index);
681c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
682c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    UNREACHABLE();
683c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
684c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
685c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
686c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
687c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::CallCode(Handle<Code> code,
688c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        RelocInfo::Mode mode,
689c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        LInstruction* instr) {
690c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
691c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
692c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
693c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
694c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::CallCodeGeneric(Handle<Code> code,
695c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                               RelocInfo::Mode mode,
696c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                               LInstruction* instr,
697c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                               SafepointMode safepoint_mode) {
6981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EnsureSpaceForLazyDeopt();
699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(instr != NULL);
700c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LPointerMap* pointers = instr->pointer_map();
701c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  RecordPosition(pointers->position());
702c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Call(code, mode);
7030ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  RecordSafepointWithLazyDeopt(instr, safepoint_mode);
704c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
705c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
706c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
707c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::CallRuntime(const Runtime::Function* function,
708c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                           int num_arguments,
709c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                           LInstruction* instr) {
710c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(instr != NULL);
711c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LPointerMap* pointers = instr->pointer_map();
712c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(pointers != NULL);
713c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  RecordPosition(pointers->position());
714c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
715c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ CallRuntime(function, num_arguments);
7160ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
717c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
718c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
719c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
720c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
721c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                       int argc,
722c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                       LInstruction* instr) {
723c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ CallRuntimeSaveDoubles(id);
724c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  RecordSafepointWithRegisters(
7250ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
726c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
727c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
728c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
7290ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment,
7300ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                                    Safepoint::DeoptMode mode) {
731c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (!environment->HasBeenRegistered()) {
732c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Physical stack frame layout:
733c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // -x ............. -4  0 ..................................... y
734c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // [incoming arguments] [spill slots] [pushed outgoing arguments]
735c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
736c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Layout of the environment:
737c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // 0 ..................................................... size-1
738c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // [parameters] [locals] [expression stack including arguments]
739c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
740c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Layout of the translation:
741c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // 0 ........................................................ size - 1 + 4
742c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // [expression stack including arguments] [locals] [4 words] [parameters]
743c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // |>------------  translation_size ------------<|
744c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
745c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    int frame_count = 0;
746fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    int jsframe_count = 0;
747c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
748c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ++frame_count;
749812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      if (e->frame_type() == JS_FUNCTION) {
750fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org        ++jsframe_count;
751fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      }
752c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
7537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    Translation translation(&translations_, frame_count, jsframe_count, zone());
754b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    WriteTranslation(environment, &translation);
755c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    int deoptimization_index = deoptimizations_.length();
7560ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    int pc_offset = masm()->pc_offset();
7570ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    environment->Register(deoptimization_index,
7580ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                          translation.index(),
7590ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                          (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
7607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    deoptimizations_.Add(environment, zone());
761c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
762c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
763c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
764c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
765c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.comvoid LCodeGen::DeoptimizeIf(Condition condition,
766c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                            LEnvironment* environment,
7670410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com                            Deoptimizer::BailoutType bailout_type,
768c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                            Register src1,
769c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                            const Operand& src2) {
7700ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
771c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(environment->HasBeenRegistered());
772c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int id = environment->deoptimization_index();
7737c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  ASSERT(info()->IsOptimizing() || info()->IsStub());
7748432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Address entry =
7758432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
776c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (entry == NULL) {
777594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Abort(kBailoutWasNotPrepared);
778c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    return;
779c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
780c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
781c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(FLAG_deopt_every_n_times < 2);  // Other values not supported on MIPS.
782e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (FLAG_deopt_every_n_times == 1 &&
783e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      !info()->IsStub() &&
784e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      info()->opt_count() == id) {
78510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    ASSERT(frame_is_built_);
78610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    __ Call(entry, RelocInfo::RUNTIME_ENTRY);
787c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    return;
788c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
789c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
790594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (info()->ShouldTrapOnDeopt()) {
791c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Label skip;
792c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    if (condition != al) {
793c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com      __ Branch(&skip, NegateCondition(condition), src1, src2);
794c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
795c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ stop("trap_on_deopt");
796c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ bind(&skip);
797c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
798c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
79959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  ASSERT(info()->IsStub() || frame_is_built_);
800c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  if (condition == al && frame_is_built_) {
801c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    __ Call(entry, RelocInfo::RUNTIME_ENTRY, condition, src1, src2);
80259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  } else {
80359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // We often have several deopts to the same entry, reuse the last
80459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // jump entry if this is the case.
80559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    if (deopt_jump_table_.is_empty() ||
80659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        (deopt_jump_table_.last().address != entry) ||
8070410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com        (deopt_jump_table_.last().bailout_type != bailout_type) ||
80859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        (deopt_jump_table_.last().needs_frame != !frame_is_built_)) {
8090410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com      Deoptimizer::JumpTableEntry table_entry(entry,
8100410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com                                              bailout_type,
8110410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com                                              !frame_is_built_);
81259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      deopt_jump_table_.Add(table_entry, zone());
81359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    }
814c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    __ Branch(&deopt_jump_table_.last().label, condition, src1, src2);
81559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
816c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
817c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
818c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
819c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.comvoid LCodeGen::DeoptimizeIf(Condition condition,
8200410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com                            LEnvironment* environment,
8210410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com                            Register src1,
8220410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com                            const Operand& src2) {
8230410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com  Deoptimizer::BailoutType bailout_type = info()->IsStub()
8240410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com      ? Deoptimizer::LAZY
8250410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com      : Deoptimizer::EAGER;
826c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  DeoptimizeIf(condition, environment, bailout_type, src1, src2);
8270410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com}
8280410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com
8290410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com
8306ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.orgvoid LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
8316ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  ZoneList<Handle<Map> > maps(1, zone());
8326ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
8336ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
8346ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org    RelocInfo::Mode mode = it.rinfo()->rmode();
8356ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org    if (mode == RelocInfo::EMBEDDED_OBJECT &&
8366ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org        it.rinfo()->target_object()->IsMap()) {
8376ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org      Handle<Map> map(Map::cast(it.rinfo()->target_object()));
8386ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org      if (map->CanTransition()) {
8396ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org        maps.Add(map, zone());
8406ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org      }
8416ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org    }
8426ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  }
8436ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org#ifdef VERIFY_HEAP
8446ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  // This disables verification of weak embedded maps after full GC.
8456ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  // AddDependentCode can cause a GC, which would observe the state where
8466ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  // this code is not yet in the depended code lists of the embedded maps.
8476ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  NoWeakEmbeddedMapsVerificationScope disable_verification_of_embedded_maps;
8486ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org#endif
8496ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  for (int i = 0; i < maps.length(); i++) {
8502e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code);
8516ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org  }
8526ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org}
8536ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org
8546ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org
855c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
856c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int length = deoptimizations_.length();
857c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (length == 0) return;
858c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<DeoptimizationInputData> data =
859c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      factory()->NewDeoptimizationInputData(length, TENURED);
860c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
861876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  Handle<ByteArray> translations =
862876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      translations_.CreateByteArray(isolate()->factory());
863c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  data->SetTranslationByteArray(*translations);
864c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_));
865c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
866c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<FixedArray> literals =
867c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      factory()->NewFixedArray(deoptimization_literals_.length(), TENURED);
86879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  { AllowDeferredHandleDereference copy_handles;
86932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    for (int i = 0; i < deoptimization_literals_.length(); i++) {
87032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      literals->set(i, *deoptimization_literals_[i]);
87132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    }
87232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    data->SetLiteralArray(*literals);
873c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
874c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
875471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt()));
876c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_));
877c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
878c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Populate the deoptimization entries.
879c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (int i = 0; i < length; i++) {
880c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LEnvironment* env = deoptimizations_[i];
881471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    data->SetAstId(i, env->ast_id());
882c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    data->SetTranslationIndex(i, Smi::FromInt(env->translation_index()));
883c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    data->SetArgumentsStackHeight(i,
884c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                  Smi::FromInt(env->arguments_stack_height()));
8850ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    data->SetPc(i, Smi::FromInt(env->pc_offset()));
886c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
887c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  code->set_deoptimization_data(*data);
888c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
889c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
890c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
891c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgint LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) {
892c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int result = deoptimization_literals_.length();
893c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (int i = 0; i < deoptimization_literals_.length(); ++i) {
894c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (deoptimization_literals_[i].is_identical_to(literal)) return i;
895c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
8967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  deoptimization_literals_.Add(literal, zone());
897c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return result;
898c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
899c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
900c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
901c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() {
902c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(deoptimization_literals_.length() == 0);
903c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
904c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  const ZoneList<Handle<JSFunction> >* inlined_closures =
905c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      chunk()->inlined_closures();
906c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
907c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (int i = 0, length = inlined_closures->length();
908c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org       i < length;
909c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org       i++) {
910c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DefineDeoptimizationLiteral(inlined_closures->at(i));
911c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
912c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
913c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  inlined_function_count_ = deoptimization_literals_.length();
914c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
915c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
916c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
9170ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::RecordSafepointWithLazyDeopt(
9180ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    LInstruction* instr, SafepointMode safepoint_mode) {
9190ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) {
9200ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
9210ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  } else {
9220ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
9230ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    RecordSafepointWithRegisters(
9240ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry        instr->pointer_map(), 0, Safepoint::kLazyDeopt);
9250ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  }
9260ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry}
9270ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
9280ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
929c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::RecordSafepoint(
930c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LPointerMap* pointers,
931c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Safepoint::Kind kind,
932c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    int arguments,
9330ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    Safepoint::DeoptMode deopt_mode) {
934c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(expected_safepoint_kind_ == kind);
935c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
936c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  const ZoneList<LOperand*>* operands = pointers->GetNormalizedOperands();
937c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Safepoint safepoint = safepoints_.DefineSafepoint(masm(),
9380ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      kind, arguments, deopt_mode);
939c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (int i = 0; i < operands->length(); i++) {
940c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LOperand* pointer = operands->at(i);
941c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (pointer->IsStackSlot()) {
9427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      safepoint.DefinePointerSlot(pointer->index(), zone());
943c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) {
9447028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      safepoint.DefinePointerRegister(ToRegister(pointer), zone());
945c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
946c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
947c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (kind & Safepoint::kWithRegisters) {
948c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Register cp always contains a pointer to the context.
9497028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    safepoint.DefinePointerRegister(cp, zone());
950c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
952c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
953c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
954c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::RecordSafepoint(LPointerMap* pointers,
9550ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                               Safepoint::DeoptMode deopt_mode) {
9560ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode);
957c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
958c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
959c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
9600ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) {
9617028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  LPointerMap empty_pointers(RelocInfo::kNoPosition, zone());
9620ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  RecordSafepoint(&empty_pointers, deopt_mode);
963c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
964c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
965c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
966c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers,
967c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                            int arguments,
9680ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                            Safepoint::DeoptMode deopt_mode) {
9690ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  RecordSafepoint(
9700ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      pointers, Safepoint::kWithRegisters, arguments, deopt_mode);
971c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
972c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
974c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::RecordSafepointWithRegistersAndDoubles(
975c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LPointerMap* pointers,
976c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    int arguments,
9770ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    Safepoint::DeoptMode deopt_mode) {
9780ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  RecordSafepoint(
9790ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      pointers, Safepoint::kWithRegistersAndDoubles, arguments, deopt_mode);
980c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
981c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
982c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
983c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::RecordPosition(int position) {
984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (position == RelocInfo::kNoPosition) return;
985c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  masm()->positions_recorder()->RecordPosition(position);
986c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
987c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
988c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
989594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::RecordAndUpdatePosition(int position) {
990594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (position >= 0 && position != old_position_) {
991594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    masm()->positions_recorder()->RecordPosition(position);
992594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    old_position_ = position;
993594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
994594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
995594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
996594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
99732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.orgstatic const char* LabelType(LLabel* label) {
99832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (label->is_loop_header()) return " (loop header)";
99932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (label->is_osr_entry()) return " (OSR entry)";
100032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  return "";
100132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org}
100232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
100332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
1004c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLabel(LLabel* label) {
100532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------",
100632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org          current_instruction_,
100732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org          label->hydrogen_value()->id(),
1008b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org          label->block_id(),
100932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org          LabelType(label));
1010c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(label->label());
1011c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  current_block_ = label->block_id();
1012c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DoGap(label);
1013c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1014c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1015c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1016c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoParallelMove(LParallelMove* move) {
1017c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  resolver_.Resolve(move);
1018c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1019c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1020c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1021c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoGap(LGap* gap) {
1022c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (int i = LGap::FIRST_INNER_POSITION;
1023c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org       i <= LGap::LAST_INNER_POSITION;
1024c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org       i++) {
1025c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LGap::InnerPosition inner_pos = static_cast<LGap::InnerPosition>(i);
1026c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LParallelMove* move = gap->GetParallelMove(inner_pos);
1027c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (move != NULL) DoParallelMove(move);
1028c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1029c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1030c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1031c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1032c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoInstructionGap(LInstructionGap* instr) {
1033c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DoGap(instr);
1034c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1035c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1036c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1037c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoParameter(LParameter* instr) {
1038c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Nothing to do.
1039c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1040c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1041c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1042c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallStub(LCallStub* instr) {
1043c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
1044c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  switch (instr->hydrogen()->major_key()) {
1045c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case CodeStub::RegExpConstructResult: {
1046c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      RegExpConstructResultStub stub;
10478432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1048c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1049c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1050c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case CodeStub::RegExpExec: {
1051c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      RegExpExecStub stub;
10528432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1053c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1054c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1055c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case CodeStub::SubString: {
1056c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      SubStringStub stub;
10578432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1058c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1059c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1060c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case CodeStub::NumberToString: {
1061c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      NumberToStringStub stub;
10628432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1063c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1064c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1065c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case CodeStub::StringCompare: {
1066c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      StringCompareStub stub;
10678432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1068c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1069c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1070c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case CodeStub::TranscendentalCache: {
1071c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ lw(a0, MemOperand(sp, 0));
1072c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      TranscendentalCacheStub stub(instr->transcendental_type(),
1073c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                   TranscendentalCacheStub::TAGGED);
10748432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1075c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1076c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1077c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    default:
1078c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      UNREACHABLE();
1079c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1080c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1081c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1082c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1083c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
10841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Record the address of the first unknown OSR value as the place to enter.
10851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (osr_pc_offset_ == -1) osr_pc_offset_ = masm()->pc_offset();
1086c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1087c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1088c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1089c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoModI(LModI* instr) {
10908a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  HMod* hmod = instr->hydrogen();
10918a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  HValue* left = hmod->left();
10928a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  HValue* right = hmod->right();
10938a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  if (hmod->HasPowerOf2Divisor()) {
10948a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    const Register left_reg = ToRegister(instr->left());
10958a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    const Register result_reg = ToRegister(instr->result());
10968a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org
10978a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // Note: The code below even works when right contains kMinInt.
10988a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    int32_t divisor = Abs(right->GetInteger32Constant());
10998a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org
11008a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    Label left_is_not_negative, done;
11018a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    if (left->CanBeNegative()) {
1102c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org      __ Branch(left_reg.is(result_reg) ? PROTECT : USE_DELAY_SLOT,
1103c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org                &left_is_not_negative, ge, left_reg, Operand(zero_reg));
11048a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ subu(result_reg, zero_reg, left_reg);
11058a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ And(result_reg, result_reg, divisor - 1);
11068a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
11078a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org        DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg));
11088a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      }
11098a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ Branch(USE_DELAY_SLOT, &done);
11108a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ subu(result_reg, zero_reg, result_reg);
11118a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    }
1112c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
11138a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    __ bind(&left_is_not_negative);
1114c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org    __ And(result_reg, left_reg, divisor - 1);
11158a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    __ bind(&done);
1116c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
11171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  } else if (hmod->fixed_right_arg().has_value) {
11181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    const Register left_reg = ToRegister(instr->left());
11191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    const Register result_reg = ToRegister(instr->result());
1120c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org    const Register right_reg = ToRegister(instr->right());
11218a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org
11221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    int32_t divisor = hmod->fixed_right_arg().value;
11231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    ASSERT(IsPowerOf2(divisor));
11241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    // Check if our assumption of a fixed right operand still holds.
11261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    DeoptimizeIf(ne, instr->environment(), right_reg, Operand(divisor));
11271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Label left_is_not_negative, done;
11291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (left->CanBeNegative()) {
1130c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org      __ Branch(left_reg.is(result_reg) ? PROTECT : USE_DELAY_SLOT,
1131c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org                &left_is_not_negative, ge, left_reg, Operand(zero_reg));
11321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      __ subu(result_reg, zero_reg, left_reg);
11331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      __ And(result_reg, result_reg, divisor - 1);
11341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
11351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg));
11361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      }
11371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      __ Branch(USE_DELAY_SLOT, &done);
11381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      __ subu(result_reg, zero_reg, result_reg);
11391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }
11401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ bind(&left_is_not_negative);
11421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ And(result_reg, left_reg, divisor - 1);
11431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ bind(&done);
11441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  } else {
11468a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    const Register scratch = scratch0();
11478a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    const Register left_reg = ToRegister(instr->left());
11488a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    const Register result_reg = ToRegister(instr->result());
11498a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org
11500ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    // div runs in the background while we check for special cases.
11518a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    Register right_reg = EmitLoadRegister(instr->right(), scratch);
11528a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    __ div(left_reg, right_reg);
1153c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
11548a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    Label done;
11558a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // Check for x % 0, we have to deopt in this case because we can't return a
11568a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // NaN.
11578a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    if (right->CanBeZero()) {
11588a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      DeoptimizeIf(eq, instr->environment(), right_reg, Operand(zero_reg));
11590ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    }
1160c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
11618a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // Check for kMinInt % -1, we have to deopt if we care about -0, because we
11628a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // can't return that.
11638a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) {
116459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      Label left_not_min_int;
11658a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      __ Branch(&left_not_min_int, ne, left_reg, Operand(kMinInt));
11668a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      // TODO(svenpanne) Don't deopt when we don't care about -0.
11678a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      DeoptimizeIf(eq, instr->environment(), right_reg, Operand(-1));
116859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      __ bind(&left_not_min_int);
116959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    }
117059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
11718a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // TODO(svenpanne) Only emit the test/deopt if we have to.
11728a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    __ Branch(USE_DELAY_SLOT, &done, ge, left_reg, Operand(zero_reg));
11738a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    __ mfhi(result_reg);
11740ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
11758a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
11768a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg));
11770ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    }
11788a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    __ bind(&done);
1179c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1180c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1181c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1182c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1183b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgvoid LCodeGen::EmitSignedIntegerDivisionByConstant(
1184b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    Register result,
1185b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    Register dividend,
1186b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    int32_t divisor,
1187b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    Register remainder,
1188b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    Register scratch,
1189b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    LEnvironment* environment) {
1190b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  ASSERT(!AreAliased(dividend, scratch, at, no_reg));
1191b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1192b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  uint32_t divisor_abs = abs(divisor);
1193b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1194b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  int32_t power_of_2_factor =
1195b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    CompilerIntrinsics::CountTrailingZeros(divisor_abs);
1196b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1197b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  switch (divisor_abs) {
1198b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case 0:
1199b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      DeoptimizeIf(al, environment);
1200b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      return;
1201b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1202b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    case 1:
1203b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (divisor > 0) {
1204b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ Move(result, dividend);
1205b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      } else {
1206b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ SubuAndCheckForOverflow(result, zero_reg, dividend, scratch);
1207b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        DeoptimizeIf(lt, environment, scratch, Operand(zero_reg));
1208b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
1209b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      // Compute the remainder.
1210b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      __ Move(remainder, zero_reg);
1211b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      return;
1212b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1213b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    default:
1214b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (IsPowerOf2(divisor_abs)) {
1215b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // Branch and condition free code for integer division by a power
1216b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // of two.
1217b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        int32_t power = WhichPowerOf2(divisor_abs);
1218b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        if (power > 1) {
1219b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          __ sra(scratch, dividend, power - 1);
1220b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        }
1221b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ srl(scratch, scratch, 32 - power);
1222b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ Addu(scratch, dividend, Operand(scratch));
1223b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ sra(result, scratch,  power);
1224b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // Negate if necessary.
1225b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // We don't need to check for overflow because the case '-1' is
1226b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // handled separately.
1227b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        if (divisor < 0) {
1228b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          ASSERT(divisor != -1);
1229b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          __ Subu(result, zero_reg, Operand(result));
1230b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        }
1231b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // Compute the remainder.
1232b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        if (divisor > 0) {
1233b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          __ sll(scratch, result, power);
1234b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          __ Subu(remainder, dividend, Operand(scratch));
1235b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        } else {
1236b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          __ sll(scratch, result, power);
1237b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          __ Addu(remainder, dividend, Operand(scratch));
1238b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        }
1239b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        return;
1240b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      } else if (LChunkBuilder::HasMagicNumberForDivisor(divisor)) {
1241b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // Use magic numbers for a few specific divisors.
1242b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // Details and proofs can be found in:
1243b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // - Hacker's Delight, Henry S. Warren, Jr.
1244b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // - The PowerPC Compiler Writer's Guide
1245b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // and probably many others.
1246b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        //
1247b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // We handle
1248b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        //   <divisor with magic numbers> * <power of 2>
1249b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // but not
1250b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        //   <divisor with magic numbers> * <other divisor with magic numbers>
1251b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        DivMagicNumbers magic_numbers =
1252b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          DivMagicNumberFor(divisor_abs >> power_of_2_factor);
1253b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // Branch and condition free code for integer division by a power
1254b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // of two.
1255b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        const int32_t M = magic_numbers.M;
1256b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        const int32_t s = magic_numbers.s + power_of_2_factor;
1257b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1258b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ li(scratch, Operand(M));
1259b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ mult(dividend, scratch);
1260b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ mfhi(scratch);
1261b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        if (M < 0) {
1262b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          __ Addu(scratch, scratch, Operand(dividend));
1263b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        }
1264b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        if (s > 0) {
1265b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          __ sra(scratch, scratch, s);
1266b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          __ mov(scratch, scratch);
1267b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        }
1268b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ srl(at, dividend, 31);
1269b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ Addu(result, scratch, Operand(at));
1270b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        if (divisor < 0) __ Subu(result, zero_reg, Operand(result));
1271b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        // Compute the remainder.
1272b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ li(scratch, Operand(divisor));
1273b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ Mul(scratch, result, Operand(scratch));
1274b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ Subu(remainder, dividend, Operand(scratch));
1275b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      } else {
1276b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ li(scratch, Operand(divisor));
1277b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ div(dividend, scratch);
1278b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ mfhi(remainder);
1279b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        __ mflo(result);
1280b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
1281b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  }
1282b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org}
1283b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1284b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1285c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDivI(LDivI* instr) {
1286c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  const Register left = ToRegister(instr->left());
1287c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  const Register right = ToRegister(instr->right());
1288c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  const Register result = ToRegister(instr->result());
1289c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1290c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // On MIPS div is asynchronous - it will run in the background while we
1291c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // check for special cases.
1292c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ div(left, right);
1293c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1294c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Check for x / 0.
1295c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
1296c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg));
1297c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1298c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1299c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Check for (0 / -x) that will produce negative zero.
1300c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1301c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Label left_not_zero;
1302c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(&left_not_zero, ne, left, Operand(zero_reg));
1303c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(lt, instr->environment(), right, Operand(zero_reg));
1304c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ bind(&left_not_zero);
1305c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1306c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
130759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // Check for (kMinInt / -1).
1308c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1309c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Label left_not_min_int;
1310c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(&left_not_min_int, ne, left, Operand(kMinInt));
1311c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(eq, instr->environment(), right, Operand(-1));
1312c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ bind(&left_not_min_int);
1313c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1314c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
131541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (!instr->hydrogen()->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
131641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    __ mfhi(result);
131741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    DeoptimizeIf(ne, instr->environment(), result, Operand(zero_reg));
131841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
1319c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ mflo(result);
1320c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1321c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1322c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
132359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgvoid LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) {
132459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  DoubleRegister addend = ToDoubleRegister(instr->addend());
132559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  DoubleRegister multiplier = ToDoubleRegister(instr->multiplier());
132659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand());
132759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
132859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // This is computed in-place.
132959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  ASSERT(addend.is(ToDoubleRegister(instr->result())));
133059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
133159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  __ madd_d(addend, addend, multiplier, multiplicand);
133259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org}
133359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
133459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
1335b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgvoid LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
1336b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  const Register result = ToRegister(instr->result());
1337b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  const Register left = ToRegister(instr->left());
1338b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  const Register remainder = ToRegister(instr->temp());
1339b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  const Register scratch = scratch0();
1340b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1341b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  if (instr->right()->IsConstantOperand()) {
1342b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    Label done;
1343b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
1344b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (divisor < 0) {
1345b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg));
1346b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
1347b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    EmitSignedIntegerDivisionByConstant(result,
1348b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                        left,
1349b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                        divisor,
1350b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                        remainder,
1351b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                        scratch,
1352b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                        instr->environment());
1353b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    // We performed a truncating division. Correct the result if necessary.
1354b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ Branch(&done, eq, remainder, Operand(zero_reg), USE_DELAY_SLOT);
1355b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ Xor(scratch , remainder, Operand(divisor));
1356b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ Branch(&done, ge, scratch, Operand(zero_reg));
1357b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ Subu(result, result, Operand(1));
1358b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ bind(&done);
1359b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  } else {
1360b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    Label done;
1361b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    const Register right = ToRegister(instr->right());
1362b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1363b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    // On MIPS div is asynchronous - it will run in the background while we
1364b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    // check for special cases.
1365b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ div(left, right);
1366b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1367b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    // Check for x / 0.
1368b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg));
1369b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1370b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    // Check for (0 / -x) that will produce negative zero.
1371b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1372b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      Label left_not_zero;
1373b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      __ Branch(&left_not_zero, ne, left, Operand(zero_reg));
1374b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      DeoptimizeIf(lt, instr->environment(), right, Operand(zero_reg));
1375b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      __ bind(&left_not_zero);
1376b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
1377b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1378b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    // Check for (kMinInt / -1).
1379b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1380b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      Label left_not_min_int;
1381b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      __ Branch(&left_not_min_int, ne, left, Operand(kMinInt));
1382b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      DeoptimizeIf(eq, instr->environment(), right, Operand(-1));
1383b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      __ bind(&left_not_min_int);
1384b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
1385b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1386b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ mfhi(remainder);
1387b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ mflo(result);
1388b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1389b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    // We performed a truncating division. Correct the result if necessary.
1390b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ Branch(&done, eq, remainder, Operand(zero_reg), USE_DELAY_SLOT);
1391b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ Xor(scratch , remainder, Operand(right));
1392b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ Branch(&done, ge, scratch, Operand(zero_reg));
1393b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ Subu(result, result, Operand(1));
1394b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ bind(&done);
1395b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  }
1396b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org}
1397b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1398b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
1399c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoMulI(LMulI* instr) {
1400c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
1401c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
1402c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Note that result may alias left.
1403c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register left = ToRegister(instr->left());
1404c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* right_op = instr->right();
1405c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1406c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1407c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool bailout_on_minus_zero =
1408c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1409c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1410c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (right_op->IsConstantOperand() && !can_overflow) {
1411c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Use optimized code for specific constants.
1412fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    int32_t constant = ToRepresentation(
1413fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        LConstantOperand::cast(right_op),
1414fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        instr->hydrogen()->right()->representation());
1415c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1416c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (bailout_on_minus_zero && (constant < 0)) {
1417c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // The case of a null constant will be handled separately.
1418c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // If constant is negative and left is null, the result should be -0.
1419c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg));
1420c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1421c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1422c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    switch (constant) {
1423c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case -1:
1424c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ Subu(result, zero_reg, left);
1425c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
1426c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case 0:
1427c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        if (bailout_on_minus_zero) {
1428c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          // If left is strictly negative and the constant is null, the
1429c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          // result is -0. Deoptimize if required, otherwise return 0.
1430c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          DeoptimizeIf(lt, instr->environment(), left, Operand(zero_reg));
1431c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
1432c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ mov(result, zero_reg);
1433c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
1434c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case 1:
1435c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Nothing to do.
1436c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ Move(result, left);
1437c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
1438c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      default:
1439c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Multiplying by powers of two and powers of two plus or minus
1440c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // one can be done faster with shifted operands.
1441c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // For other constants we emit standard code.
1442c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        int32_t mask = constant >> 31;
1443c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        uint32_t constant_abs = (constant + mask) ^ mask;
1444c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1445c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        if (IsPowerOf2(constant_abs) ||
1446c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            IsPowerOf2(constant_abs - 1) ||
1447c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            IsPowerOf2(constant_abs + 1)) {
1448c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          if (IsPowerOf2(constant_abs)) {
1449c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            int32_t shift = WhichPowerOf2(constant_abs);
1450c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            __ sll(result, left, shift);
1451c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          } else if (IsPowerOf2(constant_abs - 1)) {
1452c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            int32_t shift = WhichPowerOf2(constant_abs - 1);
14532bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org            __ sll(scratch, left, shift);
14542bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org            __ Addu(result, scratch, left);
1455c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          } else if (IsPowerOf2(constant_abs + 1)) {
1456c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            int32_t shift = WhichPowerOf2(constant_abs + 1);
14572bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org            __ sll(scratch, left, shift);
14582bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org            __ Subu(result, scratch, left);
1459c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          }
1460c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1461c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          // Correct the sign of the result is the constant is negative.
1462c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          if (constant < 0)  {
1463c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            __ Subu(result, zero_reg, result);
1464c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          }
1465c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1466c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        } else {
1467c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          // Generate standard code.
1468c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          __ li(at, constant);
14693233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org          __ Mul(result, left, at);
1470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
1471c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1472c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1473c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
1474c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register right = EmitLoadRegister(right_op, scratch);
1475c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (bailout_on_minus_zero) {
1476c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org      __ Or(ToRegister(instr->temp()), left, right);
1477c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1478c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1479c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (can_overflow) {
1480c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // hi:lo = left * right.
1481fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      if (instr->hydrogen()->representation().IsSmi()) {
1482fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        __ SmiUntag(result, left);
1483fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        __ mult(result, right);
1484fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        __ mfhi(scratch);
1485fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        __ mflo(result);
1486fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      } else {
1487fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        __ mult(left, right);
1488fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        __ mfhi(scratch);
1489fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        __ mflo(result);
1490fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      }
1491c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ sra(at, result, 31);
1492c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      DeoptimizeIf(ne, instr->environment(), scratch, Operand(at));
1493c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
1494fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      if (instr->hydrogen()->representation().IsSmi()) {
1495fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        __ SmiUntag(result, left);
1496fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        __ Mul(result, result, right);
1497fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      } else {
1498fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        __ Mul(result, left, right);
1499fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      }
1500c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1501c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1502c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (bailout_on_minus_zero) {
1503c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // Bail out if the result is supposed to be negative zero.
1504c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Label done;
1505c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ Branch(&done, ne, result, Operand(zero_reg));
1506c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      DeoptimizeIf(lt,
1507c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                   instr->environment(),
1508c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org                   ToRegister(instr->temp()),
1509c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                   Operand(zero_reg));
1510c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ bind(&done);
1511c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1512c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1513c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1514c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1515c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1516c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoBitI(LBitI* instr) {
1517c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* left_op = instr->left();
1518c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* right_op = instr->right();
1519c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(left_op->IsRegister());
1520c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register left = ToRegister(left_op);
1521c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
1522c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Operand right(no_reg);
1523c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1524c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (right_op->IsStackSlot() || right_op->IsArgument()) {
1525c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    right = Operand(EmitLoadRegister(right_op, at));
1526c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
1527c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    ASSERT(right_op->IsRegister() || right_op->IsConstantOperand());
1528c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    right = ToOperand(right_op);
1529c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1530c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1531c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  switch (instr->op()) {
1532c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::BIT_AND:
1533c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ And(result, left, right);
1534c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1535c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::BIT_OR:
1536c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ Or(result, left, right);
1537c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1538c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::BIT_XOR:
1539594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      if (right_op->IsConstantOperand() && right.immediate() == int32_t(~0)) {
1540594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        __ Nor(result, zero_reg, left);
1541594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      } else {
1542594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        __ Xor(result, left, right);
1543594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      }
1544c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1545c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    default:
1546c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      UNREACHABLE();
1547c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1549c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1550c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1551c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1552c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoShiftI(LShiftI* instr) {
1553c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so
1554c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // result may alias either of them.
1555c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* right_op = instr->right();
1556c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register left = ToRegister(instr->left());
1557c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
1558d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Register scratch = scratch0();
1559c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1560c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (right_op->IsRegister()) {
1561c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // No need to mask the right operand on MIPS, it is built into the variable
1562c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // shift instructions.
1563c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    switch (instr->op()) {
1564fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      case Token::ROR:
1565fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        __ Ror(result, left, Operand(ToRegister(right_op)));
1566fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        break;
1567c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case Token::SAR:
1568c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ srav(result, left, ToRegister(right_op));
1569c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
1570c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case Token::SHR:
1571c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ srlv(result, left, ToRegister(right_op));
1572c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        if (instr->can_deopt()) {
1573c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg));
1574c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
1575c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
1576c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case Token::SHL:
1577c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ sllv(result, left, ToRegister(right_op));
1578c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
1579c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      default:
1580c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        UNREACHABLE();
1581c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
1582c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1583c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
1584c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Mask the right_op operand.
1585c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    int value = ToInteger32(LConstantOperand::cast(right_op));
1586c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
1587c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    switch (instr->op()) {
1588fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      case Token::ROR:
1589fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (shift_count != 0) {
1590fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          __ Ror(result, left, Operand(shift_count));
1591fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        } else {
1592fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          __ Move(result, left);
1593fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        }
1594fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        break;
1595c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case Token::SAR:
1596c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        if (shift_count != 0) {
1597c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          __ sra(result, left, shift_count);
1598c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        } else {
1599c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          __ Move(result, left);
1600c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
1601c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
1602c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case Token::SHR:
1603c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        if (shift_count != 0) {
1604c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          __ srl(result, left, shift_count);
1605c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        } else {
1606c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          if (instr->can_deopt()) {
1607c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            __ And(at, left, Operand(0x80000000));
1608c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg));
1609c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          }
1610c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          __ Move(result, left);
1611c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
1612c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
1613c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case Token::SHL:
1614c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        if (shift_count != 0) {
1615d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          if (instr->hydrogen_value()->representation().IsSmi() &&
1616d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org              instr->can_deopt()) {
1617d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            if (shift_count != 1) {
1618d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org              __ sll(result, left, shift_count - 1);
1619d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org              __ SmiTagCheckOverflow(result, result, scratch);
1620d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            } else {
1621d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org              __ SmiTagCheckOverflow(result, left, scratch);
1622d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            }
1623d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg));
1624d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          } else {
1625d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            __ sll(result, left, shift_count);
1626d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          }
1627c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        } else {
1628c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          __ Move(result, left);
1629c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
1630c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
1631c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      default:
1632c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        UNREACHABLE();
1633c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
1634c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1635c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1636c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1637c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1638c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1639c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoSubI(LSubI* instr) {
1640c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* left = instr->left();
1641c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* right = instr->right();
1642c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LOperand* result = instr->result();
1643c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1644c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1645c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (!can_overflow) {
1646c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (right->IsStackSlot() || right->IsArgument()) {
1647c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Register right_reg = EmitLoadRegister(right, at);
1648c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ Subu(ToRegister(result), ToRegister(left), Operand(right_reg));
1649c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
1650c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ASSERT(right->IsRegister() || right->IsConstantOperand());
1651c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ Subu(ToRegister(result), ToRegister(left), ToOperand(right));
1652c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1653c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {  // can_overflow.
1654c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register overflow = scratch0();
1655c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register scratch = scratch1();
1656c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (right->IsStackSlot() ||
1657c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        right->IsArgument() ||
1658c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        right->IsConstantOperand()) {
1659c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Register right_reg = EmitLoadRegister(right, scratch);
1660c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ SubuAndCheckForOverflow(ToRegister(result),
1661c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 ToRegister(left),
1662c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 right_reg,
1663c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 overflow);  // Reg at also used as scratch.
1664c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
1665c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ASSERT(right->IsRegister());
1666c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // Due to overflow check macros not supporting constant operands,
1667c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // handling the IsConstantOperand case was moved to prev if clause.
1668c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ SubuAndCheckForOverflow(ToRegister(result),
1669c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 ToRegister(left),
1670c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 ToRegister(right),
1671c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 overflow);  // Reg at also used as scratch.
1672c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1673c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg));
1674c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1675c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1676c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1677c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1678c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoConstantI(LConstantI* instr) {
1679b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  __ li(ToRegister(instr->result()), Operand(instr->value()));
1680b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org}
1681b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
1682b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
1683b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgvoid LCodeGen::DoConstantS(LConstantS* instr) {
1684c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(ToRegister(instr->result()), Operand(instr->value()));
1685c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1686c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1687c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1688c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoConstantD(LConstantD* instr) {
1689c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(instr->result()->IsDoubleRegister());
1690c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DoubleRegister result = ToDoubleRegister(instr->result());
1691c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  double v = instr->value();
1692c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Move(result, v);
1693c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1694c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1695c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1696d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid LCodeGen::DoConstantE(LConstantE* instr) {
1697d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  __ li(ToRegister(instr->result()), Operand(instr->value()));
1698d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
1699d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1700d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1701c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoConstantT(LConstantT* instr) {
170264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Handle<Object> value = instr->value();
170379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowDeferredHandleDereference smi_check;
1704fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  __ LoadObject(ToRegister(instr->result()), value);
1705c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1706c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1707c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
170878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgvoid LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
170978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  Register result = ToRegister(instr->result());
1710c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register map = ToRegister(instr->value());
171178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  __ EnumLength(result, map);
171278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org}
171378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
171478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
1715c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoElementsKind(LElementsKind* instr) {
1716c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
1717c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input = ToRegister(instr->value());
1718c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1719c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Load map into |result|.
1720c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(result, FieldMemOperand(input, HeapObject::kMapOffset));
1721c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Load the map's "bit field 2" into |result|. We only need the first byte,
1722c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // but the following bit field extraction takes care of that anyway.
1723c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lbu(result, FieldMemOperand(result, Map::kBitField2Offset));
1724c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Retrieve elements_kind from bit field 2.
1725c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Ext(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount);
1726c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1727c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1728c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1729c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoValueOf(LValueOf* instr) {
1730c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input = ToRegister(instr->value());
1731c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
1732c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register map = ToRegister(instr->temp());
1733c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label done;
1734c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
17351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!instr->hydrogen()->value()->IsHeapObject()) {
17361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    // If the object is a smi return the object.
17371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ Move(result, input);
17381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ JumpIfSmi(input, &done);
17391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
1740c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1741c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // If the object is not a value type, return the object.
1742c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ GetObjectType(input, map, map);
1743c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&done, ne, map, Operand(JS_VALUE_TYPE));
1744c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(result, FieldMemOperand(input, JSValue::kValueOffset));
1745c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1746c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&done);
1747c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1748c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1749c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1750154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgvoid LCodeGen::DoDateField(LDateField* instr) {
1751c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register object = ToRegister(instr->date());
1752154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  Register result = ToRegister(instr->result());
1753c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register scratch = ToRegister(instr->temp());
1754154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  Smi* index = instr->index();
1755154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  Label runtime, done;
1756154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  ASSERT(object.is(a0));
1757154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  ASSERT(result.is(v0));
1758154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  ASSERT(!scratch.is(scratch0()));
1759154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  ASSERT(!scratch.is(object));
1760154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org
1761de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  __ And(at, object, Operand(kSmiTagMask));
1762de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
1763154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  __ GetObjectType(object, scratch, scratch);
1764de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_DATE_TYPE));
1765154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org
1766154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  if (index->value() == 0) {
1767154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    __ lw(result, FieldMemOperand(object, JSDate::kValueOffset));
1768154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  } else {
1769154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    if (index->value() < JSDate::kFirstUncachedField) {
1770154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
1771154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      __ li(scratch, Operand(stamp));
1772154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      __ lw(scratch, MemOperand(scratch));
1773154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      __ lw(scratch0(), FieldMemOperand(object, JSDate::kCacheStampOffset));
1774154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      __ Branch(&runtime, ne, scratch, Operand(scratch0()));
1775154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      __ lw(result, FieldMemOperand(object, JSDate::kValueOffset +
1776154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org                                            kPointerSize * index->value()));
1777154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      __ jmp(&done);
1778154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    }
1779154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    __ bind(&runtime);
1780154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    __ PrepareCallCFunction(2, scratch);
1781154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    __ li(a1, Operand(index));
1782154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
1783154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    __ bind(&done);
1784154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  }
1785154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org}
1786154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org
1787154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org
1788a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
1789a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register string = ToRegister(instr->string());
1790a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register index = ToRegister(instr->index());
1791a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register value = ToRegister(instr->value());
1792a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register scratch = scratch0();
1793a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  String::Encoding encoding = instr->encoding();
1794a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
1795a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  if (FLAG_debug_code) {
1796a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ lw(at, FieldMemOperand(string, HeapObject::kMapOffset));
1797a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset));
1798a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
1799a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ And(at, at, Operand(kStringRepresentationMask | kStringEncodingMask));
1800a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
1801a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
1802a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ Subu(at, at, Operand(encoding == String::ONE_BYTE_ENCODING
1803a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                                ? one_byte_seq_type : two_byte_seq_type));
1804594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Check(eq, kUnexpectedStringType, at, Operand(zero_reg));
1805a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
1806a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
1807a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  __ Addu(scratch,
1808a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org          string,
1809a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org          Operand(SeqString::kHeaderSize - kHeapObjectTag));
1810a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  if (encoding == String::ONE_BYTE_ENCODING) {
1811a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ Addu(at, scratch, index);
1812a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ sb(value, MemOperand(at));
1813a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  } else {
1814a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ sll(at, index, 1);
1815a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ Addu(at, scratch, at);
1816a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ sh(value, MemOperand(at));
1817a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
1818a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
1819a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1820a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1821c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoThrow(LThrow* instr) {
1822c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input_reg = EmitLoadRegister(instr->value(), at);
1823c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ push(input_reg);
1824c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallRuntime(Runtime::kThrow, 1, instr);
1825c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1826c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (FLAG_debug_code) {
1827c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ stop("Unreachable code.");
1828c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1829c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1830c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1831c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1832c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoAddI(LAddI* instr) {
1833c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* left = instr->left();
1834c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* right = instr->right();
1835c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LOperand* result = instr->result();
1836c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1837c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1838c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (!can_overflow) {
1839c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (right->IsStackSlot() || right->IsArgument()) {
1840c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Register right_reg = EmitLoadRegister(right, at);
1841c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ Addu(ToRegister(result), ToRegister(left), Operand(right_reg));
1842c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
1843c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ASSERT(right->IsRegister() || right->IsConstantOperand());
1844c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ Addu(ToRegister(result), ToRegister(left), ToOperand(right));
1845c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1846c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {  // can_overflow.
1847c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register overflow = scratch0();
1848c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register scratch = scratch1();
1849c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (right->IsStackSlot() ||
1850c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        right->IsArgument() ||
1851c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        right->IsConstantOperand()) {
1852c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Register right_reg = EmitLoadRegister(right, scratch);
1853c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ AdduAndCheckForOverflow(ToRegister(result),
1854c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 ToRegister(left),
1855c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 right_reg,
1856c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 overflow);  // Reg at also used as scratch.
1857c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
1858c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ASSERT(right->IsRegister());
1859c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // Due to overflow check macros not supporting constant operands,
1860c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // handling the IsConstantOperand case was moved to prev if clause.
1861c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ AdduAndCheckForOverflow(ToRegister(result),
1862c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 ToRegister(left),
1863c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 ToRegister(right),
1864c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 overflow);  // Reg at also used as scratch.
1865c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1866c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg));
1867c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1868c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1869c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1870c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1871471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1872c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* left = instr->left();
1873c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* right = instr->right();
1874471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  HMathMinMax::Operation operation = instr->hydrogen()->operation();
1875471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
1876fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
1877471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    Register left_reg = ToRegister(left);
1878471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    Operand right_op = (right->IsRegister() || right->IsConstantOperand())
1879471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        ? ToOperand(right)
1880471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        : Operand(EmitLoadRegister(right, at));
1881471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    Register result_reg = ToRegister(instr->result());
1882471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    Label return_right, done;
1883471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    if (!result_reg.is(left_reg)) {
1884471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ Branch(&return_right, NegateCondition(condition), left_reg, right_op);
1885471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ mov(result_reg, left_reg);
1886471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ Branch(&done);
1887471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    }
1888471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ Branch(&done, condition, left_reg, right_op);
1889471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ bind(&return_right);
1890471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ Addu(result_reg, zero_reg, right_op);
1891471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ bind(&done);
1892471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  } else {
1893471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    ASSERT(instr->hydrogen()->representation().IsDouble());
1894471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    FPURegister left_reg = ToDoubleRegister(left);
1895471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    FPURegister right_reg = ToDoubleRegister(right);
1896471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    FPURegister result_reg = ToDoubleRegister(instr->result());
1897471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    Label check_nan_left, check_zero, return_left, return_right, done;
1898471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ BranchF(&check_zero, &check_nan_left, eq, left_reg, right_reg);
1899471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ BranchF(&return_left, NULL, condition, left_reg, right_reg);
1900471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ Branch(&return_right);
1901471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
1902471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ bind(&check_zero);
1903471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // left == right != 0.
1904471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ BranchF(&return_left, NULL, ne, left_reg, kDoubleRegZero);
1905471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // At this point, both left and right are either 0 or -0.
1906471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    if (operation == HMathMinMax::kMathMin) {
1907471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ neg_d(left_reg, left_reg);
1908471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ sub_d(result_reg, left_reg, right_reg);
1909471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ neg_d(result_reg, result_reg);
1910471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    } else {
1911471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ add_d(result_reg, left_reg, right_reg);
1912471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    }
1913471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ Branch(&done);
1914471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
1915471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ bind(&check_nan_left);
1916471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // left == NaN.
1917471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ BranchF(NULL, &return_left, eq, left_reg, left_reg);
1918471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ bind(&return_right);
1919471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    if (!right_reg.is(result_reg)) {
1920471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ mov_d(result_reg, right_reg);
1921471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    }
1922471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ Branch(&done);
1923471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
1924471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ bind(&return_left);
1925471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    if (!left_reg.is(result_reg)) {
1926471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ mov_d(result_reg, left_reg);
1927471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    }
1928471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    __ bind(&done);
1929471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  }
1930471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org}
1931471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
1932471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
1933c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1934c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  DoubleRegister left = ToDoubleRegister(instr->left());
1935c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  DoubleRegister right = ToDoubleRegister(instr->right());
1936c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DoubleRegister result = ToDoubleRegister(instr->result());
1937c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  switch (instr->op()) {
1938c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::ADD:
1939c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ add_d(result, left, right);
1940c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1941c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::SUB:
1942c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ sub_d(result, left, right);
1943c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1944c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::MUL:
1945c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ mul_d(result, left, right);
1946c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1947c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::DIV:
1948c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ div_d(result, left, right);
1949c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1950c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::MOD: {
1951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // Save a0-a3 on the stack.
1952c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      RegList saved_regs = a0.bit() | a1.bit() | a2.bit() | a3.bit();
1953c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ MultiPush(saved_regs);
1954c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1955c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ PrepareCallCFunction(0, 2, scratch0());
1956c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ SetCallCDoubleArguments(left, right);
1957c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ CallCFunction(
1958c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          ExternalReference::double_fp_operation(Token::MOD, isolate()),
1959c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          0, 2);
1960c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // Move the result in the double result register.
1961c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ GetCFunctionDoubleResult(result);
1962c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1963c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // Restore saved register.
1964c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ MultiPop(saved_regs);
1965c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1966c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1967c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    default:
1968c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      UNREACHABLE();
1969c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
1970c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1971c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1972c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1974c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1975c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  ASSERT(ToRegister(instr->left()).is(a1));
1976c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  ASSERT(ToRegister(instr->right()).is(a0));
1977c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
1978c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1979c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  BinaryOpStub stub(instr->op(), NO_OVERWRITE);
19808432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1981c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Other arch use a nop here, to signal that there is no inlined
1982c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // patchable code. Mips does not need the nop, since our marker
1983c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // instruction (andi zero_reg) will never be used in normal code.
1984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1985c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1986c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
198732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.orgint LCodeGen::GetNextEmittedBlock() const {
198877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
198977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    if (!chunk_->GetLabel(i)->HasReplacement()) return i;
1990c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
1991c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return -1;
1992c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
1993c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
19941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<class InstrType>
19951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid LCodeGen::EmitBranch(InstrType instr,
1996c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                          Condition condition,
1997c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                          Register src1,
1998c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                          const Operand& src2) {
19991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  int left_block = instr->TrueDestination(chunk_);
2000e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  int right_block = instr->FalseDestination(chunk_);
20011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
200277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  int next_block = GetNextEmittedBlock();
2003c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  if (right_block == left_block || condition == al) {
2004c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    EmitGoto(left_block);
2005c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (left_block == next_block) {
2006c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(chunk_->GetAssemblyLabel(right_block),
2007c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com              NegateCondition(condition), src1, src2);
2008c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (right_block == next_block) {
2009c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    __ Branch(chunk_->GetAssemblyLabel(left_block), condition, src1, src2);
2010c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
2011c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    __ Branch(chunk_->GetAssemblyLabel(left_block), condition, src1, src2);
2012c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(chunk_->GetAssemblyLabel(right_block));
2013c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
2014c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2015c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2016c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
20171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<class InstrType>
20181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid LCodeGen::EmitBranchF(InstrType instr,
2019c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                           Condition condition,
2020c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                           FPURegister src1,
2021c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                           FPURegister src2) {
20221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  int right_block = instr->FalseDestination(chunk_);
20231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  int left_block = instr->TrueDestination(chunk_);
20241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
202577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  int next_block = GetNextEmittedBlock();
2026c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (right_block == left_block) {
2027c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    EmitGoto(left_block);
2028c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (left_block == next_block) {
2029c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ BranchF(chunk_->GetAssemblyLabel(right_block), NULL,
2030c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com               NegateCondition(condition), src1, src2);
2031c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (right_block == next_block) {
2032c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL,
2033c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com               condition, src1, src2);
2034c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
2035c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL,
2036c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com               condition, src1, src2);
2037c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(chunk_->GetAssemblyLabel(right_block));
2038c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
2039c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2040c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2041c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2042c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.comtemplate<class InstrType>
2043c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.comvoid LCodeGen::EmitFalseBranchF(InstrType instr,
2044c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                                Condition condition,
2045c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                                FPURegister src1,
2046c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                                FPURegister src2) {
2047c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  int false_block = instr->FalseDestination(chunk_);
2048c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  __ BranchF(chunk_->GetAssemblyLabel(false_block), NULL,
2049c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com             condition, src1, src2);
2050c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com}
2051c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com
2052c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com
20534e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid LCodeGen::DoDebugBreak(LDebugBreak* instr) {
20544e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  __ stop("LDebugBreak");
20554e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org}
20564e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
20574e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
2058e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgvoid LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) {
2059e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  Representation r = instr->hydrogen()->value()->representation();
2060e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  if (r.IsSmiOrInteger32() || r.IsDouble()) {
2061e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    EmitBranch(instr, al, zero_reg, Operand(zero_reg));
2062e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  } else {
2063e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    ASSERT(r.IsTagged());
2064e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    Register reg = ToRegister(instr->value());
2065e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    HType type = instr->hydrogen()->value()->type();
2066e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    if (type.IsTaggedNumber()) {
2067e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      EmitBranch(instr, al, zero_reg, Operand(zero_reg));
2068e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    }
2069e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2070e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    __ lw(scratch0(), FieldMemOperand(reg, HeapObject::kMapOffset));
2071e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
2072e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    EmitBranch(instr, eq, scratch0(), Operand(at));
2073e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  }
2074e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org}
2075e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
2076e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
2077c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoBranch(LBranch* instr) {
2078c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Representation r = instr->hydrogen()->value()->representation();
2079a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  if (r.IsInteger32() || r.IsSmi()) {
2080b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    ASSERT(!info()->IsStub());
2081c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Register reg = ToRegister(instr->value());
20821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    EmitBranch(instr, ne, reg, Operand(zero_reg));
2083c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (r.IsDouble()) {
2084b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    ASSERT(!info()->IsStub());
2085c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    DoubleRegister reg = ToDoubleRegister(instr->value());
2086c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Test the double value. Zero and NaN are false.
20871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    EmitBranchF(instr, nue, reg, kDoubleRegZero);
2088c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
2089c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    ASSERT(r.IsTagged());
2090c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Register reg = ToRegister(instr->value());
2091c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    HType type = instr->hydrogen()->value()->type();
2092c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (type.IsBoolean()) {
2093b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org      ASSERT(!info()->IsStub());
2094c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ LoadRoot(at, Heap::kTrueValueRootIndex);
20951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitBranch(instr, eq, reg, Operand(at));
2096c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else if (type.IsSmi()) {
2097b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org      ASSERT(!info()->IsStub());
20981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitBranch(instr, ne, reg, Operand(zero_reg));
20991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    } else if (type.IsJSArray()) {
21001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      ASSERT(!info()->IsStub());
21011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitBranch(instr, al, zero_reg, Operand(zero_reg));
21021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    } else if (type.IsHeapNumber()) {
21031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      ASSERT(!info()->IsStub());
21041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      DoubleRegister dbl_scratch = double_scratch0();
21051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
21061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      // Test the double value. Zero and NaN are false.
21071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitBranchF(instr, nue, dbl_scratch, kDoubleRegZero);
21081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    } else if (type.IsString()) {
21091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      ASSERT(!info()->IsStub());
21101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      __ lw(at, FieldMemOperand(reg, String::kLengthOffset));
21111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitBranch(instr, ne, at, Operand(zero_reg));
2112c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
2113c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2114c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // Avoid deopts in the case where we've never executed this path before.
21151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
2116c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2117c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      if (expected.Contains(ToBooleanStub::UNDEFINED)) {
2118c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // undefined -> false.
2119c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
21201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2121c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      }
2122c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      if (expected.Contains(ToBooleanStub::BOOLEAN)) {
2123c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Boolean -> its value.
2124c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ LoadRoot(at, Heap::kTrueValueRootIndex);
21251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ Branch(instr->TrueLabel(chunk_), eq, reg, Operand(at));
2126c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ LoadRoot(at, Heap::kFalseValueRootIndex);
21271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2128c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      }
2129c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
2130c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // 'null' -> false.
2131c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ LoadRoot(at, Heap::kNullValueRootIndex);
21321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2133c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      }
2134c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2135c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      if (expected.Contains(ToBooleanStub::SMI)) {
2136c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Smis: 0 -> false, all other -> true.
21371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg));
21381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2139c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      } else if (expected.NeedsMap()) {
2140c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // If we need a map later and have a Smi -> deopt.
2141c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ And(at, reg, Operand(kSmiTagMask));
2142c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
2143c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      }
2144c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2145c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      const Register map = scratch0();
2146c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      if (expected.NeedsMap()) {
2147c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ lw(map, FieldMemOperand(reg, HeapObject::kMapOffset));
2148c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        if (expected.CanBeUndetectable()) {
2149c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          // Undetectable -> false.
2150c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset));
2151c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          __ And(at, at, Operand(1 << Map::kIsUndetectable));
21521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          __ Branch(instr->FalseLabel(chunk_), ne, at, Operand(zero_reg));
2153c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
2154c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      }
2155c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2156c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
2157c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // spec object -> true.
2158c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset));
21591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ Branch(instr->TrueLabel(chunk_),
21601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                  ge, at, Operand(FIRST_SPEC_OBJECT_TYPE));
2161c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      }
2162c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2163c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      if (expected.Contains(ToBooleanStub::STRING)) {
2164c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // String value -> false iff empty.
2165c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        Label not_string;
2166c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset));
2167c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ Branch(&not_string, ge , at, Operand(FIRST_NONSTRING_TYPE));
2168c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ lw(at, FieldMemOperand(reg, String::kLengthOffset));
21691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ Branch(instr->TrueLabel(chunk_), ne, at, Operand(zero_reg));
21701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ Branch(instr->FalseLabel(chunk_));
2171c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ bind(&not_string);
2172c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      }
2173c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2174f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      if (expected.Contains(ToBooleanStub::SYMBOL)) {
2175f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        // Symbol value -> true.
2176f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        const Register scratch = scratch1();
2177f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
21781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ Branch(instr->TrueLabel(chunk_), eq, scratch, Operand(SYMBOL_TYPE));
2179f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      }
2180f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
2181c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
2182c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // heap number -> false iff +0, -0, or NaN.
2183c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        DoubleRegister dbl_scratch = double_scratch0();
2184c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        Label not_heap_number;
2185c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
2186c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ Branch(&not_heap_number, ne, map, Operand(at));
2187c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
21881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
21891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                   ne, dbl_scratch, kDoubleRegZero);
2190c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Falls through if dbl_scratch == 0.
21911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        __ Branch(instr->FalseLabel(chunk_));
2192c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ bind(&not_heap_number);
2193c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      }
2194c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
21951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      if (!expected.IsGeneric()) {
21961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        // We've seen something for the first time -> deopt.
21971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        // This can only happen if we are not generic already.
21981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg));
21991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      }
2200c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
2201c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
2202c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2203c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2204c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2205c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::EmitGoto(int block) {
220632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (!IsNextEmittedBlock(block)) {
22071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block)));
2208c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
2209c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2210c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2211c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2212c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoGoto(LGoto* instr) {
2213c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  EmitGoto(instr->block_id());
2214c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2215c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2216c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2217c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgCondition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
2218c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Condition cond = kNoCondition;
2219c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  switch (op) {
2220c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::EQ:
2221c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::EQ_STRICT:
2222c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      cond = eq;
2223c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
2224c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::LT:
2225c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      cond = is_unsigned ? lo : lt;
2226c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
2227c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::GT:
2228c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      cond = is_unsigned ? hi : gt;
2229c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
2230c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::LTE:
2231c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      cond = is_unsigned ? ls : le;
2232c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
2233c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::GTE:
2234c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      cond = is_unsigned ? hs : ge;
2235c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
2236c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::IN:
2237c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case Token::INSTANCEOF:
2238c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    default:
2239c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      UNREACHABLE();
2240c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
2241c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return cond;
2242c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2243c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2244c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2245e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgvoid LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
2246c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* left = instr->left();
2247c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* right = instr->right();
2248c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Condition cond = TokenToCondition(instr->op(), false);
2249c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2250c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (left->IsConstantOperand() && right->IsConstantOperand()) {
2251c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // We can statically evaluate the comparison.
2252c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    double left_val = ToDouble(LConstantOperand::cast(left));
2253c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    double right_val = ToDouble(LConstantOperand::cast(right));
22541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    int next_block = EvalComparison(instr->op(), left_val, right_val) ?
22551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2256c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    EmitGoto(next_block);
2257c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
2258c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (instr->is_double()) {
2259c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // Compare left and right as doubles and load the
2260c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // resulting flags into the normal status register.
2261c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      FPURegister left_reg = ToDoubleRegister(left);
2262c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      FPURegister right_reg = ToDoubleRegister(right);
2263c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2264c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // If a NaN is involved, i.e. the result is unordered,
2265c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // jump to false block label.
22661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      __ BranchF(NULL, instr->FalseLabel(chunk_), eq,
2267c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                 left_reg, right_reg);
2268c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
22691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitBranchF(instr, cond, left_reg, right_reg);
2270c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
2271c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Register cmp_left;
2272c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Operand cmp_right = Operand(0);
2273c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2274c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      if (right->IsConstantOperand()) {
2275b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org        int32_t value = ToInteger32(LConstantOperand::cast(right));
2276b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org        if (instr->hydrogen_value()->representation().IsSmi()) {
2277b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org          cmp_left = ToRegister(left);
2278b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org          cmp_right = Operand(Smi::FromInt(value));
2279b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org        } else {
2280b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org          cmp_left = ToRegister(left);
2281b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org          cmp_right = Operand(value);
2282b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org        }
2283c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      } else if (left->IsConstantOperand()) {
2284b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org        int32_t value = ToInteger32(LConstantOperand::cast(left));
2285b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org        if (instr->hydrogen_value()->representation().IsSmi()) {
2286b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org           cmp_left = ToRegister(right);
2287b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org           cmp_right = Operand(Smi::FromInt(value));
2288b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org        } else {
2289b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org          cmp_left = ToRegister(right);
2290b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org          cmp_right = Operand(value);
2291b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org        }
2292c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // We transposed the operands. Reverse the condition.
2293c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        cond = ReverseCondition(cond);
2294c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      } else {
2295c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        cmp_left = ToRegister(left);
2296c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        cmp_right = Operand(ToRegister(right));
2297c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      }
2298c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
22991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitBranch(instr, cond, cmp_left, cmp_right);
2300c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
2301c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
2302c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2303c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2304c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2305c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2306c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register left = ToRegister(instr->left());
2307c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register right = ToRegister(instr->right());
2308c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
23091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, eq, left, Operand(right));
2310c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2311c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2312c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2313c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.comvoid LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2314c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  if (instr->hydrogen()->representation().IsTagged()) {
2315c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    Register input_reg = ToRegister(instr->object());
2316c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    __ li(at, Operand(factory()->the_hole_value()));
2317c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    EmitBranch(instr, eq, input_reg, Operand(at));
2318c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    return;
2319c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  }
2320c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com
2321c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  DoubleRegister input_reg = ToDoubleRegister(instr->object());
2322c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  EmitFalseBranchF(instr, eq, input_reg, input_reg);
2323c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com
2324c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  Register scratch = scratch0();
2325c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  __ FmoveHigh(scratch, input_reg);
2326c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  EmitBranch(instr, eq, scratch, Operand(kHoleNanUpper32));
2327c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com}
2328c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com
2329c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com
2330c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgCondition LCodeGen::EmitIsObject(Register input,
2331c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 Register temp1,
23320ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                 Register temp2,
2333c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 Label* is_not_object,
2334c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 Label* is_object) {
2335c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ JumpIfSmi(input, is_not_object);
2336c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2337c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ LoadRoot(temp2, Heap::kNullValueRootIndex);
2338c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(is_object, eq, input, Operand(temp2));
2339c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2340c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Load map.
2341c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(temp1, FieldMemOperand(input, HeapObject::kMapOffset));
2342c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Undetectable objects behave like undefined.
2343c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lbu(temp2, FieldMemOperand(temp1, Map::kBitFieldOffset));
2344c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ And(temp2, temp2, Operand(1 << Map::kIsUndetectable));
2345c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(is_not_object, ne, temp2, Operand(zero_reg));
2346c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2347c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Load instance type and check that it is in object type range.
2348c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lbu(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset));
2349c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(is_not_object,
2350c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            lt, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
2351c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2352c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return le;
2353c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2354c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2355c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2356c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2357c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register reg = ToRegister(instr->value());
2358c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register temp1 = ToRegister(instr->temp());
2359c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register temp2 = scratch0();
2360c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2361c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Condition true_cond =
23621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitIsObject(reg, temp1, temp2,
23631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2364c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
23651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, true_cond, temp2,
2366c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org             Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
2367c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2368c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2369c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2370f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.orgCondition LCodeGen::EmitIsString(Register input,
2371f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org                                 Register temp1,
23721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                 Label* is_not_string,
23731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                 SmiCheck check_needed = INLINE_SMI_CHECK) {
23741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (check_needed == INLINE_SMI_CHECK) {
23751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ JumpIfSmi(input, is_not_string);
23761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
2377f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  __ GetObjectType(input, temp1, temp1);
2378f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
2379f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  return lt;
2380f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org}
2381f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
2382f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
2383f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.orgvoid LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2384c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register reg = ToRegister(instr->value());
2385c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register temp1 = ToRegister(instr->temp());
2386f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
23871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  SmiCheck check_needed =
23881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      instr->hydrogen()->value()->IsHeapObject()
23891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
2390f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  Condition true_cond =
23911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      EmitIsString(reg, temp1, instr->FalseLabel(chunk_), check_needed);
2392f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
23931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, true_cond, temp1,
2394f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org             Operand(FIRST_NONSTRING_TYPE));
2395f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org}
2396f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
2397f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
2398c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2399c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input_reg = EmitLoadRegister(instr->value(), at);
2400c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ And(at, input_reg, kSmiTagMask);
24011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, eq, at, Operand(zero_reg));
2402c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2403c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2404c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2405c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2406c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input = ToRegister(instr->value());
2407c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register temp = ToRegister(instr->temp());
2408c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
24091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!instr->hydrogen()->value()->IsHeapObject()) {
24101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ JumpIfSmi(input, instr->FalseLabel(chunk_));
24111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
2412c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(temp, FieldMemOperand(input, HeapObject::kMapOffset));
2413c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lbu(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
2414c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ And(at, temp, Operand(1 << Map::kIsUndetectable));
24151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, ne, at, Operand(zero_reg));
2416c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2417c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2418c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2419f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.orgstatic Condition ComputeCompareCondition(Token::Value op) {
2420f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  switch (op) {
2421f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org    case Token::EQ_STRICT:
2422f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org    case Token::EQ:
2423f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org      return eq;
2424f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org    case Token::LT:
2425f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org      return lt;
2426f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org    case Token::GT:
2427f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org      return gt;
2428f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org    case Token::LTE:
2429f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org      return le;
2430f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org    case Token::GTE:
2431f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org      return ge;
2432f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org    default:
2433f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org      UNREACHABLE();
2434f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org      return kNoCondition;
2435f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  }
2436f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org}
2437f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
2438f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
2439f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.orgvoid LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2440f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  Token::Value op = instr->op();
2441f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
24428432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
2443f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET, instr);
2444f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
2445f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  Condition condition = ComputeCompareCondition(op);
2446f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
24471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, condition, v0, Operand(zero_reg));
2448f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org}
2449f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
2450f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
2451c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgstatic InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2452c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  InstanceType from = instr->from();
2453c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  InstanceType to = instr->to();
2454c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (from == FIRST_TYPE) return to;
2455c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(from == to || to == LAST_TYPE);
2456c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return from;
2457c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2458c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2459c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2460c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgstatic Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2461c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  InstanceType from = instr->from();
2462c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  InstanceType to = instr->to();
2463c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (from == to) return eq;
2464c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (to == LAST_TYPE) return hs;
2465c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (from == FIRST_TYPE) return ls;
2466c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  UNREACHABLE();
2467c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return eq;
2468c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2469c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2471c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2472c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
2473c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input = ToRegister(instr->value());
2474c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
24751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!instr->hydrogen()->value()->IsHeapObject()) {
24761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ JumpIfSmi(input, instr->FalseLabel(chunk_));
24771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
2478c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2479c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ GetObjectType(input, scratch, scratch);
24801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr,
2481c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org             BranchCondition(instr->hydrogen()),
2482c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org             scratch,
2483c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org             Operand(TestType(instr->hydrogen())));
2484c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2485c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2486c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2487c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2488c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input = ToRegister(instr->value());
2489c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
2490c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2491c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  __ AssertString(input);
2492c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2493c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(result, FieldMemOperand(input, String::kHashFieldOffset));
2494c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ IndexFromHash(result, result);
2495c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2496c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2497c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2498c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoHasCachedArrayIndexAndBranch(
2499c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LHasCachedArrayIndexAndBranch* instr) {
2500c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input = ToRegister(instr->value());
2501c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
2502c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2503c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(scratch,
2504c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org         FieldMemOperand(input, String::kHashFieldOffset));
2505c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ And(at, scratch, Operand(String::kContainsCachedArrayIndexMask));
25061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, eq, at, Operand(zero_reg));
2507c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2508c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2509c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
25102efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Branches to a label or falls through with the answer in flags.  Trashes
25112efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// the temp registers, but not the input.
2512c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::EmitClassOfTest(Label* is_true,
2513c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                               Label* is_false,
2514c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                               Handle<String>class_name,
2515c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                               Register input,
2516c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                               Register temp,
2517c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                               Register temp2) {
2518c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!input.is(temp));
25192efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  ASSERT(!input.is(temp2));
25202efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  ASSERT(!temp.is(temp2));
25212efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
2522c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ JumpIfSmi(input, is_false);
2523c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
252459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Function"))) {
2525c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Assuming the following assertions, we can use the same compares to test
2526c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // for both being a function type and being in the object type range.
2527c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
2528c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
2529c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                  FIRST_SPEC_OBJECT_TYPE + 1);
2530c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
2531c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                  LAST_SPEC_OBJECT_TYPE - 1);
2532c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
2533c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2534c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ GetObjectType(input, temp, temp2);
2535c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(is_false, lt, temp2, Operand(FIRST_SPEC_OBJECT_TYPE));
2536c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(is_true, eq, temp2, Operand(FIRST_SPEC_OBJECT_TYPE));
2537c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(is_true, eq, temp2, Operand(LAST_SPEC_OBJECT_TYPE));
2538c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
2539c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Faster code path to avoid two compares: subtract lower bound from the
2540c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // actual type and do a signed compare with the width of the type range.
2541c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ GetObjectType(input, temp, temp2);
2542c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Subu(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
2543c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(is_false, gt, temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
2544c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                           FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
2545c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
2546c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2547c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range.
2548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Check if the constructor in the map is a function.
2549c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(temp, FieldMemOperand(temp, Map::kConstructorOffset));
2550c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2551c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Objects with a non-function constructor have class 'Object'.
2552c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ GetObjectType(temp, temp2, temp2);
255359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Object"))) {
2554c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(is_true, ne, temp2, Operand(JS_FUNCTION_TYPE));
2555c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
2556c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(is_false, ne, temp2, Operand(JS_FUNCTION_TYPE));
2557c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
2558c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2559c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // temp now contains the constructor function. Grab the
2560c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // instance class name from there.
2561c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(temp, FieldMemOperand(temp, JSFunction::kSharedFunctionInfoOffset));
2562c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(temp, FieldMemOperand(temp,
2563c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                               SharedFunctionInfo::kInstanceClassNameOffset));
2564750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // The class name we are testing against is internalized since it's a literal.
2565750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // The name in the constructor is internalized because of the way the context
2566750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // is booted.  This routine isn't expected to work for random API-created
2567c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // classes and it doesn't have to because you can't access it with natives
2568750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // syntax.  Since both sides are internalized it is sufficient to use an
2569750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // identity comparison.
2570c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2571c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // End with the address of this class_name instance in temp register.
2572c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // On MIPS, the caller must do the comparison with Handle<String>class_name.
2573c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2574c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2575c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2576c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2577c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input = ToRegister(instr->value());
2578c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register temp = scratch0();
2579c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register temp2 = ToRegister(instr->temp());
2580c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<String> class_name = instr->hydrogen()->class_name();
2581c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
25821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
25831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                  class_name, input, temp, temp2);
2584c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
25851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, eq, temp, Operand(class_name));
2586c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2587c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2588c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2589c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2590c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register reg = ToRegister(instr->value());
2591c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register temp = ToRegister(instr->temp());
2592c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2593c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
25941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, eq, temp, Operand(instr->map()));
2595c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2596c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2597c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2598c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2599c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label true_label, done;
2600c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  ASSERT(ToRegister(instr->left()).is(a0));  // Object is in a0.
2601c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  ASSERT(ToRegister(instr->right()).is(a1));  // Function is in a1.
2602c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
2603c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(result.is(v0));
2604c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2605c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  InstanceofStub stub(InstanceofStub::kArgsInRegisters);
26068432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2607c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2608c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&true_label, eq, result, Operand(zero_reg));
2609c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(result, Operand(factory()->false_value()));
2610c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&done);
2611c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&true_label);
2612c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(result, Operand(factory()->true_value()));
2613c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&done);
2614c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2615c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2616c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2617c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2618c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  class DeferredInstanceOfKnownGlobal: public LDeferredCode {
2619c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   public:
2620c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
2621c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                  LInstanceOfKnownGlobal* instr)
2622c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
2623c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual void Generate() {
26240ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_);
2625c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
2626c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual LInstruction* instr() { return instr_; }
2627c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Label* map_check() { return &map_check_; }
2628c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2629c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   private:
2630c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LInstanceOfKnownGlobal* instr_;
2631c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Label map_check_;
2632c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  };
2633c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2634c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeferredInstanceOfKnownGlobal* deferred;
26357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2636c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2637c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label done, false_result;
2638c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register object = ToRegister(instr->value());
2639c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register temp = ToRegister(instr->temp());
2640c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
2641c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2642c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(object.is(a0));
2643c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(result.is(v0));
2644c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2645c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // A Smi is not instance of anything.
2646c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ JumpIfSmi(object, &false_result);
2647c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2648c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // This is the inlined call site instanceof cache. The two occurences of the
2649c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // hole value will be patched to the last map/result pair generated by the
2650c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // instanceof stub.
2651c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label cache_miss;
2652c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register map = temp;
2653c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(map, FieldMemOperand(object, HeapObject::kMapOffset));
2654c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2655c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
2656c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(deferred->map_check());  // Label for calculating code patching.
2657c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // We use Factory::the_hole_value() on purpose instead of loading from the
2658c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // root array to force relocation to be able to later patch with
2659c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // the cached map.
2660f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org  Handle<Cell> cell = factory()->NewCell(factory()->the_hole_value());
266105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  __ li(at, Operand(Handle<Object>(cell)));
2662b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  __ lw(at, FieldMemOperand(at, PropertyCell::kValueOffset));
2663c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&cache_miss, ne, map, Operand(at));
2664c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // We use Factory::the_hole_value() on purpose instead of loading from the
2665c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // root array to force relocation to be able to later patch
2666c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // with true or false.
266788aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  __ li(result, Operand(factory()->the_hole_value()), CONSTANT_SIZE);
2668c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&done);
2669c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2670c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // The inlined call site cache did not match. Check null and string before
2671c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // calling the deferred code.
2672c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&cache_miss);
2673c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Null is not instance of anything.
2674c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ LoadRoot(temp, Heap::kNullValueRootIndex);
2675c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&false_result, eq, object, Operand(temp));
2676c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2677c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // String values is not instance of anything.
2678c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Condition cc = __ IsObjectStringType(object, temp, temp);
2679c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&false_result, cc, temp, Operand(zero_reg));
2680c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2681c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Go to the deferred code.
2682c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(deferred->entry());
2683c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2684c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&false_result);
2685c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ LoadRoot(result, Heap::kFalseValueRootIndex);
2686c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2687c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Here result has either true or false. Deferred code also produces true or
2688c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // false object.
2689c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(deferred->exit());
2690c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&done);
2691c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2692c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2693c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
26940ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
26950ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                               Label* map_check) {
2696c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
2697c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(result.is(v0));
2698c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  InstanceofStub::Flags flags = InstanceofStub::kNoFlags;
2700c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  flags = static_cast<InstanceofStub::Flags>(
2701c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      flags | InstanceofStub::kArgsInRegisters);
2702c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  flags = static_cast<InstanceofStub::Flags>(
2703c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      flags | InstanceofStub::kCallSiteInlineCheck);
2704c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  flags = static_cast<InstanceofStub::Flags>(
2705c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      flags | InstanceofStub::kReturnTrueFalseObject);
2706c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  InstanceofStub stub(flags);
2707c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2708c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2709c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2710c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Get the temp register reserved by the instruction. This needs to be t0 as
2711c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // its slot of the pushing of safepoint registers is used to communicate the
2712c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // offset to the location of the map check.
2713c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register temp = ToRegister(instr->temp());
2714c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(temp.is(t0));
271564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ LoadHeapObject(InstanceofStub::right(), instr->function());
2716c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  static const int kAdditionalDelta = 7;
2717c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta;
2718c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label before_push_delta;
2719c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&before_push_delta);
2720c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  {
2721c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
272288aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org    __ li(temp, Operand(delta * kPointerSize), CONSTANT_SIZE);
2723c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ StoreToSafepointRegisterSlot(temp, temp);
2724c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
27258432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCodeGeneric(stub.GetCode(isolate()),
2726c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                  RelocInfo::CODE_TARGET,
2727c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                  instr,
2728c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                  RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
2729e4bfb26083376408caf54512da4924003f090a61danno@chromium.org  LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
27300ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
2731c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Put the result value into the result register slot and
2732c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // restore all registers.
2733c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ StoreToSafepointRegisterSlot(result, result);
2734c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2735c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2736c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
27374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid LCodeGen::DoInstanceSize(LInstanceSize* instr) {
27384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Register object = ToRegister(instr->object());
27394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Register result = ToRegister(instr->result());
27404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ lw(result, FieldMemOperand(object, HeapObject::kMapOffset));
27414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ lbu(result, FieldMemOperand(result, Map::kInstanceSizeOffset));
27424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
27434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
27444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
2745c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCmpT(LCmpT* instr) {
2746c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Token::Value op = instr->op();
2747c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
27488432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
2749c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET, instr);
2750c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // On MIPS there is no need for a "no inlined smi code" marker (nop).
2751c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2752c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Condition condition = ComputeCompareCondition(op);
2753c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // A minor optimization that relies on LoadRoot always emitting one
2754c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // instruction.
2755c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm());
2756750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Label done, check;
2757c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(USE_DELAY_SLOT, &done, condition, v0, Operand(zero_reg));
2758750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  __ bind(&check);
2759c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
2760750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT_EQ(1, masm()->InstructionsGeneratedSince(&check));
2761c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2762c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&done);
2763c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2764c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2765c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2766c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoReturn(LReturn* instr) {
276759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (FLAG_trace && info()->IsOptimizing()) {
2768c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Push the return value on the stack as the parameter.
2769c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Runtime::TraceExit returns its parameter in v0.
2770c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ push(v0);
2771c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ CallRuntime(Runtime::kTraceExit, 1);
2772c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
2773e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (info()->saves_caller_doubles()) {
27747c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    ASSERT(NeedsEagerFrame());
27757c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    BitVector* doubles = chunk()->allocated_double_registers();
27767c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    BitVector::Iterator save_iterator(doubles);
27777c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    int count = 0;
27787c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    while (!save_iterator.Done()) {
27797c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
27807c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org              MemOperand(sp, count * kDoubleSize));
27817c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      save_iterator.Advance();
27827c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      count++;
27837c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    }
27847c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  }
27854e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  int no_frame_start = -1;
278659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (NeedsEagerFrame()) {
278759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    __ mov(sp, fp);
27884e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    no_frame_start = masm_->pc_offset();
2789b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    __ Pop(ra, fp);
2790ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
2791ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if (instr->has_constant_parameter_count()) {
2792ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    int parameter_count = ToInteger32(instr->constant_parameter_count());
2793ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    int32_t sp_delta = (parameter_count + 1) * kPointerSize;
2794ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if (sp_delta != 0) {
2795ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      __ Addu(sp, sp, Operand(sp_delta));
27967c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    }
2797ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  } else {
2798ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    Register reg = ToRegister(instr->parameter_count());
2799ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    // The argument count parameter is a smi
2800ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    __ SmiUntag(reg);
2801ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    __ sll(at, reg, kPointerSizeLog2);
2802ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    __ Addu(sp, sp, at);
280359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
2804ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
2805c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Jump(ra);
28064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
28074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (no_frame_start != -1) {
28084e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    info_->AddNoFrameRange(no_frame_start, masm_->pc_offset());
28094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
2810c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2811c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2812c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2813c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2814c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
2815c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(at, Operand(Handle<Object>(instr->hydrogen()->cell())));
2816f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org  __ lw(result, FieldMemOperand(at, Cell::kValueOffset));
2817c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->hydrogen()->RequiresHoleCheck()) {
2818c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2819c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(eq, instr->environment(), result, Operand(at));
2820c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
2821c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2822c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2823c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2824c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
2825c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->global_object()).is(a0));
2826c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
2827c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2828c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(a2, Operand(instr->name()));
2829c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET
2830c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                             : RelocInfo::CODE_TARGET_CONTEXT;
2831c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2832c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallCode(ic, mode, instr);
2833c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2834c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2835c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2836c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
2837e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org  Register value = ToRegister(instr->value());
2838e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org  Register cell = scratch0();
2839c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2840c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Load the cell.
2841e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org  __ li(cell, Operand(instr->hydrogen()->cell()));
2842c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2843c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // If the cell we are storing to contains the hole it could have
2844c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // been deleted from the property dictionary. In that case, we need
2845c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // to update the property details in the property dictionary to mark
2846c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // it as no longer deleted.
2847c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->hydrogen()->RequiresHoleCheck()) {
2848e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    // We use a temp to check the payload.
2849c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Register payload = ToRegister(instr->temp());
2850f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org    __ lw(payload, FieldMemOperand(cell, Cell::kValueOffset));
2851c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2852e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    DeoptimizeIf(eq, instr->environment(), payload, Operand(at));
2853c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
2854c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2855c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Store the value.
2856f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org  __ sw(value, FieldMemOperand(cell, Cell::kValueOffset));
285764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Cells are always rescanned, so no write barrier here.
2858c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2859c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2860c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2861c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) {
2862c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->global_object()).is(a1));
2863c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->value()).is(a0));
2864c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2865c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(a2, Operand(instr->name()));
28661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
2867c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ? isolate()->builtins()->StoreIC_Initialize_Strict()
2868c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      : isolate()->builtins()->StoreIC_Initialize();
2869c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
2870c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2871c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2872c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2873c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2874c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register context = ToRegister(instr->context());
2875c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
28767ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
2877c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(result, ContextOperand(context, instr->slot_index()));
287864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (instr->hydrogen()->RequiresHoleCheck()) {
287964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
28807ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
28817ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    if (instr->hydrogen()->DeoptimizesOnHole()) {
28827ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      DeoptimizeIf(eq, instr->environment(), result, Operand(at));
28837ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    } else {
28847ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      Label is_not_hole;
28857ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      __ Branch(&is_not_hole, ne, result, Operand(at));
28867ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
28877ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      __ bind(&is_not_hole);
28887ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    }
288964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
2890c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2891c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2892c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2893c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
2894c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register context = ToRegister(instr->context());
2895c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register value = ToRegister(instr->value());
28967ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org  Register scratch = scratch0();
2897c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  MemOperand target = ContextOperand(context, instr->slot_index());
28987ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
28997ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org  Label skip_assignment;
29007ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
290164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (instr->hydrogen()->RequiresHoleCheck()) {
290264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ lw(scratch, target);
290364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
29047ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
29057ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    if (instr->hydrogen()->DeoptimizesOnHole()) {
29067ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      DeoptimizeIf(eq, instr->environment(), scratch, Operand(at));
29077ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    } else {
29087ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      __ Branch(&skip_assignment, ne, scratch, Operand(at));
29097ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    }
291064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
29117ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
2912c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ sw(value, target);
2913c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->hydrogen()->NeedsWriteBarrier()) {
2914c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    SmiCheck check_needed =
29151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        instr->hydrogen()->value()->IsHeapObject()
29161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org            ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
2917c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ RecordWriteContextSlot(context,
2918c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                              target.offset(),
2919c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                              value,
2920c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                              scratch0(),
2921c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org                              GetRAState(),
2922c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                              kSaveFPRegs,
2923c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                              EMIT_REMEMBERED_SET,
2924c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                              check_needed);
2925c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
29267ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
29277ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org  __ bind(&skip_assignment);
2928c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2929c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2930c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2931c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
293253ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  HObjectAccess access = instr->hydrogen()->access();
293353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  int offset = access.offset();
2934c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register object = ToRegister(instr->object());
2935d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
2936d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (access.IsExternalMemory()) {
2937d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    Register result = ToRegister(instr->result());
2938d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    __ lw(result, MemOperand(object, offset));
2939d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return;
2940d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
2941d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
294257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  if (instr->hydrogen()->representation().IsDouble()) {
294357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    DoubleRegister result = ToDoubleRegister(instr->result());
294457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ ldc1(result, FieldMemOperand(object, offset));
294557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    return;
2946f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
294757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
294857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Register result = ToRegister(instr->result());
294953ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  if (access.IsInobject()) {
295057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ lw(result, FieldMemOperand(object, offset));
2951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
295257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
295357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ lw(result, FieldMemOperand(result, offset));
2954c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
2955c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2956c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2957c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2958c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
2959c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->object()).is(a0));
2960c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
2961c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2962c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Name is always in a2.
2963c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(a2, Operand(instr->name()));
2964c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2965c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET, instr);
2966c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
2967c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2968c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2969c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
2970c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
2971c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register function = ToRegister(instr->function());
2972c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
2973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2974c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Check that the function really is a function. Load map into the
2975c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // result register.
2976c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ GetObjectType(function, result, scratch);
2977c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_FUNCTION_TYPE));
2978c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2979c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Make sure that the function has an instance prototype.
2980c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label non_instance;
2981c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lbu(scratch, FieldMemOperand(result, Map::kBitFieldOffset));
2982c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ And(scratch, scratch, Operand(1 << Map::kHasNonInstancePrototype));
2983c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&non_instance, ne, scratch, Operand(zero_reg));
2984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2985c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Get the prototype or initial map from the function.
2986c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(result,
2987c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org         FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
2988c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2989c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Check that the function has a prototype or an initial map.
2990c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2991c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeoptimizeIf(eq, instr->environment(), result, Operand(at));
2992c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2993c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // If the function does not have an initial map, we're done.
2994c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label done;
2995c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ GetObjectType(result, scratch, scratch);
2996c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&done, ne, scratch, Operand(MAP_TYPE));
2997c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2998c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Get the prototype from the initial map.
2999c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(result, FieldMemOperand(result, Map::kPrototypeOffset));
3000c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&done);
3001c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3002c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Non-instance prototype: Fetch prototype from constructor field
3003c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // in initial map.
3004c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&non_instance);
3005c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(result, FieldMemOperand(result, Map::kConstructorOffset));
3006c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3007c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // All done.
3008c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&done);
3009c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3010c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3011c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3012c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadExternalArrayPointer(
3013c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LLoadExternalArrayPointer* instr) {
3014c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register to_reg = ToRegister(instr->result());
3015c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register from_reg  = ToRegister(instr->object());
3016c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(to_reg, FieldMemOperand(from_reg,
3017c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                ExternalArray::kExternalPointerOffset));
3018c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3019c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3020c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3021c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3022c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register arguments = ToRegister(instr->arguments());
3023c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
302432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (instr->length()->IsConstantOperand() &&
302532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      instr->index()->IsConstantOperand()) {
302632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
302732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
302832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    int index = (const_length - const_index) + 1;
302932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ lw(result, MemOperand(arguments, index * kPointerSize));
303032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  } else {
303132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    Register length = ToRegister(instr->length());
303232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    Register index = ToRegister(instr->index());
303332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    // There are two words between the frame pointer and the last argument.
303432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    // Subtracting from length accounts for one of them, add one more.
303532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ subu(length, length, index);
303632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ Addu(length, length, Operand(1));
303732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ sll(length, length, kPointerSizeLog2);
303832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ Addu(at, arguments, Operand(length));
303932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ lw(result, MemOperand(at, 0));
304032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  }
3041c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3042c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3043c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3044e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3045e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register external_pointer = ToRegister(instr->elements());
3046e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register key = no_reg;
3047e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ElementsKind elements_kind = instr->elements_kind();
3048e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  bool key_is_constant = instr->key()->IsConstantOperand();
3049e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  int constant_key = 0;
3050e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (key_is_constant) {
3051e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3052e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    if (constant_key & 0xF0000000) {
3053594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Abort(kArrayIndexConstantValueTooBig);
3054471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    }
3055e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else {
3056e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    key = ToRegister(instr->key());
3057129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  }
3058e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  int element_size_shift = ElementsKindToShiftSize(elements_kind);
305953ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
3060e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      ? (element_size_shift - kSmiTagSize) : element_size_shift;
3061e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  int additional_offset = instr->additional_index() << element_size_shift;
3062c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3063e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
3064e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3065e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    FPURegister result = ToDoubleRegister(instr->result());
3066e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    if (key_is_constant) {
3067e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      __ Addu(scratch0(), external_pointer, constant_key << element_size_shift);
30687028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    } else {
3069e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      __ sll(scratch0(), key, shift_size);
3070e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      __ Addu(scratch0(), scratch0(), external_pointer);
3071e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
3072e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3073e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ lwc1(result, MemOperand(scratch0(), additional_offset));
3074e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ cvt_d_s(result, result);
3075e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    } else  {  // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
3076e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ ldc1(result, MemOperand(scratch0(), additional_offset));
3077e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
3078e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else {
3079e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    Register result = ToRegister(instr->result());
3080e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    MemOperand mem_operand = PrepareKeyedOperand(
3081e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        key, external_pointer, key_is_constant, constant_key,
3082e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        element_size_shift, shift_size,
3083e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        instr->additional_index(), additional_offset);
3084e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    switch (elements_kind) {
3085e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case EXTERNAL_BYTE_ELEMENTS:
3086e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        __ lb(result, mem_operand);
3087e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        break;
3088e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case EXTERNAL_PIXEL_ELEMENTS:
3089e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3090e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        __ lbu(result, mem_operand);
3091e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        break;
3092e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case EXTERNAL_SHORT_ELEMENTS:
3093e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        __ lh(result, mem_operand);
3094e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        break;
3095e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3096e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        __ lhu(result, mem_operand);
3097e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        break;
3098e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case EXTERNAL_INT_ELEMENTS:
3099e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        __ lw(result, mem_operand);
3100e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        break;
3101e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3102e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        __ lw(result, mem_operand);
3103e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3104e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org          DeoptimizeIf(Ugreater_equal, instr->environment(),
3105e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org              result, Operand(0x80000000));
3106e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        }
3107e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        break;
3108e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case EXTERNAL_FLOAT_ELEMENTS:
3109e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case EXTERNAL_DOUBLE_ELEMENTS:
3110e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case FAST_DOUBLE_ELEMENTS:
3111e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case FAST_ELEMENTS:
3112e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case FAST_SMI_ELEMENTS:
3113e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case FAST_HOLEY_DOUBLE_ELEMENTS:
3114e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case FAST_HOLEY_ELEMENTS:
3115e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case FAST_HOLEY_SMI_ELEMENTS:
3116e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case DICTIONARY_ELEMENTS:
3117e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case NON_STRICT_ARGUMENTS_ELEMENTS:
3118e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        UNREACHABLE();
3119e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        break;
31207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    }
3121c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
3122c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3123c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3124c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3125e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
3126c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register elements = ToRegister(instr->elements());
3127c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool key_is_constant = instr->key()->IsConstantOperand();
3128c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register key = no_reg;
3129c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DoubleRegister result = ToDoubleRegister(instr->result());
3130c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
3131c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3132129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
313353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
3134129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org      ? (element_size_shift - kSmiTagSize) : element_size_shift;
3135c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int constant_key = 0;
3136c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (key_is_constant) {
3137c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3138c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (constant_key & 0xF0000000) {
3139594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Abort(kArrayIndexConstantValueTooBig);
3140c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
3141c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
3142c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    key = ToRegister(instr->key());
3143c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
3144c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
314559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
314659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      ((constant_key + instr->additional_index()) << element_size_shift);
314759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (!key_is_constant) {
3148c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ sll(scratch, key, shift_size);
314959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    __ Addu(elements, elements, scratch);
315059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
3151e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ Addu(elements, elements, Operand(base_offset));
3152e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ ldc1(result, MemOperand(elements));
3153e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (instr->hydrogen()->RequiresHoleCheck()) {
3154e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
3155e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32));
3156830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  }
3157c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3158c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3159c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3160e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3161e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register elements = ToRegister(instr->elements());
3162e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register result = ToRegister(instr->result());
3163e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register scratch = scratch0();
3164e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register store_base = scratch;
3165e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  int offset = 0;
3166e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
3167e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (instr->key()->IsConstantOperand()) {
3168e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3169e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
3170e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                                           instr->additional_index());
3171e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    store_base = elements;
3172e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else {
3173e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    Register key = EmitLoadRegister(instr->key(), scratch0());
3174e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // Even though the HLoadKeyed instruction forces the input
3175e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // representation for the key to be an integer, the input gets replaced
3176e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // during bound check elimination with the index argument to the bounds
3177e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // check, which can be tagged, so that case must be handled here, too.
317853ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org    if (instr->hydrogen()->key()->representation().IsSmi()) {
3179e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
3180e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      __ addu(scratch, elements, scratch);
3181e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    } else {
3182e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      __ sll(scratch, key, kPointerSizeLog2);
3183e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      __ addu(scratch, elements, scratch);
3184e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
3185e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    offset = FixedArray::OffsetOfElementAt(instr->additional_index());
3186e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
3187e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  __ lw(result, FieldMemOperand(store_base, offset));
3188e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
3189e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Check for the hole value.
3190e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (instr->hydrogen()->RequiresHoleCheck()) {
3191e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3192e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      __ And(scratch, result, Operand(kSmiTagMask));
3193e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
3194e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    } else {
3195e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
3196e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      DeoptimizeIf(eq, instr->environment(), result, Operand(scratch));
3197e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
3198e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
3199e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
3200e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
3201e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
3202e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3203e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (instr->is_external()) {
3204e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    DoLoadKeyedExternalArray(instr);
3205e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else if (instr->hydrogen()->representation().IsDouble()) {
3206e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    DoLoadKeyedFixedDoubleArray(instr);
3207e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else {
3208e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    DoLoadKeyedFixedArray(instr);
3209e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
3210e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
3211e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
3212e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
3213129d398d682e6ca3910808c913212ce532f1e155danno@chromium.orgMemOperand LCodeGen::PrepareKeyedOperand(Register key,
3214129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org                                         Register base,
3215129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org                                         bool key_is_constant,
3216129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org                                         int constant_key,
3217129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org                                         int element_size,
3218129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org                                         int shift_size,
3219129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org                                         int additional_index,
3220129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org                                         int additional_offset) {
3221129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  if (additional_index != 0 && !key_is_constant) {
3222129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    additional_index *= 1 << (element_size - shift_size);
3223129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    __ Addu(scratch0(), key, Operand(additional_index));
3224129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  }
3225129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
3226129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  if (key_is_constant) {
3227129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    return MemOperand(base,
3228129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org                      (constant_key << element_size) + additional_offset);
3229129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  }
3230129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
3231129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  if (additional_index == 0) {
3232129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    if (shift_size >= 0) {
3233129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org      __ sll(scratch0(), key, shift_size);
3234129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org      __ Addu(scratch0(), base, scratch0());
3235129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org      return MemOperand(scratch0());
3236129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    } else {
3237129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org      ASSERT_EQ(-1, shift_size);
3238129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org      __ srl(scratch0(), key, 1);
3239129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org      __ Addu(scratch0(), base, scratch0());
3240129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org      return MemOperand(scratch0());
3241129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    }
3242129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  }
3243129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
3244129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  if (shift_size >= 0) {
3245129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    __ sll(scratch0(), scratch0(), shift_size);
3246129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    __ Addu(scratch0(), base, scratch0());
3247129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    return MemOperand(scratch0());
3248129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  } else {
3249129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    ASSERT_EQ(-1, shift_size);
3250129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    __ srl(scratch0(), scratch0(), 1);
3251129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    __ Addu(scratch0(), base, scratch0());
3252129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    return MemOperand(scratch0());
3253129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  }
3254129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org}
3255129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
3256129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
3257c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3258c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->object()).is(a1));
3259c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->key()).is(a0));
3260c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3261c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
3262c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET, instr);
3263c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3264c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3265c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3266c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
3267c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
3268c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register temp = scratch1();
3269c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
3270c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
327128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  if (instr->hydrogen()->from_inlined()) {
327228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ Subu(result, sp, 2 * kPointerSize);
327328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  } else {
327428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    // Check if the calling frame is an arguments adaptor frame.
327528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    Label done, adapted;
327628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ lw(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
327728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ lw(result, MemOperand(scratch, StandardFrameConstants::kContextOffset));
327828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ Xor(temp, result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3279c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
328028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    // Result is the frame pointer for the frame if not adapted and for the real
328128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    // frame below the adaptor frame if adapted.
328228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ Movn(result, fp, temp);  // Move only if temp is not equal to zero (ne).
328328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    __ Movz(result, scratch, temp);  // Move only if temp is equal to zero (eq).
328428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  }
3285c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3286c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3287c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3288c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
3289c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register elem = ToRegister(instr->elements());
3290c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
3291c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3292c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label done;
3293c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3294c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // If no arguments adaptor frame the number of arguments is fixed.
3295c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Addu(result, zero_reg, Operand(scope()->num_parameters()));
3296c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&done, eq, fp, Operand(elem));
3297c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3298c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Arguments adaptor frame present. Get argument length from there.
3299c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(result, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3300c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(result,
3301c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        MemOperand(result, ArgumentsAdaptorFrameConstants::kLengthOffset));
3302c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ SmiUntag(result);
3303c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3304c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Argument length is in result register.
3305c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&done);
3306c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3307c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3308c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
33092c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.orgvoid LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3310c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register receiver = ToRegister(instr->receiver());
3311c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register function = ToRegister(instr->function());
3312c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
3313c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3314c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // If the receiver is null or undefined, we have to pass the global
3315c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // object as a receiver to normal functions. Values have to be
3316c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // passed unchanged to builtins and strict-mode functions.
3317c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label global_object, receiver_ok;
3318c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3319c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Do not transform the receiver to object for strict mode
3320c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // functions.
3321c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(scratch,
3322c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org         FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
3323c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(scratch,
3324c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org         FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset));
3325c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3326c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Do not transform the receiver to object for builtins.
3327c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int32_t strict_mode_function_mask =
3328c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                  1 <<  (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize);
3329c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int32_t native_mask = 1 << (SharedFunctionInfo::kNative + kSmiTagSize);
3330c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ And(scratch, scratch, Operand(strict_mode_function_mask | native_mask));
3331c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&receiver_ok, ne, scratch, Operand(zero_reg));
3332c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3333c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Normal function. Replace undefined or null with global receiver.
3334c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ LoadRoot(scratch, Heap::kNullValueRootIndex);
3335c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&global_object, eq, receiver, Operand(scratch));
3336c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
3337c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&global_object, eq, receiver, Operand(scratch));
3338c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3339c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Deoptimize if the receiver is not a JS object.
3340c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ And(scratch, receiver, Operand(kSmiTagMask));
3341c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg));
3342c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3343c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ GetObjectType(receiver, scratch, scratch);
3344c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeoptimizeIf(lt, instr->environment(),
3345c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org               scratch, Operand(FIRST_SPEC_OBJECT_TYPE));
3346c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&receiver_ok);
3347c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3348c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&global_object);
3349c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(receiver, GlobalObjectOperand());
3350c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(receiver,
3351c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org         FieldMemOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
3352c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&receiver_ok);
33532c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org}
33542c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
3355e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
33562c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.orgvoid LCodeGen::DoApplyArguments(LApplyArguments* instr) {
33572c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  Register receiver = ToRegister(instr->receiver());
33582c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  Register function = ToRegister(instr->function());
33592c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  Register length = ToRegister(instr->length());
33602c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  Register elements = ToRegister(instr->elements());
33612c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  Register scratch = scratch0();
33622c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  ASSERT(receiver.is(a0));  // Used for parameter count.
33632c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  ASSERT(function.is(a1));  // Required by InvokeFunction.
33642c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
3365c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3366c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Copy the arguments to this function possibly from the
3367c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // adaptor frame below it.
3368c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  const uint32_t kArgumentsLimit = 1 * KB;
3369c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeoptimizeIf(hi, instr->environment(), length, Operand(kArgumentsLimit));
3370c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3371c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Push the receiver and use the register to keep the original
3372c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // number of arguments.
3373c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ push(receiver);
3374c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Move(receiver, length);
3375c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // The arguments are at a one pointer size offset from elements.
3376c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Addu(elements, elements, Operand(1 * kPointerSize));
3377c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3378c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Loop through the arguments pushing them onto the execution
3379c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // stack.
3380c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label invoke, loop;
3381c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // length is a small non-negative integer, due to the test above.
3382c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(USE_DELAY_SLOT, &invoke, eq, length, Operand(zero_reg));
3383c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ sll(scratch, length, 2);
3384c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&loop);
3385c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Addu(scratch, elements, scratch);
3386c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(scratch, MemOperand(scratch));
3387c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ push(scratch);
3388c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Subu(length, length, Operand(1));
3389c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(USE_DELAY_SLOT, &loop, ne, length, Operand(zero_reg));
3390c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ sll(scratch, length, 2);
3391c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3392c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&invoke);
3393e4bfb26083376408caf54512da4924003f090a61danno@chromium.org  ASSERT(instr->HasPointerMap());
3394c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LPointerMap* pointers = instr->pointer_map();
3395c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  RecordPosition(pointers->position());
33960ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  SafepointGenerator safepoint_generator(
33970ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      this, pointers, Safepoint::kLazyDeopt);
3398c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // The number of arguments is stored in receiver which is a0, as expected
3399c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // by InvokeFunction.
340005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  ParameterCount actual(receiver);
3401c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ InvokeFunction(function, actual, CALL_FUNCTION,
3402c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                    safepoint_generator, CALL_AS_METHOD);
3403c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3404c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3405c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3406c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3407c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoPushArgument(LPushArgument* instr) {
3408c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* argument = instr->value();
3409c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) {
3410594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Abort(kDoPushArgumentNotImplementedForDoubleType);
3411c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
3412c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register argument_reg = EmitLoadRegister(argument, at);
3413c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ push(argument_reg);
3414c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
3415c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3416c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3417c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
341828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.orgvoid LCodeGen::DoDrop(LDrop* instr) {
341928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  __ Drop(instr->count());
342028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org}
342128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
342228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
3423c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoThisFunction(LThisFunction* instr) {
3424c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
34255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  __ lw(result, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
3426c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3427c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3428c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3429c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoContext(LContext* instr) {
34307c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  // If there is a non-return use, the context must be moved to a register.
3431c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
34327c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  for (HUseIterator it(instr->hydrogen()->uses()); !it.Done(); it.Advance()) {
34337c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    if (!it.value()->IsReturn()) {
34347c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ mov(result, cp);
34357c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      return;
34367c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    }
34377c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  }
3438c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3439c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3440c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3441c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoOuterContext(LOuterContext* instr) {
3442c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register context = ToRegister(instr->context());
3443c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
3444c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(result,
3445c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        MemOperand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
3446c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3447c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3448c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3449f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgvoid LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3450f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  __ LoadHeapObject(scratch0(), instr->hydrogen()->pairs());
3451f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  __ li(scratch1(), Operand(Smi::FromInt(instr->hydrogen()->flags())));
3452f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // The context is the first argument.
3453f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  __ Push(cp, scratch0(), scratch1());
3454f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3455f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
3456f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
3457f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
3458c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3459c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
346046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  __ lw(result, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
3461c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3462c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3463c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3464c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
3465c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register global = ToRegister(instr->global_object());
3466c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
3467c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset));
3468c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3469c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3471c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::CallKnownFunction(Handle<JSFunction> function,
347232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                                 int formal_parameter_count,
3473c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 int arity,
3474c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 LInstruction* instr,
3475fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                                 CallKind call_kind,
3476fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                                 A1State a1_state) {
347732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  bool dont_adapt_arguments =
347832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
347932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  bool can_invoke_directly =
348032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      dont_adapt_arguments || formal_parameter_count == arity;
3481c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3482c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LPointerMap* pointers = instr->pointer_map();
3483c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  RecordPosition(pointers->position());
3484c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
348505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  if (can_invoke_directly) {
3486fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    if (a1_state == A1_UNINITIALIZED) {
3487fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org      __ LoadHeapObject(a1, function);
3488fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    }
3489fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org
3490b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    // Change context.
3491b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
3492c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
349305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    // Set r0 to arguments count if adaption is not needed. Assumes that r0
349405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    // is available to write to at this point.
349532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    if (dont_adapt_arguments) {
349605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org      __ li(a0, Operand(arity));
349705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    }
349805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
349905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    // Invoke function.
350005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    __ SetCallKind(t1, call_kind);
350105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
350205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    __ Call(at);
350305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
350405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    // Set up deoptimization.
350505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
350605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  } else {
350705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
350805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    ParameterCount count(arity);
350932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    ParameterCount expected(formal_parameter_count);
351032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ InvokeFunction(
351132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org        function, expected, count, CALL_FUNCTION, generator, call_kind);
351205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
3513c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3514c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Restore context.
3515c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3516c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3517c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3518c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3519c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
3520c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
3521c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ mov(a0, v0);
352232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  CallKnownFunction(instr->hydrogen()->function(),
352332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                    instr->hydrogen()->formal_parameter_count(),
3524fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    instr->arity(),
3525fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    instr,
3526fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    CALL_AS_METHOD,
3527fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    A1_UNINITIALIZED);
3528c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3529c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3530c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3531e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3532c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input = ToRegister(instr->value());
3533c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
3534c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
3535c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3536c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Deoptimize if not a heap number.
3537c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
3538c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
3539c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeoptimizeIf(ne, instr->environment(), scratch, Operand(at));
3540c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3541c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label done;
3542c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register exponent = scratch0();
3543c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  scratch = no_reg;
3544c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
3545c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Check the sign of the argument. If the argument is positive, just
3546c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // return it.
3547c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Move(result, input);
3548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ And(at, exponent, Operand(HeapNumber::kSignMask));
3549c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&done, eq, at, Operand(zero_reg));
3550c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3551c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Input is negative. Reverse its sign.
3552c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Preserve the value of all registers.
3553c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  {
3554c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
3555c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3556c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Registers were saved at the safepoint, so we can use
3557c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // many scratch registers.
3558c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register tmp1 = input.is(a1) ? a0 : a1;
3559c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register tmp2 = input.is(a2) ? a0 : a2;
3560c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register tmp3 = input.is(a3) ? a0 : a3;
3561c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register tmp4 = input.is(t0) ? a0 : t0;
3562c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3563c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // exponent: floating point exponent value.
3564c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3565c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Label allocated, slow;
3566c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ LoadRoot(tmp4, Heap::kHeapNumberMapRootIndex);
3567c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ AllocateHeapNumber(tmp1, tmp2, tmp3, tmp4, &slow);
3568c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(&allocated);
3569c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3570c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Slow case: Call the runtime system to do the number allocation.
3571c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ bind(&slow);
3572c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3573c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
3574c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Set the pointer to the new heap number in tmp.
3575c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (!tmp1.is(v0))
3576c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ mov(tmp1, v0);
3577c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Restore input_reg after call to runtime.
3578c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ LoadFromSafepointRegisterSlot(input, input);
3579c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ lw(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
3580c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3581c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ bind(&allocated);
3582c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // exponent: floating point exponent value.
3583c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // tmp1: allocated heap number.
3584c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ And(exponent, exponent, Operand(~HeapNumber::kSignMask));
3585c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ sw(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset));
3586c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ lw(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset));
3587c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ sw(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
3588c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3589c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ StoreToSafepointRegisterSlot(tmp1, result);
3590c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
3591c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3592c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&done);
3593c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3594c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3595c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3596e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3597c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input = ToRegister(instr->value());
3598c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
3599c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
3600c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label done;
3601c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg));
3602c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ mov(result, input);
36031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  __ subu(result, zero_reg, input);
36042efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Overflow if result is still negative, i.e. 0x80000000.
3605c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg));
3606c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&done);
3607c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3608c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3609c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3610e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathAbs(LMathAbs* instr) {
3611c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Class for deferred case.
3612c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3613c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   public:
3614e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3615c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
3616c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual void Generate() {
3617c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3618c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
3619c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual LInstruction* instr() { return instr_; }
3620c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   private:
3621e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    LMathAbs* instr_;
3622c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  };
3623c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3624c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Representation r = instr->hydrogen()->value()->representation();
3625c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (r.IsDouble()) {
3626c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    FPURegister input = ToDoubleRegister(instr->value());
3627c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    FPURegister result = ToDoubleRegister(instr->result());
3628c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ abs_d(result, input);
3629594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else if (r.IsSmiOrInteger32()) {
3630c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    EmitIntegerMathAbs(instr);
3631c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
3632c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Representation is tagged.
3633c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeferredMathAbsTaggedHeapNumber* deferred =
36347028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3635c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Register input = ToRegister(instr->value());
3636c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Smi check.
3637c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ JumpIfNotSmi(input, deferred->entry());
3638c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // If smi, handle it directly.
3639c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    EmitIntegerMathAbs(instr);
3640c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ bind(deferred->exit());
3641c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
3642c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3643c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3644c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3645e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathFloor(LMathFloor* instr) {
3646c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  DoubleRegister input = ToDoubleRegister(instr->value());
3647c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
3648c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch1 = scratch0();
3649c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register except_flag = ToRegister(instr->temp());
3650c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3651c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ EmitFPUTruncate(kRoundToMinusInf,
365283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                     result,
3653c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                     input,
3654c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                     scratch1,
365583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                     double_scratch0(),
3656c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                     except_flag);
3657c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3658c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Deopt if the operation did not succeed.
3659c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
3660c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3661c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3662c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Test for -0.
3663c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Label done;
3664c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(&done, ne, result, Operand(zero_reg));
3665c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ mfc1(scratch1, input.high());
3666c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
3667c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
3668c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ bind(&done);
3669c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
3670c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3671c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3672c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3673e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathRound(LMathRound* instr) {
3674c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  DoubleRegister input = ToDoubleRegister(instr->value());
3675c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
367683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp());
3677c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
3678c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label done, check_sign_on_zero;
3679c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3680c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Extract exponent bits.
3681c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ mfc1(result, input.high());
3682c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Ext(scratch,
3683c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org         result,
3684c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org         HeapNumber::kExponentShift,
3685c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org         HeapNumber::kExponentBits);
3686c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3687c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // If the number is in ]-0.5, +0.5[, the result is +/- 0.
3688c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label skip1;
3689c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&skip1, gt, scratch, Operand(HeapNumber::kExponentBias - 2));
3690c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ mov(result, zero_reg);
3691c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3692c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(&check_sign_on_zero);
3693c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
3694c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(&done);
3695c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
3696c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&skip1);
3697c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3698c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // The following conversion will not work with numbers
3699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // outside of ]-2^32, 2^32[.
3700c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeoptimizeIf(ge, instr->environment(), scratch,
3701c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org               Operand(HeapNumber::kExponentBias + 32));
3702c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3703c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Save the original sign for later comparison.
3704c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ And(scratch, result, Operand(HeapNumber::kSignMask));
3705c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3706c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Move(double_scratch0(), 0.5);
370764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ add_d(double_scratch0(), input, double_scratch0());
3708c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3709c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Check sign of the result: if the sign changed, the input
3710c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // value was in ]0.5, 0[ and the result should be -0.
371164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ mfc1(result, double_scratch0().high());
3712c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Xor(result, result, Operand(scratch));
3713c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3714c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // ARM uses 'mi' here, which is 'lt'
3715c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(lt, instr->environment(), result,
3716c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                 Operand(zero_reg));
3717c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
3718c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Label skip2;
3719c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // ARM uses 'mi' here, which is 'lt'
3720c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Negating it results in 'ge'
3721c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(&skip2, ge, result, Operand(zero_reg));
3722c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ mov(result, zero_reg);
3723c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(&done);
3724c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ bind(&skip2);
3725c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
3726c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3727c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register except_flag = scratch;
3728c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ EmitFPUTruncate(kRoundToMinusInf,
3729c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                     result,
373083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                     double_scratch0(),
373183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                     at,
373283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                     double_scratch1,
3733c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                     except_flag);
3734c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3735c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
3736c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3737c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3738c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Test for -0.
3739c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(&done, ne, result, Operand(zero_reg));
3740c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ bind(&check_sign_on_zero);
3741c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ mfc1(scratch, input.high());
3742c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ And(scratch, scratch, Operand(HeapNumber::kSignMask));
3743c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
3744c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
3745c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&done);
3746c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3747c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3748c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3749e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3750c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  DoubleRegister input = ToDoubleRegister(instr->value());
3751c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DoubleRegister result = ToDoubleRegister(instr->result());
3752c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ sqrt_d(result, input);
3753c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3754c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3755c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3756e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3757c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  DoubleRegister input = ToDoubleRegister(instr->value());
3758c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DoubleRegister result = ToDoubleRegister(instr->result());
3759c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  DoubleRegister temp = ToDoubleRegister(instr->temp());
376064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
376164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  ASSERT(!input.is(result));
376264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
376364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Note that according to ECMA-262 15.8.2.13:
376464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Math.pow(-Infinity, 0.5) == Infinity
376564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Math.sqrt(-Infinity) == NaN
376664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Label done;
376764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Move(temp, -V8_INFINITY);
376864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, temp, input);
376964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Set up Infinity in the delay slot.
377064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // result is overwritten if the branch is not taken.
377164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ neg_d(result, temp);
3772c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3773c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Add +0 to convert -0 to +0.
377464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ add_d(result, input, kDoubleRegZero);
3775c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ sqrt_d(result, result);
377664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&done);
3777c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3778c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3779c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3780c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoPower(LPower* instr) {
3781c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Representation exponent_type = instr->hydrogen()->right()->representation();
378264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Having marked this as a call, we can use any registers.
378364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Just make sure that the input/output registers are the expected ones.
3784c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  ASSERT(!instr->right()->IsDoubleRegister() ||
3785c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org         ToDoubleRegister(instr->right()).is(f4));
3786c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  ASSERT(!instr->right()->IsRegister() ||
3787c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org         ToRegister(instr->right()).is(a2));
3788c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  ASSERT(ToDoubleRegister(instr->left()).is(f2));
378964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  ASSERT(ToDoubleRegister(instr->result()).is(f0));
379064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
379153ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  if (exponent_type.IsSmi()) {
379253ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org    MathPowStub stub(MathPowStub::TAGGED);
379353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org    __ CallStub(&stub);
379453ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  } else if (exponent_type.IsTagged()) {
379564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    Label no_deopt;
379664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ JumpIfSmi(a2, &no_deopt);
379764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ lw(t3, FieldMemOperand(a2, HeapObject::kMapOffset));
379864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    DeoptimizeIf(ne, instr->environment(), t3, Operand(at));
379964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ bind(&no_deopt);
380064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    MathPowStub stub(MathPowStub::TAGGED);
380164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ CallStub(&stub);
3802c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else if (exponent_type.IsInteger32()) {
380364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    MathPowStub stub(MathPowStub::INTEGER);
380464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ CallStub(&stub);
3805c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
380664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    ASSERT(exponent_type.IsDouble());
380764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    MathPowStub stub(MathPowStub::DOUBLE);
380864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ CallStub(&stub);
3809c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
3810c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3811c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3812c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3813f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid LCodeGen::DoRandom(LRandom* instr) {
3814bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  class DeferredDoRandom: public LDeferredCode {
3815bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com   public:
3816bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
3817bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        : LDeferredCode(codegen), instr_(instr) { }
3818bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    virtual void Generate() { codegen()->DoDeferredRandom(instr_); }
3819bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    virtual LInstruction* instr() { return instr_; }
3820bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com   private:
3821bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    LRandom* instr_;
3822bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  };
3823bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
38247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
3825f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Having marked this instruction as a call we can use any
3826f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // registers.
3827f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  ASSERT(ToDoubleRegister(instr->result()).is(f0));
3828c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  ASSERT(ToRegister(instr->global_object()).is(a0));
3829f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
3830bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  static const int kSeedSize = sizeof(uint32_t);
3831bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  STATIC_ASSERT(kPointerSize == kSeedSize);
3832bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
383346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  __ lw(a0, FieldMemOperand(a0, GlobalObject::kNativeContextOffset));
3834bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  static const int kRandomSeedOffset =
3835bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
3836bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ lw(a2, FieldMemOperand(a0, kRandomSeedOffset));
383746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // a2: FixedArray of the native context's random seeds
3838bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
3839bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Load state[0].
3840bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ lw(a1, FieldMemOperand(a2, ByteArray::kHeaderSize));
3841bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ Branch(deferred->entry(), eq, a1, Operand(zero_reg));
3842bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Load state[1].
3843bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ lw(a0, FieldMemOperand(a2, ByteArray::kHeaderSize + kSeedSize));
3844bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // a1: state[0].
3845bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // a0: state[1].
3846bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
3847bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16)
3848bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ And(a3, a1, Operand(0xFFFF));
3849bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ li(t0, Operand(18273));
3850212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  __ Mul(a3, a3, t0);
3851bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ srl(a1, a1, 16);
3852bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ Addu(a1, a3, a1);
3853bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Save state[0].
3854bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ sw(a1, FieldMemOperand(a2, ByteArray::kHeaderSize));
3855bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
3856bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16)
3857bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ And(a3, a0, Operand(0xFFFF));
3858bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ li(t0, Operand(36969));
3859212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  __ Mul(a3, a3, t0);
3860bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ srl(a0, a0, 16),
3861bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ Addu(a0, a3, a0);
3862bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Save state[1].
3863bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ sw(a0, FieldMemOperand(a2, ByteArray::kHeaderSize + kSeedSize));
3864bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
3865bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF)
3866bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ And(a0, a0, Operand(0x3FFFF));
3867bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ sll(a1, a1, 14);
3868bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ Addu(v0, a0, a1);
3869bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
3870bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ bind(deferred->exit());
3871f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
3872f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // 0x41300000 is the top half of 1.0 x 2^20 as a double.
3873f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  __ li(a2, Operand(0x41300000));
3874f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Move 0x41300000xxxxxxxx (x = random bits in v0) to FPU.
3875f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  __ Move(f12, v0, a2);
3876f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Move 0x4130000000000000 to FPU.
3877f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  __ Move(f14, zero_reg, a2);
3878f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Subtract to get the result.
3879f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  __ sub_d(f0, f12, f14);
3880f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
3881f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
3882e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
3883bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.comvoid LCodeGen::DoDeferredRandom(LRandom* instr) {
3884bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ PrepareCallCFunction(1, scratch0());
3885bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
3886bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Return value is in v0.
3887bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com}
3888bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
3889f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
389083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgvoid LCodeGen::DoMathExp(LMathExp* instr) {
389183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  DoubleRegister input = ToDoubleRegister(instr->value());
389283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  DoubleRegister result = ToDoubleRegister(instr->result());
389383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp());
389483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  DoubleRegister double_scratch2 = double_scratch0();
389583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  Register temp1 = ToRegister(instr->temp1());
389683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  Register temp2 = ToRegister(instr->temp2());
389783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
389883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  MathExpGenerator::EmitMathExp(
389983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      masm(), input, result, double_scratch1, double_scratch2,
390083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      temp1, temp2, scratch0());
390183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org}
390283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
390383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
3904e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathLog(LMathLog* instr) {
3905c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToDoubleRegister(instr->result()).is(f4));
3906c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  TranscendentalCacheStub stub(TranscendentalCache::LOG,
3907c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                               TranscendentalCacheStub::UNTAGGED);
39088432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3909c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3910c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3911c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3912e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathTan(LMathTan* instr) {
3913ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  ASSERT(ToDoubleRegister(instr->result()).is(f4));
3914ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  TranscendentalCacheStub stub(TranscendentalCache::TAN,
3915ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org                               TranscendentalCacheStub::UNTAGGED);
39168432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3917ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org}
3918ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org
3919ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org
3920e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathCos(LMathCos* instr) {
3921c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToDoubleRegister(instr->result()).is(f4));
3922c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  TranscendentalCacheStub stub(TranscendentalCache::COS,
3923c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                               TranscendentalCacheStub::UNTAGGED);
39248432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3925c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3926c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3927c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3928e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid LCodeGen::DoMathSin(LMathSin* instr) {
3929c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToDoubleRegister(instr->result()).is(f4));
3930c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  TranscendentalCacheStub stub(TranscendentalCache::SIN,
3931c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                               TranscendentalCacheStub::UNTAGGED);
39328432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3933c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3934c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3935c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3936c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3937c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->function()).is(a1));
3938c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(instr->HasPointerMap());
3939fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org
394032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  Handle<JSFunction> known_function = instr->hydrogen()->known_function();
394132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (known_function.is_null()) {
3942fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    LPointerMap* pointers = instr->pointer_map();
3943fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    RecordPosition(pointers->position());
3944fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
3945fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    ParameterCount count(instr->arity());
3946fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
3947fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3948fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org  } else {
394932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    CallKnownFunction(known_function,
395032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                      instr->hydrogen()->formal_parameter_count(),
3951fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                      instr->arity(),
3952fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                      instr,
3953fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                      CALL_AS_METHOD,
3954fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                      A1_CONTAINS_TARGET);
3955fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org  }
3956c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3957c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3958c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3959c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallKeyed(LCallKeyed* instr) {
3960c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
3961c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3962c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int arity = instr->arity();
3963c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<Code> ic =
3964c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      isolate()->stub_cache()->ComputeKeyedCallInitialize(arity);
3965c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET, instr);
3966c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3967c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3968c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3969c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3970c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallNamed(LCallNamed* instr) {
3971c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
3972c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int arity = instr->arity();
3974c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
3975c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<Code> ic =
3976c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
3977c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(a2, Operand(instr->name()));
3978c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallCode(ic, mode, instr);
3979c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Restore context register.
3980c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3981c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3982c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3983c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallFunction(LCallFunction* instr) {
3985c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  ASSERT(ToRegister(instr->function()).is(a1));
3986c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
3987c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3988c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int arity = instr->arity();
3989c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS);
39908432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3991c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3992c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
3993c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3994c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3995c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallGlobal(LCallGlobal* instr) {
3996c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
3997c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
3998c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int arity = instr->arity();
3999c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
4000c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<Code> ic =
4001c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
4002c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(a2, Operand(instr->name()));
4003c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallCode(ic, mode, instr);
4004c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4005c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4006c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4007c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4008c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
4009c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
401032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  CallKnownFunction(instr->hydrogen()->target(),
401132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                    instr->hydrogen()->formal_parameter_count(),
4012fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    instr->arity(),
4013fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    instr,
4014fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    CALL_AS_FUNCTION,
4015fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                    A1_UNINITIALIZED);
4016c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4017c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4018c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4019c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallNew(LCallNew* instr) {
4020c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  ASSERT(ToRegister(instr->constructor()).is(a1));
4021c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
4022c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4023c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(a0, Operand(instr->arity()));
40241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // No cell in a2 for construct type feedback in optimized code
40251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<Object> undefined_value(isolate()->factory()->undefined_value());
40261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  __ li(a2, Operand(undefined_value));
4027750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
40288432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4029c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4030c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4031c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4032750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid LCodeGen::DoCallNewArray(LCallNewArray* instr) {
4033750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(ToRegister(instr->constructor()).is(a1));
4034750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
4035750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
4036750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  __ li(a0, Operand(instr->arity()));
4037750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  __ li(a2, Operand(instr->hydrogen()->property_cell()));
403857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  ElementsKind kind = instr->hydrogen()->elements_kind();
403907237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com  AllocationSiteOverrideMode override_mode =
4040bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
404107237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com          ? DISABLE_ALLOCATION_SITES
404207237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com          : DONT_OVERRIDE;
404307237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com  ContextCheckMode context_mode = CONTEXT_CHECK_NOT_REQUIRED;
4044d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
4045ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if (instr->arity() == 0) {
404607237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com    ArrayNoArgumentConstructorStub stub(kind, context_mode, override_mode);
4047ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4048ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  } else if (instr->arity() == 1) {
4049f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org    Label done;
4050f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org    if (IsFastPackedElementsKind(kind)) {
4051f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org      Label packed_case;
4052f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org      // We might need a change here,
4053f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org      // look at the first argument.
4054f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org      __ lw(t1, MemOperand(sp, 0));
4055f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org      __ Branch(&packed_case, eq, t1, Operand(zero_reg));
4056f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org
4057f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org      ElementsKind holey_kind = GetHoleyElementsKind(kind);
405807237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com      ArraySingleArgumentConstructorStub stub(holey_kind, context_mode,
405907237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com                                              override_mode);
4060f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org      CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4061f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org      __ jmp(&done);
4062f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org      __ bind(&packed_case);
4063f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org    }
4064f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org
406507237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com    ArraySingleArgumentConstructorStub stub(kind, context_mode, override_mode);
4066ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4067f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org    __ bind(&done);
4068ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  } else {
406907237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com    ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode);
4070ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4071ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
4072750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
4073750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
4074750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
4075c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCallRuntime(LCallRuntime* instr) {
4076c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallRuntime(instr->function(), instr->arity(), instr);
4077c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4078c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4079c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
40804c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.orgvoid LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
40814c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  Register result = ToRegister(instr->result());
40824c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  Register base = ToRegister(instr->base_object());
40834c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  __ Addu(result, base, Operand(instr->offset()));
40844c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org}
40854c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org
40864c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org
4087c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
4088f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  Representation representation = instr->representation();
4089f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
4090c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register object = ToRegister(instr->object());
4091c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
409253ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  HObjectAccess access = instr->hydrogen()->access();
409353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  int offset = access.offset();
4094c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4095d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (access.IsExternalMemory()) {
4096d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    Register value = ToRegister(instr->value());
4097d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    __ sw(value, MemOperand(object, offset));
4098d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return;
4099d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
4100d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
410157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Handle<Map> transition = instr->transition();
410257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
4103a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
4104906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    Register value = ToRegister(instr->value());
4105906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    if (!instr->hydrogen()->value()->type().IsHeapObject()) {
4106906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      __ And(scratch, value, Operand(kSmiTagMask));
4107906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg));
4108906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    }
410957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  } else if (FLAG_track_double_fields && representation.IsDouble()) {
411057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    ASSERT(transition.is_null());
411153ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org    ASSERT(access.IsInobject());
411257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
411357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    DoubleRegister value = ToDoubleRegister(instr->value());
411457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ sdc1(value, FieldMemOperand(object, offset));
411557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    return;
4116f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
4117f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
4118f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (!transition.is_null()) {
4119f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    __ li(scratch, Operand(transition));
4120c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
412137141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org    if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
4122c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org      Register temp = ToRegister(instr->temp());
412337141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org      // Update the write barrier for the map field.
412437141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org      __ RecordWriteField(object,
412537141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org                          HeapObject::kMapOffset,
412637141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org                          scratch,
412737141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org                          temp,
4128c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org                          GetRAState(),
412937141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org                          kSaveFPRegs,
413037141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org                          OMIT_REMEMBERED_SET,
413137141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org                          OMIT_SMI_CHECK);
413237141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org    }
4133c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
4134c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4135c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Do the store.
413657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Register value = ToRegister(instr->value());
413757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  ASSERT(!object.is(value));
4138c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  SmiCheck check_needed =
41391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      instr->hydrogen()->value()->IsHeapObject()
41401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
414153ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  if (access.IsInobject()) {
4142c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ sw(value, FieldMemOperand(object, offset));
4143c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (instr->hydrogen()->NeedsWriteBarrier()) {
4144c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // Update the write barrier for the object for in-object properties.
4145c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ RecordWriteField(object,
4146c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                          offset,
4147c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                          value,
4148c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                          scratch,
4149c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org                          GetRAState(),
4150c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                          kSaveFPRegs,
4151c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                          EMIT_REMEMBERED_SET,
4152c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                          check_needed);
4153c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
4154c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
4155c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ lw(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset));
4156c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ sw(value, FieldMemOperand(scratch, offset));
4157c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (instr->hydrogen()->NeedsWriteBarrier()) {
4158c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // Update the write barrier for the properties array.
4159c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // object is used as a scratch register.
4160c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ RecordWriteField(scratch,
4161c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                          offset,
4162c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                          value,
4163c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                          object,
4164c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org                          GetRAState(),
4165c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                          kSaveFPRegs,
4166c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                          EMIT_REMEMBERED_SET,
4167c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                          check_needed);
4168c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
4169c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
4170c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4171c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4172c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4173c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4174c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->object()).is(a1));
4175c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->value()).is(a0));
4176c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4177c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Name is always in a2.
4178c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(a2, Operand(instr->name()));
41791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4180c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ? isolate()->builtins()->StoreIC_Initialize_Strict()
4181c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      : isolate()->builtins()->StoreIC_Initialize();
4182c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET, instr);
4183c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4184c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4185c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4186c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.comvoid LCodeGen::ApplyCheckIf(Condition condition,
4187fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                            LBoundsCheck* check,
4188fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                            Register src1,
4189fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                            const Operand& src2) {
4190fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (FLAG_debug_code && check->hydrogen()->skip_check()) {
4191fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    Label done;
4192c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    __ Branch(&done, NegateCondition(condition), src1, src2);
4193fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    __ stop("eliminated bounds check failed");
4194fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    __ bind(&done);
4195fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  } else {
4196c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    DeoptimizeIf(condition, check->environment(), src1, src2);
4197fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
4198fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org}
4199fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
4200fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
4201c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
42027c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  if (instr->hydrogen()->skip_check()) return;
42037c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
4204fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  Condition condition = instr->hydrogen()->allow_equality() ? hi : hs;
4205471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  if (instr->index()->IsConstantOperand()) {
4206471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    int constant_index =
4207471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        ToInteger32(LConstantOperand::cast(instr->index()));
420853ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org    if (instr->hydrogen()->length()->representation().IsSmi()) {
4209471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ li(at, Operand(Smi::FromInt(constant_index)));
4210471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    } else {
4211471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      __ li(at, Operand(constant_index));
4212471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    }
4213fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    ApplyCheckIf(condition,
4214fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                 instr,
4215471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                 at,
4216471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                 Operand(ToRegister(instr->length())));
4217471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  } else {
4218fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    ApplyCheckIf(condition,
4219fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                 instr,
4220471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                 ToRegister(instr->index()),
4221471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                 Operand(ToRegister(instr->length())));
4222471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  }
4223c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4224c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4225c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4226e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4227e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register external_pointer = ToRegister(instr->elements());
4228c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register key = no_reg;
4229c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ElementsKind elements_kind = instr->elements_kind();
4230c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool key_is_constant = instr->key()->IsConstantOperand();
4231c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int constant_key = 0;
4232c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (key_is_constant) {
4233c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
4234c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (constant_key & 0xF0000000) {
4235594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Abort(kArrayIndexConstantValueTooBig);
4236c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
4237c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
4238c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    key = ToRegister(instr->key());
4239c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
4240129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  int element_size_shift = ElementsKindToShiftSize(elements_kind);
424153ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
4242129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org      ? (element_size_shift - kSmiTagSize) : element_size_shift;
4243129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  int additional_offset = instr->additional_index() << element_size_shift;
4244c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4245c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
4246c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
4247c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    FPURegister value(ToDoubleRegister(instr->value()));
4248c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (key_is_constant) {
4249129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org      __ Addu(scratch0(), external_pointer, constant_key <<
4250129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org          element_size_shift);
4251c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
4252c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ sll(scratch0(), key, shift_size);
4253c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ Addu(scratch0(), scratch0(), external_pointer);
4254c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
4255c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4256c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
4257c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ cvt_s_d(double_scratch0(), value);
4258777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org      __ swc1(double_scratch0(), MemOperand(scratch0(), additional_offset));
4259c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {  // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
4260777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org      __ sdc1(value, MemOperand(scratch0(), additional_offset));
4261c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
4262c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
4263c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register value(ToRegister(instr->value()));
4264129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    MemOperand mem_operand = PrepareKeyedOperand(
4265129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org        key, external_pointer, key_is_constant, constant_key,
4266129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org        element_size_shift, shift_size,
4267129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org        instr->additional_index(), additional_offset);
4268c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    switch (elements_kind) {
4269c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case EXTERNAL_PIXEL_ELEMENTS:
4270c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case EXTERNAL_BYTE_ELEMENTS:
4271c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
4272c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ sb(value, mem_operand);
4273c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
4274c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case EXTERNAL_SHORT_ELEMENTS:
4275c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
4276c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ sh(value, mem_operand);
4277c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
4278c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case EXTERNAL_INT_ELEMENTS:
4279c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case EXTERNAL_UNSIGNED_INT_ELEMENTS:
4280c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        __ sw(value, mem_operand);
4281c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
4282c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case EXTERNAL_FLOAT_ELEMENTS:
4283c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case EXTERNAL_DOUBLE_ELEMENTS:
4284c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case FAST_DOUBLE_ELEMENTS:
4285c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case FAST_ELEMENTS:
4286830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_SMI_ELEMENTS:
4287830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_HOLEY_DOUBLE_ELEMENTS:
4288830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_HOLEY_ELEMENTS:
4289830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_HOLEY_SMI_ELEMENTS:
4290c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case DICTIONARY_ELEMENTS:
4291c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      case NON_STRICT_ARGUMENTS_ELEMENTS:
4292c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        UNREACHABLE();
4293c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        break;
4294c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
4295c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
4296c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4297c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4298e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4299e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4300e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  DoubleRegister value = ToDoubleRegister(instr->value());
4301e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register elements = ToRegister(instr->elements());
4302e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register key = no_reg;
4303e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register scratch = scratch0();
4304e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  bool key_is_constant = instr->key()->IsConstantOperand();
4305e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  int constant_key = 0;
4306e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Label not_nan;
4307e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4308e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Calculate the effective address of the slot in the array to store the
4309e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // double value.
4310e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (key_is_constant) {
4311e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
4312e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    if (constant_key & 0xF0000000) {
4313594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Abort(kArrayIndexConstantValueTooBig);
4314e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
4315e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else {
4316e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    key = ToRegister(instr->key());
4317e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4318e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
431953ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
4320e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      ? (element_size_shift - kSmiTagSize) : element_size_shift;
4321e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (key_is_constant) {
4322e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    __ Addu(scratch, elements, Operand((constant_key << element_size_shift) +
4323e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org            FixedDoubleArray::kHeaderSize - kHeapObjectTag));
4324e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else {
4325e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    __ sll(scratch, key, shift_size);
4326e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    __ Addu(scratch, elements, Operand(scratch));
4327e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    __ Addu(scratch, scratch,
4328e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org            Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
4329e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4330e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4331e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (instr->NeedsCanonicalization()) {
4332e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    Label is_nan;
4333e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // Check for NaN. All NaNs must be canonicalized.
4334e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    __ BranchF(NULL, &is_nan, eq, value, value);
4335e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    __ Branch(&not_nan);
4336e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4337e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // Only load canonical NaN if the comparison above set the overflow.
4338e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    __ bind(&is_nan);
4339e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double());
4340e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4341e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4342e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  __ bind(&not_nan);
4343e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  __ sdc1(value, MemOperand(scratch, instr->additional_index() <<
4344e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      element_size_shift));
4345e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
4346e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4347e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4348e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4349e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register value = ToRegister(instr->value());
4350e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register elements = ToRegister(instr->elements());
4351e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register key = instr->key()->IsRegister() ? ToRegister(instr->key())
4352e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      : no_reg;
4353e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register scratch = scratch0();
4354e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Register store_base = scratch;
4355e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  int offset = 0;
4356e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4357e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Do the store.
4358e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (instr->key()->IsConstantOperand()) {
4359e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4360e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
4361e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
4362e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                                           instr->additional_index());
4363e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    store_base = elements;
4364e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else {
4365e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // Even though the HLoadKeyed instruction forces the input
4366e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // representation for the key to be an integer, the input gets replaced
4367e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // during bound check elimination with the index argument to the bounds
4368e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // check, which can be tagged, so that case must be handled here, too.
436953ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org    if (instr->hydrogen()->key()->representation().IsSmi()) {
4370e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
4371e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      __ addu(scratch, elements, scratch);
4372e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    } else {
4373e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      __ sll(scratch, key, kPointerSizeLog2);
4374e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      __ addu(scratch, elements, scratch);
4375e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
4376e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    offset = FixedArray::OffsetOfElementAt(instr->additional_index());
4377e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4378e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  __ sw(value, FieldMemOperand(store_base, offset));
4379e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4380e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (instr->hydrogen()->NeedsWriteBarrier()) {
4381e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    SmiCheck check_needed =
43821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        instr->hydrogen()->value()->IsHeapObject()
43831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org            ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4384e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // Compute address of modified element and store it into key register.
4385e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    __ Addu(key, store_base, Operand(offset - kHeapObjectTag));
4386e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    __ RecordWrite(elements,
4387e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                   key,
4388e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                   value,
4389c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org                   GetRAState(),
4390e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                   kSaveFPRegs,
4391e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                   EMIT_REMEMBERED_SET,
4392e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                   check_needed);
4393e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4394e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
4395e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4396e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4397e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4398e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // By cases: external, fast double
4399e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (instr->is_external()) {
4400e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    DoStoreKeyedExternalArray(instr);
4401e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4402e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    DoStoreKeyedFixedDoubleArray(instr);
4403e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else {
4404e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    DoStoreKeyedFixedArray(instr);
4405e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4406e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
4407e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4408e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4409c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
4410c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->object()).is(a2));
4411c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->key()).is(a1));
4412c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->value()).is(a0));
4413c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
44141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4415c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
4416c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      : isolate()->builtins()->KeyedStoreIC_Initialize();
4417c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallCode(ic, RelocInfo::CODE_TARGET, instr);
4418c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4419c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4420c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4421c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4422c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register object_reg = ToRegister(instr->object());
4423c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
4424c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4425c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<Map> from_map = instr->original_map();
4426c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<Map> to_map = instr->transitioned_map();
4427003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  ElementsKind from_kind = instr->from_kind();
4428003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  ElementsKind to_kind = instr->to_kind();
4429c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4430c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label not_applicable;
4431c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset));
4432c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&not_applicable, ne, scratch, Operand(from_map));
4433c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
443446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
44357c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    Register new_map_reg = ToRegister(instr->new_map_temp());
44367c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    __ li(new_map_reg, Operand(to_map));
4437c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ sw(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset));
4438c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Write barrier.
4439c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
4440c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org                        scratch, GetRAState(), kDontSaveFPRegs);
4441d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  } else {
4442c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    PushSafepointRegistersScope scope(
4443c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org        this, Safepoint::kWithRegistersAndDoubles);
44447c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    __ mov(a0, object_reg);
44457c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    __ li(a1, Operand(to_map));
44467c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    TransitionElementsKindStub stub(from_kind, to_kind);
44477c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    __ CallStub(&stub);
4448c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    RecordSafepointWithRegistersAndDoubles(
44497c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org        instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4450c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
4451c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&not_applicable);
4452c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4453c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4454c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
44557c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgvoid LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
44567c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Register object = ToRegister(instr->object());
44577c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Register temp = ToRegister(instr->temp());
44587c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Label fail;
4459ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  __ TestJSArrayForAllocationMemento(object, temp, ne, &fail);
44607c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  DeoptimizeIf(al, instr->environment());
44617c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  __ bind(&fail);
44627c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org}
44637c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
44647c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
4465c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStringAdd(LStringAdd* instr) {
4466c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ push(ToRegister(instr->left()));
4467c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ push(ToRegister(instr->right()));
4468ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  StringAddStub stub(instr->hydrogen()->flags());
44698432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4471c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4472c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4473c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4474c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  class DeferredStringCharCodeAt: public LDeferredCode {
4475c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   public:
4476c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
4477c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
4478c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); }
4479c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual LInstruction* instr() { return instr_; }
4480c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   private:
4481c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LStringCharCodeAt* instr_;
4482c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  };
4483c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4484c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeferredStringCharCodeAt* deferred =
44857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      new(zone()) DeferredStringCharCodeAt(this, instr);
448664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  StringCharLoadGenerator::Generate(masm(),
448764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                                    ToRegister(instr->string()),
448864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                                    ToRegister(instr->index()),
448964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                                    ToRegister(instr->result()),
449064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                                    deferred->entry());
4491c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(deferred->exit());
4492c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4493c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4494c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4495c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
4496c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register string = ToRegister(instr->string());
4497c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
4498c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
4499c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4500c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // TODO(3095996): Get rid of this. For now, we need to make the
4501c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // result register contain a valid pointer because it is already
4502c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // contained in the register pointer map.
4503c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ mov(result, zero_reg);
4504c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4505c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4506c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ push(string);
4507c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Push the index as a smi. This is safe because of the checks in
4508c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // DoStringCharCodeAt above.
4509c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->index()->IsConstantOperand()) {
4510c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
4511c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Addu(scratch, zero_reg, Operand(Smi::FromInt(const_index)));
4512c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ push(scratch);
4513c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
4514c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register index = ToRegister(instr->index());
4515c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ SmiTag(index);
4516c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ push(index);
4517c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
4518c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr);
4519c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  __ AssertSmi(v0);
4520c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ SmiUntag(v0);
4521c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ StoreToSafepointRegisterSlot(v0, result);
4522c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4523c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4524c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4525c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4526c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  class DeferredStringCharFromCode: public LDeferredCode {
4527c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   public:
4528c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
4529c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
4530c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); }
4531c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual LInstruction* instr() { return instr_; }
4532c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   private:
4533c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LStringCharFromCode* instr_;
4534c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  };
4535c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4536c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeferredStringCharFromCode* deferred =
45377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      new(zone()) DeferredStringCharFromCode(this, instr);
4538c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4539c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
4540c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register char_code = ToRegister(instr->char_code());
4541c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
4542c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
4543c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!char_code.is(result));
4544c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4545c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(deferred->entry(), hi,
454659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org            char_code, Operand(String::kMaxOneByteCharCode));
4547c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex);
4548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ sll(scratch, char_code, kPointerSizeLog2);
4549c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Addu(result, result, scratch);
4550c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(result, FieldMemOperand(result, FixedArray::kHeaderSize));
4551c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
4552c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(deferred->entry(), eq, result, Operand(scratch));
4553c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(deferred->exit());
4554c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4555c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4556c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4557c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
4558c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register char_code = ToRegister(instr->char_code());
4559c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result = ToRegister(instr->result());
4560c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4561c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // TODO(3095996): Get rid of this. For now, we need to make the
4562c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // result register contain a valid pointer because it is already
4563c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // contained in the register pointer map.
4564c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ mov(result, zero_reg);
4565c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4566c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4567c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ SmiTag(char_code);
4568c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ push(char_code);
4569c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr);
4570c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ StoreToSafepointRegisterSlot(v0, result);
4571c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4572c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4573c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4574c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4575c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* input = instr->value();
4576c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(input->IsRegister() || input->IsStackSlot());
4577c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LOperand* output = instr->result();
4578c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(output->IsDoubleRegister());
4579c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  FPURegister single_scratch = double_scratch0().low();
4580c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (input->IsStackSlot()) {
4581c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register scratch = scratch0();
4582c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ lw(scratch, ToMemOperand(input));
4583c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ mtc1(scratch, single_scratch);
4584c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
4585c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ mtc1(ToRegister(input), single_scratch);
4586c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
4587c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ cvt_d_w(ToDoubleRegister(output), single_scratch);
4588c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4589c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4590c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4591a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
4592a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  LOperand* input = instr->value();
4593a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(input->IsRegister());
4594a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  LOperand* output = instr->result();
4595a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(output->IsRegister());
4596a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register scratch = scratch0();
4597a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
4598a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  __ SmiTagCheckOverflow(ToRegister(output), ToRegister(input), scratch);
4599a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  if (!instr->hydrogen()->value()->HasRange() ||
4600a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      !instr->hydrogen()->value()->range()->IsInSmiRange()) {
4601a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg));
4602a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
4603a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org}
4604a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
4605a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
460678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgvoid LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4607c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* input = instr->value();
460878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  LOperand* output = instr->result();
460978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
461078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  FPURegister dbl_scratch = double_scratch0();
461178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  __ mtc1(ToRegister(input), dbl_scratch);
461278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22);
461378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org}
461478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
461578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
4616c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4617c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  class DeferredNumberTagI: public LDeferredCode {
4618c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   public:
4619c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4620c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
462178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    virtual void Generate() {
462278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      codegen()->DoDeferredNumberTagI(instr_,
4623c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org                                      instr_->value(),
462478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                      SIGNED_INT32);
462578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    }
4626c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual LInstruction* instr() { return instr_; }
4627c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   private:
4628c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LNumberTagI* instr_;
4629c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  };
4630c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4631c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register src = ToRegister(instr->value());
4632fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  Register dst = ToRegister(instr->result());
4633c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register overflow = scratch0();
4634c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
46357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4636fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ SmiTagCheckOverflow(dst, src, overflow);
4637c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ BranchOnOverflow(deferred->entry(), overflow);
4638c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(deferred->exit());
4639c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4640c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4641c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
464278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgvoid LCodeGen::DoNumberTagU(LNumberTagU* instr) {
464378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  class DeferredNumberTagU: public LDeferredCode {
464478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org   public:
464578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
464678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
464778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    virtual void Generate() {
464878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      codegen()->DoDeferredNumberTagI(instr_,
4649c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org                                      instr_->value(),
465078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                      UNSIGNED_INT32);
465178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    }
465278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    virtual LInstruction* instr() { return instr_; }
465378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org   private:
465478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    LNumberTagU* instr_;
465578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  };
465678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
4657c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* input = instr->value();
465878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  ASSERT(input->IsRegister() && input->Equals(instr->result()));
465978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  Register reg = ToRegister(input);
466078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
466178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
466278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  __ Branch(deferred->entry(), hi, reg, Operand(Smi::kMaxValue));
466378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  __ SmiTag(reg, reg);
466478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  __ bind(deferred->exit());
466578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org}
466678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
466778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
466878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgvoid LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
466978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                    LOperand* value,
467078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                    IntegerSignedness signedness) {
4671c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label slow;
467278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  Register src = ToRegister(value);
4673fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  Register dst = ToRegister(instr->result());
467459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  DoubleRegister dbl_scratch = double_scratch0();
4675c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4676c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Preserve the value of all registers.
4677c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4678c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4679c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label done;
468078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (signedness == SIGNED_INT32) {
468178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    // There was overflow, so bits 30 and 31 of the original integer
468278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    // disagree. Try to allocate a heap number in new space and store
468378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    // the value in there. If that fails, call the runtime system.
468478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    if (dst.is(src)) {
468578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      __ SmiUntag(src, dst);
468678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      __ Xor(src, src, Operand(0x80000000));
468778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    }
4688e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ mtc1(src, dbl_scratch);
4689e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ cvt_d_w(dbl_scratch, dbl_scratch);
469078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  } else {
4691e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ mtc1(src, dbl_scratch);
4692e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22);
4693fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
469478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
4695c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (FLAG_inline_new) {
469659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex);
469759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    __ AllocateHeapNumber(t1, a3, t0, scratch0(), &slow, DONT_TAG_RESULT);
4698fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    __ Move(dst, t1);
4699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(&done);
4700c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
4701c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4702c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Slow case: Call the runtime system to do the number allocation.
4703c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&slow);
4704c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4705c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // TODO(3095996): Put a valid pointer value in the stack slot where the result
4706c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // register is stored, as this register is in the pointer map, but contains an
4707c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // integer value.
4708fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ StoreToSafepointRegisterSlot(zero_reg, dst);
4709c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4710fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ Move(dst, v0);
471183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ Subu(dst, dst, kHeapObjectTag);
4712c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4713c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Done. Put the value in dbl_scratch into the value of the allocated heap
4714c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // number.
4715c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&done);
4716e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset));
471783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ Addu(dst, dst, kHeapObjectTag);
4718fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ StoreToSafepointRegisterSlot(dst, dst);
4719c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4720c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4721c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4722c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4723c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  class DeferredNumberTagD: public LDeferredCode {
4724c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   public:
4725c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4726c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
4727c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
4728c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual LInstruction* instr() { return instr_; }
4729c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   private:
4730c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LNumberTagD* instr_;
4731c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  };
4732c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4733c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  DoubleRegister input_reg = ToDoubleRegister(instr->value());
4734c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
4735c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register reg = ToRegister(instr->result());
4736c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register temp1 = ToRegister(instr->temp());
4737c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register temp2 = ToRegister(instr->temp2());
4738c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
47397028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4740c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (FLAG_inline_new) {
4741c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
474283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    // We want the untagged address first for performance
474383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(),
474483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                          DONT_TAG_RESULT);
4745c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
4746c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(deferred->entry());
4747c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
4748c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(deferred->exit());
4749e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset));
475083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // Now that we have finished with the object's real address tag it
475183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ Addu(reg, reg, kHeapObjectTag);
4752c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4753c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4754c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4755c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4756c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // TODO(3095996): Get rid of this. For now, we need to make the
4757c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // result register contain a valid pointer because it is already
4758c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // contained in the register pointer map.
4759c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register reg = ToRegister(instr->result());
4760c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ mov(reg, zero_reg);
4761c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4762c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4763c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
476483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ Subu(v0, v0, kHeapObjectTag);
4765c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ StoreToSafepointRegisterSlot(v0, reg);
4766c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4767c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4768c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4769c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoSmiTag(LSmiTag* instr) {
4770c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
4771c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  __ SmiTag(ToRegister(instr->result()), ToRegister(instr->value()));
4772c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4773c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4774c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4775c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4776c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
4777c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input = ToRegister(instr->value());
4778fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  Register result = ToRegister(instr->result());
4779c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->needs_check()) {
4780c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    STATIC_ASSERT(kHeapObjectTag == 1);
4781c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // If the input is a HeapObject, value of scratch won't be zero.
4782fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    __ And(scratch, input, Operand(kHeapObjectTag));
4783fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    __ SmiUntag(result, input);
4784c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
4785c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
4786fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    __ SmiUntag(result, input);
4787c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
4788c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4789c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4790c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4791c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::EmitNumberUntagD(Register input_reg,
4792c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                DoubleRegister result_reg,
4793c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                                bool can_convert_undefined_to_nan,
47942efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                                bool deoptimize_on_minus_zero,
47957c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org                                LEnvironment* env,
47967c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org                                NumberUntagDMode mode) {
4797c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
4798c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4799c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label load_smi, heap_number, done;
4800c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4801c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
48027c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    // Smi check.
48037c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi);
4804c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
48057c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    // Heap number map check.
48067c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
48077c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
4808c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    if (!can_convert_undefined_to_nan) {
48097c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      DeoptimizeIf(ne, env, scratch, Operand(at));
48107c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    } else {
4811c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      Label heap_number, convert;
48127c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ Branch(&heap_number, eq, scratch, Operand(at));
4813c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4814c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      // Convert undefined (and hole) to NaN.
48157c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
48167c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      DeoptimizeIf(ne, env, input_reg, Operand(at));
4817c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4818c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      __ bind(&convert);
48197c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ LoadRoot(at, Heap::kNanValueRootIndex);
48207c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ ldc1(result_reg, FieldMemOperand(at, HeapNumber::kValueOffset));
48217c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ Branch(&done);
4822c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
48237c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ bind(&heap_number);
48247c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    }
48257c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    // Heap number to double register conversion.
48267c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset));
48277c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    if (deoptimize_on_minus_zero) {
48287c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ mfc1(at, result_reg.low());
48297c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ Branch(&done, ne, at, Operand(zero_reg));
48307c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      __ mfc1(scratch, result_reg.high());
48317c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      DeoptimizeIf(eq, env, scratch, Operand(HeapNumber::kSignMask));
48327c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    }
48337c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    __ Branch(&done);
48347c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  } else {
48357c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    __ SmiUntag(scratch, input_reg);
48367c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
48372efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  }
4838c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4839c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Smi to double register conversion
4840c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&load_smi);
4841fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // scratch: untagged value of input_reg
4842fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ mtc1(scratch, result_reg);
4843c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ cvt_d_w(result_reg, result_reg);
4844c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&done);
4845c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4846c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4847c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4848c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
4849c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input_reg = ToRegister(instr->value());
4850c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch1 = scratch0();
4851c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register scratch2 = ToRegister(instr->temp());
4852c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DoubleRegister double_scratch = double_scratch0();
485383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  DoubleRegister double_scratch2 = ToDoubleRegister(instr->temp3());
4854c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4855c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2));
4856c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1));
4857c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4858c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label done;
4859c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4860c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // The input is a tagged HeapObject.
4861c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Heap number map check.
4862c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4863c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
4864c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // This 'at' value and scratch1 map value are used for tests in both clauses
4865c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // of the if.
4866c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4867c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->truncating()) {
4868c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Register scratch3 = ToRegister(instr->temp2());
486983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    FPURegister single_scratch = double_scratch.low();
4870c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    ASSERT(!scratch3.is(input_reg) &&
4871c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org           !scratch3.is(scratch1) &&
4872c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org           !scratch3.is(scratch2));
4873c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Performs a truncating conversion of a floating point number as used by
4874c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // the JS bitwise operations.
4875c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Label heap_number;
4876c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(&heap_number, eq, scratch1, Operand(at));  // HeapNumber map?
4877c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Check for undefined. Undefined is converted to zero for truncating
4878c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // conversions.
4879c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
4880c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(ne, instr->environment(), input_reg, Operand(at));
4881c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    ASSERT(ToRegister(instr->result()).is(input_reg));
4882c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ mov(input_reg, zero_reg);
4883c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(&done);
4884c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4885c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ bind(&heap_number);
4886c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ ldc1(double_scratch2,
4887c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            FieldMemOperand(input_reg, HeapNumber::kValueOffset));
4888c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ EmitECMATruncate(input_reg,
4889c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        double_scratch2,
4890c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        single_scratch,
4891c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        scratch1,
4892c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        scratch2,
4893c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        scratch3);
4894c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
4895c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Deoptimize if we don't have a heap number.
4896c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(ne, instr->environment(), scratch1, Operand(at));
4897c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4898c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Load the double value.
4899c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ ldc1(double_scratch,
4900c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            FieldMemOperand(input_reg, HeapNumber::kValueOffset));
4901c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4902c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register except_flag = scratch2;
4903c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ EmitFPUTruncate(kRoundToZero,
490483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                       input_reg,
4905c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       double_scratch,
4906c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       scratch1,
490783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                       double_scratch2,
4908c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       except_flag,
4909c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       kCheckForInexactConversion);
4910c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4911c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Deopt if the operation did not succeed.
4912c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
4913c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4914c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4915c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ Branch(&done, ne, input_reg, Operand(zero_reg));
4916c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4917c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ mfc1(scratch1, double_scratch.high());
4918c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
4919c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
4920c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
4921c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
4922c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&done);
4923c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4924c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4925c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4926c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4927c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  class DeferredTaggedToI: public LDeferredCode {
4928c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   public:
4929c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4930c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
4931c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
4932c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual LInstruction* instr() { return instr_; }
4933c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   private:
4934c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LTaggedToI* instr_;
4935c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  };
4936c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4937c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* input = instr->value();
4938c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(input->IsRegister());
4939c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(input->Equals(instr->result()));
4940c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4941c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register input_reg = ToRegister(input);
4942c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
49437028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4944c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4945c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Let the deferred code handle the HeapObject case.
4946c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ JumpIfNotSmi(input_reg, deferred->entry());
4947c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4948c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Smi to int32 conversion.
4949c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ SmiUntag(input_reg);
4950c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(deferred->exit());
4951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4952c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4953c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4954c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4955c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* input = instr->value();
4956c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(input->IsRegister());
4957c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LOperand* result = instr->result();
4958c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(result->IsDoubleRegister());
4959c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4960c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register input_reg = ToRegister(input);
4961c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DoubleRegister result_reg = ToDoubleRegister(result);
4962c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
49637c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  HValue* value = instr->hydrogen()->value();
4964c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  NumberUntagDMode mode = value->representation().IsSmi()
4965c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com      ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED;
49667c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
4967c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  EmitNumberUntagD(input_reg, result_reg,
4968c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                   instr->hydrogen()->can_convert_undefined_to_nan(),
49692efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                   instr->hydrogen()->deoptimize_on_minus_zero(),
49707c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org                   instr->environment(),
49717c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org                   mode);
4972c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
4973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4974c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4975c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4976c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result_reg = ToRegister(instr->result());
4977c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch1 = scratch0();
4978c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register scratch2 = ToRegister(instr->temp());
4979c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  DoubleRegister double_input = ToDoubleRegister(instr->value());
4980c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4981c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->truncating()) {
4982c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Register scratch3 = ToRegister(instr->temp2());
498383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    FPURegister single_scratch = double_scratch0().low();
4984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ EmitECMATruncate(result_reg,
4985c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        double_input,
4986c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        single_scratch,
4987c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        scratch1,
4988c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        scratch2,
4989c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        scratch3);
4990c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
4991c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Register except_flag = scratch2;
4992c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4993c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ EmitFPUTruncate(kRoundToMinusInf,
499483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                       result_reg,
4995c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       double_input,
4996c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       scratch1,
499783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                       double_scratch0(),
4998c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       except_flag,
4999c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       kCheckForInexactConversion);
5000c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5001c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Deopt if the operation did not succeed (except_flag != 0).
5002c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
5003a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5004a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5005a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      Label done;
5006a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      __ Branch(&done, ne, result_reg, Operand(zero_reg));
5007a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      __ mfc1(scratch1, double_input.high());
5008a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
5009a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
5010a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      __ bind(&done);
5011a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    }
5012a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
5013a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org}
5014a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5015a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5016a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5017a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register result_reg = ToRegister(instr->result());
5018a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register scratch1 = scratch0();
5019a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Register scratch2 = ToRegister(instr->temp());
5020a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  DoubleRegister double_input = ToDoubleRegister(instr->value());
5021a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5022a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  if (instr->truncating()) {
5023a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    Register scratch3 = ToRegister(instr->temp2());
5024a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    FPURegister single_scratch = double_scratch0().low();
5025a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ EmitECMATruncate(result_reg,
5026a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                        double_input,
5027a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                        single_scratch,
5028a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                        scratch1,
5029a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                        scratch2,
5030a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                        scratch3);
5031a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  } else {
5032a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    Register except_flag = scratch2;
5033a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5034a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ EmitFPUTruncate(kRoundToMinusInf,
5035a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                       result_reg,
5036a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                       double_input,
5037a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                       scratch1,
5038a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                       double_scratch0(),
5039a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                       except_flag,
5040a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                       kCheckForInexactConversion);
5041a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5042a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // Deopt if the operation did not succeed (except_flag != 0).
5043a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
5044a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5045a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5046a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      Label done;
5047a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      __ Branch(&done, ne, result_reg, Operand(zero_reg));
5048a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      __ mfc1(scratch1, double_input.high());
5049a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
5050a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
5051a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      __ bind(&done);
5052a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    }
5053c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
5054a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  __ SmiTagCheckOverflow(result_reg, result_reg, scratch1);
5055a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  DeoptimizeIf(lt, instr->environment(), scratch1, Operand(zero_reg));
5056a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org}
5057a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5058a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5059c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5060c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* input = instr->value();
5061c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ And(at, ToRegister(input), Operand(kSmiTagMask));
5062c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg));
5063c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5064c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5065c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5066c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
50671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!instr->hydrogen()->value()->IsHeapObject()) {
50681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    LOperand* input = instr->value();
50691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    __ And(at, ToRegister(input), Operand(kSmiTagMask));
50701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
50711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
5072c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5073c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5074c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5075c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
5076c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input = ToRegister(instr->value());
5077c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
5078c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5079c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ GetObjectType(input, scratch, scratch);
5080c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5081c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->hydrogen()->is_interval_check()) {
5082c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    InstanceType first;
5083c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    InstanceType last;
5084c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    instr->hydrogen()->GetCheckInterval(&first, &last);
5085c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5086c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // If there is only one type in the interval check for equality.
5087c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (first == last) {
5088c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      DeoptimizeIf(ne, instr->environment(), scratch, Operand(first));
5089c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
5090c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      DeoptimizeIf(lo, instr->environment(), scratch, Operand(first));
5091c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // Omit check for the last type.
5092c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      if (last != LAST_TYPE) {
5093c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        DeoptimizeIf(hi, instr->environment(), scratch, Operand(last));
5094c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      }
5095c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
5096c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
5097c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    uint8_t mask;
5098c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    uint8_t tag;
5099c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
5100c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5101c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (IsPowerOf2(mask)) {
5102c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ASSERT(tag == 0 || IsPowerOf2(tag));
5103c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ And(at, scratch, mask);
5104c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      DeoptimizeIf(tag == 0 ? ne : eq, instr->environment(),
5105c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          at, Operand(zero_reg));
5106c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else {
5107c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ And(scratch, scratch, Operand(mask));
5108c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      DeoptimizeIf(ne, instr->environment(), scratch, Operand(tag));
5109c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
5110c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
5111c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5112c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5113c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5114c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoCheckFunction(LCheckFunction* instr) {
511564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Register reg = ToRegister(instr->value());
511664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Handle<JSFunction> target = instr->hydrogen()->target();
511779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowDeferredHandleDereference smi_check;
511864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (isolate()->heap()->InNewSpace(*target)) {
511964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    Register reg = ToRegister(instr->value());
5120594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Handle<Cell> cell = isolate()->factory()->NewCell(target);
512164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ li(at, Operand(Handle<Object>(cell)));
5122f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org    __ lw(at, FieldMemOperand(at, Cell::kValueOffset));
512364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    DeoptimizeIf(ne, instr->environment(), reg,
512464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                 Operand(at));
512564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  } else {
512664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    DeoptimizeIf(ne, instr->environment(), reg,
512764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                 Operand(target));
512864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
5129c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5130c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5131c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5132594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5133594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  {
5134594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
5135594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ push(object);
5136594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr);
5137594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ StoreToSafepointRegisterSlot(v0, scratch0());
5138594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
5139594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  __ And(at, scratch0(), Operand(kSmiTagMask));
5140594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
514105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org}
514205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
514305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
51441456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5145594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  class DeferredCheckMaps: public LDeferredCode {
5146594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org   public:
5147594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
5148594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        : LDeferredCode(codegen), instr_(instr), object_(object) {
5149594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      SetExit(check_maps());
5150594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
5151594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    virtual void Generate() {
5152594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      codegen()->DoDeferredInstanceMigration(instr_, object_);
5153594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
5154594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Label* check_maps() { return &check_maps_; }
5155594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    virtual LInstruction* instr() { return instr_; }
5156594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org   private:
5157594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    LCheckMaps* instr_;
5158594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Label check_maps_;
5159594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Register object_;
5160594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  };
5161594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
5162c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (instr->hydrogen()->CanOmitMapChecks()) return;
516359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  Register map_reg = scratch0();
5164c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  LOperand* input = instr->value();
5165c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(input->IsRegister());
5166c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register reg = ToRegister(input);
51671456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  SmallMapList* map_set = instr->hydrogen()->map_set();
516859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
5169594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
5170594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  DeferredCheckMaps* deferred = NULL;
5171594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (instr->hydrogen()->has_migration_target()) {
5172594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
5173594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ bind(deferred->check_maps());
5174594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
5175594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
5176594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Label success;
51771456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  for (int i = 0; i < map_set->length() - 1; i++) {
51781456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    Handle<Map> map = map_set->at(i);
5179a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    __ CompareMapAndBranch(map_reg, map, &success, eq, &success);
51801456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  }
51811456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  Handle<Map> map = map_set->last();
5182594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Do the CompareMap() directly within the Branch() and DeoptimizeIf().
5183594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (instr->hydrogen()->has_migration_target()) {
5184594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Branch(deferred->entry(), ne, map_reg, Operand(map));
5185594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else {
5186594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    DeoptimizeIf(ne, instr->environment(), map_reg, Operand(map));
5187594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
5188594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
51891456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  __ bind(&success);
5190c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5191c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5192c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5193c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5194c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
5195c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result_reg = ToRegister(instr->result());
5196c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
5197c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ ClampDoubleToUint8(result_reg, value_reg, temp_reg);
5198c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5199c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5200c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5201c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5202c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register unclamped_reg = ToRegister(instr->unclamped());
5203c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result_reg = ToRegister(instr->result());
5204c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ ClampUint8(result_reg, unclamped_reg);
5205c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5206c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5207c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5208c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5209c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
5210c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register input_reg = ToRegister(instr->unclamped());
5211c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register result_reg = ToRegister(instr->result());
5212c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
5213c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label is_smi, done, heap_number;
5214c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5215c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Both smi and heap number cases are handled.
5216fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi);
5217c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5218c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Check for heap number
5219c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
5220c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&heap_number, eq, scratch, Operand(factory()->heap_number_map()));
5221c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5222c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Check for undefined. Undefined is converted to zero for clamping
5223c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // conversions.
5224c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DeoptimizeIf(ne, instr->environment(), input_reg,
5225c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org               Operand(factory()->undefined_value()));
5226c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ mov(result_reg, zero_reg);
5227c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ jmp(&done);
5228c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5229c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Heap number
5230c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&heap_number);
5231c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ ldc1(double_scratch0(), FieldMemOperand(input_reg,
5232c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                             HeapNumber::kValueOffset));
5233c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg);
5234c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ jmp(&done);
5235c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5236c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&is_smi);
5237c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ ClampUint8(result_reg, scratch);
5238c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5239c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&done);
5240c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5241c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5242c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
52437c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgvoid LCodeGen::DoAllocate(LAllocate* instr) {
52447c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  class DeferredAllocate: public LDeferredCode {
52457c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org   public:
52467c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
52477c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
52487c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    virtual void Generate() { codegen()->DoDeferredAllocate(instr_); }
52497c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    virtual LInstruction* instr() { return instr_; }
52507c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org   private:
52517c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    LAllocate* instr_;
52527c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  };
52537c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
52547c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  DeferredAllocate* deferred =
52557c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      new(zone()) DeferredAllocate(this, instr);
52567c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
52577c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Register result = ToRegister(instr->result());
52587c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Register scratch = ToRegister(instr->temp1());
52597c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Register scratch2 = ToRegister(instr->temp2());
52607c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
52614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Allocate memory for the object.
52624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  AllocationFlags flags = TAG_OBJECT;
52634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (instr->hydrogen()->MustAllocateDoubleAligned()) {
52644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT);
52654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
5266d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5267d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5268d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5269e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE);
5270d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5271d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5272b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE);
5273e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
52744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (instr->size()->IsConstantOperand()) {
52754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
52764c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org    __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags);
52777c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  } else {
52784a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Register size = ToRegister(instr->size());
5279f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    __ Allocate(size,
5280f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                result,
5281f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                scratch,
5282f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                scratch2,
5283f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                deferred->entry(),
5284f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                flags);
52857c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  }
52867c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
52877c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  __ bind(deferred->exit());
5288c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
5289c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (instr->hydrogen()->MustPrefillWithFiller()) {
5290c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    if (instr->size()->IsConstantOperand()) {
5291c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5292c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      __ li(scratch, Operand(size));
5293c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    } else {
5294c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      scratch = ToRegister(instr->size());
5295c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    }
5296c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    __ Subu(scratch, scratch, Operand(kPointerSize));
5297c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    __ Subu(result, result, Operand(kHeapObjectTag));
5298c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    Label loop;
5299c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    __ bind(&loop);
5300c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    __ li(scratch2, Operand(isolate()->factory()->one_pointer_filler_map()));
5301c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    __ Addu(at, result, Operand(scratch));
5302c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    __ sw(scratch2, MemOperand(at));
5303c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    __ Subu(scratch, scratch, Operand(kPointerSize));
5304c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    __ Branch(&loop, ge, scratch, Operand(zero_reg));
5305c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    __ Addu(result, result, Operand(kHeapObjectTag));
5306c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  }
53077c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org}
53087c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
53097c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
53107c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgvoid LCodeGen::DoDeferredAllocate(LAllocate* instr) {
53117c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Register result = ToRegister(instr->result());
53127c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
53137c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  // TODO(3095996): Get rid of this. For now, we need to make the
53147c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  // result register contain a valid pointer because it is already
53157c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  // contained in the register pointer map.
53167c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  __ mov(result, zero_reg);
53177c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
53187c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
5319f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (instr->size()->IsRegister()) {
5320f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    Register size = ToRegister(instr->size());
5321f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    ASSERT(!size.is(result));
5322f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    __ SmiTag(size);
5323f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    __ push(size);
5324f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  } else {
5325f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5326f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    __ Push(Smi::FromInt(size));
5327f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
5328f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
5329d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5330d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5331d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5332b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    CallRuntimeFromDeferred(Runtime::kAllocateInOldPointerSpace, 1, instr);
5333d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5334d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5335b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    CallRuntimeFromDeferred(Runtime::kAllocateInOldDataSpace, 1, instr);
5336e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  } else {
5337b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr);
5338e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
53397c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  __ StoreToSafepointRegisterSlot(v0, result);
53407c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org}
53417c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
53427c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
5343c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5344c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  ASSERT(ToRegister(instr->value()).is(a0));
5345c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
5346c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ push(a0);
5347c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallRuntime(Runtime::kToFastProperties, 1, instr);
5348c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5349c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5350c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5351c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5352c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label materialized;
5353c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Registers will be used as follows:
5354c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // t3 = literals array.
5355c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // a1 = regexp literal.
5356c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // a0 = regexp literal clone.
5357c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // a2 and t0-t2 are used as temporaries.
53589c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org  int literal_offset =
53599c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org      FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
53609c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org  __ LoadHeapObject(t3, instr->hydrogen()->literals());
5361c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(a1, FieldMemOperand(t3, literal_offset));
5362c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
5363c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&materialized, ne, a1, Operand(at));
5364c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5365c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Create regexp literal using runtime function
5366c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Result will be in v0.
5367c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(t2, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
5368c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(t1, Operand(instr->hydrogen()->pattern()));
5369c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(t0, Operand(instr->hydrogen()->flags()));
5370c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Push(t3, t2, t1, t0);
5371c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
5372c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ mov(a1, v0);
5373c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5374c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&materialized);
5375c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
5376c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label allocated, runtime_allocate;
5377c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
53784c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  __ Allocate(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT);
5379c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ jmp(&allocated);
5380c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5381c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&runtime_allocate);
5382c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ li(a0, Operand(Smi::FromInt(size)));
5383c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Push(a1, a0);
5384c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
5385c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ pop(a1);
5386c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5387c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&allocated);
5388c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Copy the content into the newly allocated memory.
5389c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // (Unroll copy loop once for better throughput).
5390c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) {
5391c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ lw(a3, FieldMemOperand(a1, i));
5392c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ lw(a2, FieldMemOperand(a1, i + kPointerSize));
5393c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ sw(a3, FieldMemOperand(v0, i));
5394c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ sw(a2, FieldMemOperand(v0, i + kPointerSize));
5395c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
5396c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if ((size % (2 * kPointerSize)) != 0) {
5397c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ lw(a3, FieldMemOperand(a1, size - kPointerSize));
5398c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ sw(a3, FieldMemOperand(v0, size - kPointerSize));
5399c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
5400c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5401c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5402c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5403c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
5404c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Use the fast case closure allocation code that allocates in new
5405c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // space for nested functions that don't need literals cloning.
5406c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool pretenure = instr->hydrogen()->pretenure();
540732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  if (!pretenure && instr->hydrogen()->has_no_literals()) {
540832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    FastNewClosureStub stub(instr->hydrogen()->language_mode(),
540932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                            instr->hydrogen()->is_generator());
541032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ li(a1, Operand(instr->hydrogen()->shared_info()));
5411c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ push(a1);
54128432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
5413c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
541432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ li(a2, Operand(instr->hydrogen()->shared_info()));
541532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ li(a1, Operand(pretenure ? factory()->true_value()
541632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                                : factory()->false_value()));
5417c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Push(cp, a2, a1);
5418c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    CallRuntime(Runtime::kNewClosure, 3, instr);
5419c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
5420c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5421c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5422c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5423c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoTypeof(LTypeof* instr) {
5424c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(ToRegister(instr->result()).is(v0));
5425c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input = ToRegister(instr->value());
5426c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ push(input);
5427c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CallRuntime(Runtime::kTypeof, 1, instr);
5428c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5429c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5430c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5431c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5432c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register input = ToRegister(instr->value());
5433c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5434c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register cmp1 = no_reg;
5435c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Operand cmp2 = Operand(no_reg);
5436c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
54371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Condition final_branch_condition = EmitTypeofIs(instr->TrueLabel(chunk_),
54381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                                  instr->FalseLabel(chunk_),
5439c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                                  input,
5440c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                                  instr->type_literal(),
5441c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                                  cmp1,
5442c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                                  cmp2);
5443c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5444c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(cmp1.is_valid());
5445c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!cmp2.is_reg() || cmp2.rm().is_valid());
5446c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5447c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (final_branch_condition != kNoCondition) {
54481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    EmitBranch(instr, final_branch_condition, cmp1, cmp2);
5449c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
5450c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5451c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5452c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5453c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgCondition LCodeGen::EmitTypeofIs(Label* true_label,
5454c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 Label* false_label,
5455c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 Register input,
5456c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 Handle<String> type_name,
5457c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 Register& cmp1,
5458c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                 Operand& cmp2) {
5459c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // This function utilizes the delay slot heavily. This is used to load
5460c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // values that are always usable without depending on the type of the input
5461c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // register.
5462c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Condition final_branch_condition = kNoCondition;
5463c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register scratch = scratch0();
5464750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (type_name->Equals(heap()->number_string())) {
5465c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ JumpIfSmi(input, true_label);
5466c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ lw(input, FieldMemOperand(input, HeapObject::kMapOffset));
5467c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
5468c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp1 = input;
5469c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp2 = Operand(at);
5470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    final_branch_condition = eq;
5471c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5472750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  } else if (type_name->Equals(heap()->string_string())) {
5473c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ JumpIfSmi(input, false_label);
5474c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ GetObjectType(input, input, scratch);
5475c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(USE_DELAY_SLOT, false_label,
5476c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org              ge, scratch, Operand(FIRST_NONSTRING_TYPE));
5477c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // input is an object so we can load the BitFieldOffset even if we take the
5478c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // other branch.
5479c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset));
5480c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ And(at, at, 1 << Map::kIsUndetectable);
5481c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp1 = at;
5482c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp2 = Operand(zero_reg);
5483c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    final_branch_condition = eq;
5484c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5485f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  } else if (type_name->Equals(heap()->symbol_string())) {
5486f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    __ JumpIfSmi(input, false_label);
5487f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    __ GetObjectType(input, input, scratch);
5488f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    cmp1 = scratch;
5489f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    cmp2 = Operand(SYMBOL_TYPE);
5490f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    final_branch_condition = eq;
5491f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
5492750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  } else if (type_name->Equals(heap()->boolean_string())) {
5493c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ LoadRoot(at, Heap::kTrueValueRootIndex);
5494c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input));
5495c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ LoadRoot(at, Heap::kFalseValueRootIndex);
5496c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp1 = at;
5497c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp2 = Operand(input);
5498c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    final_branch_condition = eq;
5499c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5500750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) {
5501c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ LoadRoot(at, Heap::kNullValueRootIndex);
5502c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp1 = at;
5503c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp2 = Operand(input);
5504c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    final_branch_condition = eq;
5505c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5506750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  } else if (type_name->Equals(heap()->undefined_string())) {
5507c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
5508c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input));
5509c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // The first instruction of JumpIfSmi is an And - it is safe in the delay
5510c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // slot.
5511c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ JumpIfSmi(input, false_label);
5512c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Check for undetectable objects => true.
5513c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ lw(input, FieldMemOperand(input, HeapObject::kMapOffset));
5514c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset));
5515c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ And(at, at, 1 << Map::kIsUndetectable);
5516c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp1 = at;
5517c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp2 = Operand(zero_reg);
5518c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    final_branch_condition = ne;
5519c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5520750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  } else if (type_name->Equals(heap()->function_string())) {
5521c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
5522c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ JumpIfSmi(input, false_label);
5523c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ GetObjectType(input, scratch, input);
5524c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(true_label, eq, input, Operand(JS_FUNCTION_TYPE));
5525c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp1 = input;
5526c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp2 = Operand(JS_FUNCTION_PROXY_TYPE);
5527c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    final_branch_condition = eq;
5528c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5529750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  } else if (type_name->Equals(heap()->object_string())) {
5530c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ JumpIfSmi(input, false_label);
5531c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (!FLAG_harmony_typeof) {
5532c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ LoadRoot(at, Heap::kNullValueRootIndex);
5533c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input));
5534c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
5535f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    Register map = input;
5536f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    __ GetObjectType(input, map, scratch);
5537f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    __ Branch(false_label,
5538f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org              lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
5539c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(USE_DELAY_SLOT, false_label,
5540c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org              gt, scratch, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
5541f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // map is still valid, so the BitField can be loaded in delay slot.
5542c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Check for undetectable objects => false.
5543f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset));
5544c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ And(at, at, 1 << Map::kIsUndetectable);
5545c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp1 = at;
5546c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp2 = Operand(zero_reg);
5547c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    final_branch_condition = eq;
5548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5549c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
5550c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp1 = at;
5551c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    cmp2 = Operand(zero_reg);  // Set to valid regs, to avoid caller assertion.
5552c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(false_label);
5553c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
5554c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5555c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return final_branch_condition;
5556c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5557c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5558c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5559c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5560c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  Register temp1 = ToRegister(instr->temp());
5561c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5562c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  EmitIsConstructCall(temp1, scratch0());
5563c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
55641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  EmitBranch(instr, eq, temp1,
5565c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org             Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
5566c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5567c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5568c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5569c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) {
5570c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!temp1.is(temp2));
5571c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Get the frame pointer for the calling frame.
5572c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
5573c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5574c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Skip the arguments adaptor frame if it exists.
5575c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label check_frame_marker;
5576c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset));
5577c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&check_frame_marker, ne, temp2,
5578c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
5579c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset));
5580c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5581c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Check the marker in the calling frame.
5582c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&check_frame_marker);
5583c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset));
5584c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5585c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5586c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
55870ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorryvoid LCodeGen::EnsureSpaceForLazyDeopt() {
558859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (info()->IsStub()) return;
55890ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  // Ensure that we have enough space after the previous lazy-bailout
55900ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  // instruction for patching the code here.
55910ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  int current_pc = masm()->pc_offset();
55920ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  int patch_size = Deoptimizer::patch_size();
55930ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  if (current_pc < last_lazy_deopt_pc_ + patch_size) {
55940ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc;
55950ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    ASSERT_EQ(0, padding_size % Assembler::kInstrSize);
55960ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    while (padding_size > 0) {
55970ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      __ nop();
55980ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      padding_size -= Assembler::kInstrSize;
55990ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    }
56000ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  }
56010ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry}
56020ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
56030ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
5604c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoLazyBailout(LLazyBailout* instr) {
56050ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  EnsureSpaceForLazyDeopt();
56066fe0fda6a144bf4a3991162c622e8745376b755aulan@chromium.org  last_lazy_deopt_pc_ = masm()->pc_offset();
56070ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  ASSERT(instr->HasEnvironment());
56080ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  LEnvironment* env = instr->environment();
56090ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
56100ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
5611c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5612c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5613c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5614c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5615c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  Deoptimizer::BailoutType type = instr->hydrogen()->type();
5616c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
5617c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // needed return address), even though the implementation of LAZY and EAGER is
5618c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // now identical. When LAZY is eventually completely folded into EAGER, remove
5619c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // the special case below.
5620c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (info()->IsStub() && type == Deoptimizer::EAGER) {
5621c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    type = Deoptimizer::LAZY;
5622c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  }
5623594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
5624594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
5625c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  DeoptimizeIf(al, instr->environment(), type, zero_reg, Operand(zero_reg));
5626c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5627c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5628c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
562946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgvoid LCodeGen::DoDummyUse(LDummyUse* instr) {
563046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  // Nothing to see here, move on!
563146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org}
563246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
563346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
5634c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
56350ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
56360ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  __ CallRuntimeSaveDoubles(Runtime::kStackGuard);
56370ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  RecordSafepointWithLazyDeopt(
56380ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
56390ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  ASSERT(instr->HasEnvironment());
56400ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  LEnvironment* env = instr->environment();
56410ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
5642c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5643c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5644c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5645c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoStackCheck(LStackCheck* instr) {
5646c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  class DeferredStackCheck: public LDeferredCode {
5647c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   public:
5648c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
5649c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        : LDeferredCode(codegen), instr_(instr) { }
5650c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
5651c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    virtual LInstruction* instr() { return instr_; }
5652c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   private:
5653c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LStackCheck* instr_;
5654c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  };
5655c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
56560ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  ASSERT(instr->HasEnvironment());
56570ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  LEnvironment* env = instr->environment();
56580ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  // There is no LLazyBailout instruction for stack-checks. We have to
56590ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  // prepare for lazy deoptimization explicitly here.
5660c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->hydrogen()->is_function_entry()) {
5661c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Perform stack overflow check.
5662c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Label done;
5663c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ LoadRoot(at, Heap::kStackLimitRootIndex);
5664c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(&done, hs, sp, Operand(at));
5665c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    StackCheckStub stub;
56668432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
56670ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    EnsureSpaceForLazyDeopt();
56686fe0fda6a144bf4a3991162c622e8745376b755aulan@chromium.org    last_lazy_deopt_pc_ = masm()->pc_offset();
5669c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ bind(&done);
56700ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
56710ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
5672c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
5673c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    ASSERT(instr->hydrogen()->is_backwards_branch());
5674c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Perform stack overflow check if this goto needs it before jumping.
5675c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    DeferredStackCheck* deferred_stack_check =
56767028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        new(zone()) DeferredStackCheck(this, instr);
5677c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ LoadRoot(at, Heap::kStackLimitRootIndex);
5678c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ Branch(deferred_stack_check->entry(), lo, sp, Operand(at));
56790ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    EnsureSpaceForLazyDeopt();
56806fe0fda6a144bf4a3991162c622e8745376b755aulan@chromium.org    last_lazy_deopt_pc_ = masm()->pc_offset();
5681c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ bind(instr->done_label());
5682c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    deferred_stack_check->SetExit(instr->done_label());
56830ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
56840ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    // Don't record a deoptimization index for the safepoint here.
56850ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    // This will be done explicitly when emitting call and the safepoint in
56860ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    // the deferred code.
5687c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
5688c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5689c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5690c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5691c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid LCodeGen::DoOsrEntry(LOsrEntry* instr) {
5692c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // This is a pseudo-instruction that ensures that the environment here is
5693c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // properly registered for deoptimization and records the assembler's PC
5694c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // offset.
5695c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LEnvironment* environment = instr->environment();
5696c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5697c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // If the environment were already registered, we would have no way of
5698c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // backpatching it with the spill slot operands.
5699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!environment->HasBeenRegistered());
57000ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
57011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
57021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Normally we record the first unknown OSR value as the entrypoint to the OSR
57031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // code, but if there were none, record the entrypoint here.
57041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (osr_pc_offset_ == -1) osr_pc_offset_ = masm()->pc_offset();
5705c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5706c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5707c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5708812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
5709812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Register result = ToRegister(instr->result());
5710812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Register object = ToRegister(instr->object());
5711812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
5712812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  DeoptimizeIf(eq, instr->environment(), object, Operand(at));
5713812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5714812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Register null_value = t1;
5715812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ LoadRoot(null_value, Heap::kNullValueRootIndex);
5716812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  DeoptimizeIf(eq, instr->environment(), object, Operand(null_value));
5717812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5718812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ And(at, object, kSmiTagMask);
5719812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
5720812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5721812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
5722812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ GetObjectType(object, a1, a1);
5723812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  DeoptimizeIf(le, instr->environment(), a1, Operand(LAST_JS_PROXY_TYPE));
5724812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5725812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Label use_cache, call_runtime;
5726812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  ASSERT(object.is(a0));
5727812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ CheckEnumCache(null_value, &call_runtime);
5728812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5729812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ lw(result, FieldMemOperand(object, HeapObject::kMapOffset));
5730812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ Branch(&use_cache);
5731812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5732812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // Get the set of properties to enumerate.
5733812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ bind(&call_runtime);
5734812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ push(object);
5735812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
5736812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5737812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
5738812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  ASSERT(result.is(v0));
5739812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ LoadRoot(at, Heap::kMetaMapRootIndex);
5740812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  DeoptimizeIf(ne, instr->environment(), a1, Operand(at));
5741812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ bind(&use_cache);
5742812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org}
5743812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5744812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5745812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
5746812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Register map = ToRegister(instr->map());
5747812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Register result = ToRegister(instr->result());
574878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  Label load_cache, done;
574978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  __ EnumLength(result, map);
575078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  __ Branch(&load_cache, ne, result, Operand(Smi::FromInt(0)));
575178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  __ li(result, Operand(isolate()->factory()->empty_fixed_array()));
575278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  __ jmp(&done);
575378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
575478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  __ bind(&load_cache);
575589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  __ LoadInstanceDescriptors(map, result);
5756812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ lw(result,
5757304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org        FieldMemOperand(result, DescriptorArray::kEnumCacheOffset));
5758812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ lw(result,
5759812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org        FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
5760812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg));
576178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
576278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  __ bind(&done);
5763812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org}
5764812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5765812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5766812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5767812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Register object = ToRegister(instr->value());
5768812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Register map = ToRegister(instr->map());
5769812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ lw(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset));
5770812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  DeoptimizeIf(ne, instr->environment(), map, Operand(scratch0()));
5771812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org}
5772812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5773812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5774812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
5775812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Register object = ToRegister(instr->object());
5776812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Register index = ToRegister(instr->index());
5777812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Register result = ToRegister(instr->result());
5778812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Register scratch = scratch0();
5779812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5780812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Label out_of_object, done;
5781812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ Branch(USE_DELAY_SLOT, &out_of_object, lt, index, Operand(zero_reg));
5782812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ sll(scratch, index, kPointerSizeLog2 - kSmiTagSize);  // In delay slot.
5783812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5784812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  STATIC_ASSERT(kPointerSizeLog2 > kSmiTagSize);
5785812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ Addu(scratch, object, scratch);
5786812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ lw(result, FieldMemOperand(scratch, JSObject::kHeaderSize));
5787812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5788812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ Branch(&done);
5789812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5790812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ bind(&out_of_object);
5791812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
5792812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // Index is equal to negated out of object property index plus 1.
5793812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ Subu(scratch, result, scratch);
5794812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ lw(result, FieldMemOperand(scratch,
5795812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org                                FixedArray::kHeaderSize - kPointerSize));
5796812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  __ bind(&done);
5797812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org}
5798812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5799812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
5800c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#undef __
5801c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5802c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} }  // namespace v8::internal
5803