lithium-x64.cc revision f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3
13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/x64/lithium-x64.h"
6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <sstream>
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_X64
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-osr.h"
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/lithium-inl.h"
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/x64/lithium-codegen-x64.h"
149fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
15086aeeaae12517475c22695a200be45495516549Ben Murdochnamespace v8 {
16086aeeaae12517475c22695a200be45495516549Ben Murdochnamespace internal {
179fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
18b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#define DEFINE_COMPILE(type)                            \
19b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void L##type::CompileToNative(LCodeGen* generator) {  \
20b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    generator->Do##type(this);                          \
21b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
22b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLITHIUM_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE)
23b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#undef DEFINE_COMPILE
24b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
25b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#ifdef DEBUG
271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid LInstruction::VerifyCall() {
28257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Call instructions can use only fixed registers as temporaries and
29257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // outputs because all registers are blocked by the calling convention.
30257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Inputs operands must use a fixed register or use-at-start policy or
31257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // a non-register policy.
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(Output() == NULL ||
331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block         LUnallocated::cast(Output())->HasFixedPolicy() ||
341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block         !LUnallocated::cast(Output())->HasRegisterPolicy());
353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (UseIterator it(this); !it.Done(); it.Advance()) {
363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    LUnallocated* operand = LUnallocated::cast(it.Current());
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(operand->HasFixedPolicy() ||
38257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch           operand->IsUsedAtStart());
391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (TempIterator it(this); !it.Done(); it.Advance()) {
413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    LUnallocated* operand = LUnallocated::cast(it.Current());
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy());
431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif
461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
48b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LInstruction::PrintTo(StringStream* stream) {
49b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add("%s ", this->Mnemonic());
501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  PrintOutputOperandTo(stream);
52b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
53b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  PrintDataTo(stream);
54b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
55b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  if (HasEnvironment()) {
56b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    stream->Add(" ");
57b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    environment()->PrintTo(stream);
58b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
59b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
60b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  if (HasPointerMap()) {
61b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    stream->Add(" ");
62b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    pointer_map()->PrintTo(stream);
63b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
64b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
65b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
66b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LInstruction::PrintDataTo(StringStream* stream) {
68b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add("= ");
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < InputCount(); i++) {
703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (i > 0) stream->Add(" ");
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (InputAt(i) == NULL) {
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      stream->Add("NULL");
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      InputAt(i)->PrintTo(stream);
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
77b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
78b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
79b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LInstruction::PrintOutputOperandTo(StringStream* stream) {
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (HasResult()) result()->PrintTo(stream);
82b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
83b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
84b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
85b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LLabel::PrintDataTo(StringStream* stream) {
86b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  LGap::PrintDataTo(stream);
87b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  LLabel* rep = replacement();
88b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  if (rep != NULL) {
89b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    stream->Add(" Dead block replaced with B%d", rep->block_id());
90b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
91b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
92b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
93b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
94b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochbool LGap::IsRedundant() const {
95b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  for (int i = 0; i < 4; i++) {
96b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) {
97b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      return false;
98b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
99b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
100b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
101b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return true;
102b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
103b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
104b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
105b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LGap::PrintDataTo(StringStream* stream) {
106b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  for (int i = 0; i < 4; i++) {
107b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    stream->Add("(");
108b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if (parallel_moves_[i] != NULL) {
109b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      parallel_moves_[i]->PrintDataTo(stream);
110b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
111b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    stream->Add(") ");
112b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
113b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
114b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
115b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
116b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochconst char* LArithmeticD::Mnemonic() const {
117b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  switch (op()) {
118b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    case Token::ADD: return "add-d";
119b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    case Token::SUB: return "sub-d";
120b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    case Token::MUL: return "mul-d";
121b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    case Token::DIV: return "div-d";
122b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    case Token::MOD: return "mod-d";
123b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    default:
124b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      UNREACHABLE();
125b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      return NULL;
126b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
127b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
128b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
129b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
130b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochconst char* LArithmeticT::Mnemonic() const {
131b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  switch (op()) {
132b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    case Token::ADD: return "add-t";
133b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    case Token::SUB: return "sub-t";
134b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    case Token::MUL: return "mul-t";
135b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    case Token::MOD: return "mod-t";
136b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    case Token::DIV: return "div-t";
1371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    case Token::BIT_AND: return "bit-and-t";
1381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    case Token::BIT_OR: return "bit-or-t";
1391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    case Token::BIT_XOR: return "bit-xor-t";
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::ROR: return "ror-t";
1411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    case Token::SHL: return "sal-t";
1421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    case Token::SAR: return "sar-t";
1431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    case Token::SHR: return "shr-t";
144b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    default:
145b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      UNREACHABLE();
146b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      return NULL;
147b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
148b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
149b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
150b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LGoto::HasInterestingComment(LCodeGen* gen) const {
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return !gen->IsNextEmittedBlock(block_id());
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<int R>
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LTemplateResultInstruction<R>::MustSignExtendResult(
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LPlatformChunk* chunk) const {
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* hvalue = this->hydrogen_value();
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return hvalue != NULL &&
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      hvalue->representation().IsInteger32() &&
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      chunk->GetDehoistedKeyIds()->Contains(hvalue->id());
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
166b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LGoto::PrintDataTo(StringStream* stream) {
167b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add("B%d", block_id());
168b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
169b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
170b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
171b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LBranch::PrintDataTo(StringStream* stream) {
172b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add("B%d | B%d on ", true_block_id(), false_block_id());
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value()->PrintTo(stream);
174b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
175b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
176b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LCompareNumericAndBranch::PrintDataTo(StringStream* stream) {
178b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add("if ");
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  left()->PrintTo(stream);
180b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add(" %s ", Token::String(op()));
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  right()->PrintTo(stream);
182b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
183b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
184b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
185b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LIsStringAndBranch::PrintDataTo(StringStream* stream) {
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  stream->Add("if is_string(");
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value()->PrintTo(stream);
1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
193b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
194b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add("if is_smi(");
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value()->PrintTo(stream);
196b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
197b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
198b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
199b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
200257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid LIsUndetectableAndBranch::PrintDataTo(StringStream* stream) {
201257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  stream->Add("if is_undetectable(");
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value()->PrintTo(stream);
203257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
204257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
205257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
206257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LStringCompareAndBranch::PrintDataTo(StringStream* stream) {
2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  stream->Add("if string_compare(");
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  left()->PrintTo(stream);
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  right()->PrintTo(stream);
2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
215b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
216b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add("if has_instance_type(");
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value()->PrintTo(stream);
218b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
219b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
220b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
221b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
222b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) {
223b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add("if has_cached_array_index(");
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value()->PrintTo(stream);
225b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
226b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
227b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
228b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
229b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
230b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add("if class_of_test(");
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value()->PrintTo(stream);
232b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add(", \"%o\") then B%d else B%d",
233b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch              *hydrogen()->class_name(),
234b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch              true_block_id(),
235b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch              false_block_id());
236b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
237b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
238b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
239b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
240b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add("if typeof ");
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value()->PrintTo(stream);
242b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add(" == \"%s\" then B%d else B%d",
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              hydrogen()->type_literal()->ToCString().get(),
244b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch              true_block_id(), false_block_id());
245b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
246b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
247b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LStoreCodeEntry::PrintDataTo(StringStream* stream) {
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stream->Add(" = ");
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function()->PrintTo(stream);
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stream->Add(".code_entry = ");
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code_object()->PrintTo(stream);
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stream->Add(" = ");
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base_object()->PrintTo(stream);
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stream->Add(" + ");
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  offset()->PrintTo(stream);
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LCallWithDescriptor::PrintDataTo(StringStream* stream) {
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < InputCount(); i++) {
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InputAt(i)->PrintTo(stream);
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stream->Add(" ");
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stream->Add("#%d / ", arity());
270b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
271b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
272b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
273b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LLoadContextSlot::PrintDataTo(StringStream* stream) {
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  context()->PrintTo(stream);
2751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  stream->Add("[%d]", slot_index());
276b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
277b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
278b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
279e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LStoreContextSlot::PrintDataTo(StringStream* stream) {
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  context()->PrintTo(stream);
281e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  stream->Add("[%d] <- ", slot_index());
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  value()->PrintTo(stream);
283e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
284e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
285e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
286257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid LInvokeFunction::PrintDataTo(StringStream* stream) {
287257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  stream->Add("= ");
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function()->PrintTo(stream);
289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  stream->Add(" #%d / ", arity());
290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
291257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
292257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LCallNewArray::PrintDataTo(StringStream* stream) {
294b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add("= ");
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  constructor()->PrintTo(stream);
296b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add(" #%d / ", arity());
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ElementsKind kind = hydrogen()->elements_kind();
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stream->Add(" (%s) ", ElementsKindToString(kind));
299b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
300b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
301b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
302b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
303b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  arguments()->PrintTo(stream);
304b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
305b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add(" length ");
306b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  length()->PrintTo(stream);
307b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
308b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add(" index ");
309b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  index()->PrintTo(stream);
310b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
311b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
312b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint LPlatformChunk::GetNextSpillIndex(RegisterKind kind) {
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kind == DOUBLE_REGISTERS && kDoubleSize == 2 * kPointerSize) {
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Skip a slot if for a double-width slot for x32 port.
316109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    current_frame_slots_++;
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The spill slot's address is at rbp - (index + 1) * kPointerSize -
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // StandardFrameConstants::kFixedFrameSizeFromFp. kFixedFrameSizeFromFp is
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // 2 * kPointerSize, if rbp is aligned at 8-byte boundary, the below "|= 1"
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // will make sure the spilled doubles are aligned at 8-byte boundary.
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(haitao): make sure rbp is aligned at 8-byte boundary for x32 port.
322109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    current_frame_slots_ |= 1;
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
324109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return current_frame_slots_++;
325b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
326b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
327b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) {
329b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // All stack slots are Double stack slots on x64.
330b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // Alternatively, at some point, start using half-size
331b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // stack slots for int32 values.
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int index = GetNextSpillIndex(kind);
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kind == DOUBLE_REGISTERS) {
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return LDoubleStackSlot::Create(index, zone());
335b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  } else {
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(kind == GENERAL_REGISTERS);
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return LStackSlot::Create(index, zone());
338b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
339b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
340b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
341b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
342e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LStoreNamedField::PrintDataTo(StringStream* stream) {
343e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  object()->PrintTo(stream);
344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  std::ostringstream os;
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os << hydrogen()->access() << " <- ";
346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  stream->Add(os.str().c_str());
347e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  value()->PrintTo(stream);
348e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
349e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
350e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LLoadKeyed::PrintDataTo(StringStream* stream) {
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  elements()->PrintTo(stream);
353e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  stream->Add("[");
354e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  key()->PrintTo(stream);
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (hydrogen()->IsDehoisted()) {
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stream->Add(" + %d]", base_offset());
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stream->Add("]");
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
360e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
361e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
362e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LStoreKeyed::PrintDataTo(StringStream* stream) {
3643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  elements()->PrintTo(stream);
3653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  stream->Add("[");
3663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  key()->PrintTo(stream);
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (hydrogen()->IsDehoisted()) {
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stream->Add(" + %d] <-", base_offset());
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stream->Add("] <- ");
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (value() == NULL) {
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(hydrogen()->IsConstantHoleStore() &&
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           hydrogen()->value()->representation().IsDouble());
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stream->Add("<the hole(nan)>");
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value()->PrintTo(stream);
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
3813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LTransitionElementsKind::PrintDataTo(StringStream* stream) {
3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  object()->PrintTo(stream);
3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  stream->Add(" %p -> %p", *original_map(), *transitioned_map());
3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLPlatformChunk* LChunkBuilder::Build() {
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_unused());
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  chunk_ = new(zone()) LPlatformChunk(info(), graph());
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LPhase phase("L_Building chunk", chunk_);
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  status_ = BUILDING;
394b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If compiling for OSR, reserve space for the unoptimized frame,
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // which will be subsumed into this frame.
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (graph()->has_osr()) {
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) {
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      chunk_->GetNextSpillIndex(GENERAL_REGISTERS);
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
402b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
403086aeeaae12517475c22695a200be45495516549Ben Murdoch  const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
404086aeeaae12517475c22695a200be45495516549Ben Murdoch  for (int i = 0; i < blocks->length(); i++) {
405086aeeaae12517475c22695a200be45495516549Ben Murdoch    HBasicBlock* next = NULL;
406086aeeaae12517475c22695a200be45495516549Ben Murdoch    if (i < blocks->length() - 1) next = blocks->at(i + 1);
407086aeeaae12517475c22695a200be45495516549Ben Murdoch    DoBasicBlock(blocks->at(i), next);
408086aeeaae12517475c22695a200be45495516549Ben Murdoch    if (is_aborted()) return NULL;
409086aeeaae12517475c22695a200be45495516549Ben Murdoch  }
410086aeeaae12517475c22695a200be45495516549Ben Murdoch  status_ = DONE;
411086aeeaae12517475c22695a200be45495516549Ben Murdoch  return chunk_;
4129fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block}
4139fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
4149fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
415b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new (zone()) LUnallocated(LUnallocated::FIXED_REGISTER, reg.code());
417b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
418b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
419b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
420b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLUnallocated* LChunkBuilder::ToUnallocated(XMMRegister reg) {
421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new (zone())
422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER, reg.code());
423b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
424b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
425b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
426b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) {
427b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return Use(value, ToUnallocated(fixed_register));
428b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
429b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
430b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
431b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::UseFixedDouble(HValue* value, XMMRegister reg) {
432b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return Use(value, ToUnallocated(reg));
433b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
434b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
435b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
436b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::UseRegister(HValue* value) {
4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Use(value, new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
438b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
439b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
440b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
441b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::UseRegisterAtStart(HValue* value) {
442b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return Use(value,
4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch             new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER,
444b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                              LUnallocated::USED_AT_START));
445b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
446b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
447b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
448b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::UseTempRegister(HValue* value) {
4493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Use(value, new(zone()) LUnallocated(LUnallocated::WRITABLE_REGISTER));
450b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
451b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
452b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLOperand* LChunkBuilder::UseTempRegisterOrConstant(HValue* value) {
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return value->IsConstant()
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ? chunk_->DefineConstantOperand(HConstant::cast(value))
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : UseTempRegister(value);
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
460b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::Use(HValue* value) {
4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Use(value, new(zone()) LUnallocated(LUnallocated::NONE));
462b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
463b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
464b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
465b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::UseAtStart(HValue* value) {
4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Use(value, new(zone()) LUnallocated(LUnallocated::NONE,
467b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                                     LUnallocated::USED_AT_START));
468b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
469b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
470b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
471b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::UseOrConstant(HValue* value) {
472b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return value->IsConstant()
473b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      ? chunk_->DefineConstantOperand(HConstant::cast(value))
474b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      : Use(value);
475b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
476b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
477b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
478b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::UseOrConstantAtStart(HValue* value) {
479b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return value->IsConstant()
480b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      ? chunk_->DefineConstantOperand(HConstant::cast(value))
481b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      : UseAtStart(value);
482b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
483b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
484b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
485b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::UseRegisterOrConstant(HValue* value) {
486b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return value->IsConstant()
487b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      ? chunk_->DefineConstantOperand(HConstant::cast(value))
488b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      : UseRegister(value);
489b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
490b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
491b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
492b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) {
493b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return value->IsConstant()
494b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      ? chunk_->DefineConstantOperand(HConstant::cast(value))
495b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      : UseRegisterAtStart(value);
496b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
497b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
498b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLOperand* LChunkBuilder::UseConstant(HValue* value) {
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return chunk_->DefineConstantOperand(HConstant::cast(value));
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
504b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::UseAny(HValue* value) {
505b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return value->IsConstant()
506b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      ? chunk_->DefineConstantOperand(HConstant::cast(value))
5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      :  Use(value, new(zone()) LUnallocated(LUnallocated::ANY));
508b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
509b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
510b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
511b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) {
512b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  if (value->EmitAtUses()) {
513b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    HInstruction* instr = HInstruction::cast(value);
514b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    VisitInstruction(instr);
515b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  operand->set_virtual_register(value->id());
517b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return operand;
518b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
519b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
520b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::Define(LTemplateResultInstruction<1>* instr,
522b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                                    LUnallocated* result) {
5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  result->set_virtual_register(current_instruction_->id());
524b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  instr->set_result(result);
525b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return instr;
526b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
527b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
528b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
529b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DefineAsRegister(
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LTemplateResultInstruction<1>* instr) {
5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Define(instr,
5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
533b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
534b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
535b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
536b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DefineAsSpilled(
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LTemplateResultInstruction<1>* instr,
538b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    int index) {
5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Define(instr,
5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                new(zone()) LUnallocated(LUnallocated::FIXED_SLOT, index));
541b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
542b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
543b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
544b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DefineSameAsFirst(
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LTemplateResultInstruction<1>* instr) {
5463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Define(instr,
5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                new(zone()) LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT));
548b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
549b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
550b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DefineFixed(LTemplateResultInstruction<1>* instr,
552b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                                         Register reg) {
553b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return Define(instr, ToUnallocated(reg));
554b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
555b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
556b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
557b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DefineFixedDouble(
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LTemplateResultInstruction<1>* instr,
559b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    XMMRegister reg) {
560b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return Define(instr, ToUnallocated(reg));
561b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
562b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
563b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
564b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
565b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  HEnvironment* hydrogen_env = current_block_->last_environment();
5663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return LChunkBuilderBase::AssignEnvironment(instr, hydrogen_env);
567b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
568b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
569b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
570b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
571b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                                        HInstruction* hinstr,
572b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                                        CanDeoptimize can_deoptimize) {
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  info()->MarkAsNonDeferredCalling();
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#ifdef DEBUG
5761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  instr->VerifyCall();
5771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif
5781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  instr->MarkAsCall();
579b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  instr = AssignPointerMap(instr);
580b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
581b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // If instruction does not have side-effects lazy deoptimization
582b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // after the call will try to deoptimize to the point before the call.
583b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // Thus we still need to attach environment to this call even if
584b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // call sequence can not deoptimize eagerly.
585b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  bool needs_environment =
5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) ||
5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      !hinstr->HasObservableSideEffects();
588b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  if (needs_environment && !instr->HasEnvironment()) {
589b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    instr = AssignEnvironment(instr);
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We can't really figure out if the environment is needed or not.
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->environment()->set_has_been_used();
592b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
593b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
594b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return instr;
595b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
596b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
597b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
598b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!instr->HasPointerMap());
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  instr->set_pointer_map(new(zone()) LPointerMap(zone()));
601b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return instr;
602b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
603b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
604b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
605b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLUnallocated* LChunkBuilder::TempRegister() {
6063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LUnallocated* operand =
6073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER);
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int vreg = allocator_->GetVirtualRegister();
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocator_->AllocationOk()) {
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister);
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    vreg = 0;
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  operand->set_virtual_register(vreg);
614b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return operand;
615b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
616b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
617b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
618b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::FixedTemp(Register reg) {
619b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  LUnallocated* operand = ToUnallocated(reg);
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(operand->HasFixedPolicy());
621b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return operand;
622b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
623b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
624b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
625b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLOperand* LChunkBuilder::FixedTemp(XMMRegister reg) {
626b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  LUnallocated* operand = ToUnallocated(reg);
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(operand->HasFixedPolicy());
628b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return operand;
629b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
630b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
631b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
632b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return new(zone()) LLabel(instr->block());
634b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
635b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
636b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value())));
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
6453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
6463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
6473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
648b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
6493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return AssignEnvironment(new(zone()) LDeoptimize);
650b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
651b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
652b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
6531e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockLInstruction* LChunkBuilder::DoShift(Token::Value op,
6541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                                     HBitwiseBinaryOperation* instr) {
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->representation().IsSmiOrInteger32()) {
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->left()->representation().Equals(instr->representation()));
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->right()->representation().Equals(instr->representation()));
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* left = UseRegisterAtStart(instr->left());
6591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* right_value = instr->right();
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* right = NULL;
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int constant_value = 0;
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool does_deopt = false;
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (right_value->IsConstant()) {
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HConstant* constant = HConstant::cast(right_value);
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      right = chunk_->DefineConstantOperand(constant);
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      constant_value = constant->Integer32Value() & 0x1f;
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (SmiValuesAre31Bits() && instr->representation().IsSmi() &&
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          constant_value > 0) {
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Left shift can deoptimize if we shift by > 0 and the result
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // cannot be truncated to smi.
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi);
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      right = UseFixed(right_value, rcx);
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Shift operations can only deoptimize if we do a logical shift by 0 and
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the result cannot be truncated to int32.
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (op == Token::SHR && constant_value == 0) {
681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
6821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
6831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LInstruction* result =
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt));
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return does_deopt ? AssignEnvironment(result) : result;
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DoArithmeticT(op, instr);
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
690b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
691b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
692b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
693b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
694b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                                           HArithmeticBinaryOperation* instr) {
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->representation().IsDouble());
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->left()->representation().IsDouble());
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->right()->representation().IsDouble());
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (op == Token::MOD) {
69913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    LOperand* left = UseFixedDouble(instr->BetterLeftOperand(), xmm0);
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* right = UseFixedDouble(instr->BetterRightOperand(), xmm1);
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
70213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return MarkAsCall(DefineFixedDouble(result, xmm0), instr);
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return CpuFeatures::IsSupported(AVX) ? DefineAsRegister(result)
708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         : DefineSameAsFirst(result);
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
710b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
711b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
712b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
713b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           HBinaryOperation* instr) {
715b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  HValue* left = instr->left();
716b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  HValue* right = instr->right();
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(left->representation().IsTagged());
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(right->representation().IsTagged());
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
720b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  LOperand* left_operand = UseFixed(left, rdx);
721b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  LOperand* right_operand = UseFixed(right, rax);
7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LArithmeticT* result =
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new(zone()) LArithmeticT(op, context, left_operand, right_operand);
724b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return MarkAsCall(DefineFixed(result, rax), instr);
725b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
726b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
727b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
728b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_building());
730b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  current_block_ = block;
731b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  next_block_ = next_block;
732b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  if (block->IsStartBlock()) {
733b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    block->UpdateEnvironment(graph_->start_environment());
734b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    argument_count_ = 0;
735b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  } else if (block->predecessors()->length() == 1) {
736b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    // We have a single predecessor => copy environment and outgoing
737b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    // argument count from the predecessor.
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(block->phis()->length() == 0);
739b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    HBasicBlock* pred = block->predecessors()->at(0);
740b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    HEnvironment* last_environment = pred->last_environment();
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(last_environment != NULL);
742b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    // Only copy the environment, if it is later used again.
743b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if (pred->end()->SecondSuccessor() == NULL) {
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(pred->end()->FirstSuccessor() == block);
745b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    } else {
746b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      if (pred->end()->FirstSuccessor()->block_id() > block->block_id() ||
747b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch          pred->end()->SecondSuccessor()->block_id() > block->block_id()) {
748b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        last_environment = last_environment->Copy();
749b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      }
750b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
751b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    block->UpdateEnvironment(last_environment);
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(pred->argument_count() >= 0);
753b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    argument_count_ = pred->argument_count();
754b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  } else {
755b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    // We are at a state join => process phis.
756b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    HBasicBlock* pred = block->predecessors()->at(0);
757b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    // No need to copy the environment, it cannot be used later.
758b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    HEnvironment* last_environment = pred->last_environment();
759b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    for (int i = 0; i < block->phis()->length(); ++i) {
760b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      HPhi* phi = block->phis()->at(i);
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (phi->HasMergedIndex()) {
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        last_environment->SetValueAt(phi->merged_index(), phi);
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
764b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
765b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    for (int i = 0; i < block->deleted_phis()->length(); ++i) {
766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (block->deleted_phis()->at(i) < last_environment->length()) {
767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        last_environment->SetValueAt(block->deleted_phis()->at(i),
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     graph_->GetConstantUndefined());
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
770b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
771b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    block->UpdateEnvironment(last_environment);
772b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    // Pick up the outgoing argument count of one of the predecessors.
773b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    argument_count_ = pred->argument_count();
774b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
775b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  HInstruction* current = block->first();
776b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int start = chunk_->instructions()->length();
777b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  while (current != NULL && !is_aborted()) {
778b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    // Code for constants in registers is generated lazily.
779b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if (!current->EmitAtUses()) {
780b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      VisitInstruction(current);
781b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
782b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    current = current->next();
783b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
784b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int end = chunk_->instructions()->length() - 1;
785b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  if (end >= start) {
786b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    block->set_first_instruction_index(start);
787b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    block->set_last_instruction_index(end);
788b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
789b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  block->set_argument_count(argument_count_);
790b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  next_block_ = NULL;
791b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  current_block_ = NULL;
792b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
793b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
794b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
795b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LChunkBuilder::VisitInstruction(HInstruction* current) {
796b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  HInstruction* old_current = current_instruction_;
797b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  current_instruction_ = current;
798b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* instr = NULL;
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (current->CanReplaceWithDummyUses()) {
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (current->OperandCount() == 0) {
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr = DefineAsRegister(new(zone()) LDummy());
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!current->OperandAt(0)->IsControlInstruction());
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr = DefineAsRegister(new(zone())
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          LDummyUse(UseAny(current->OperandAt(0))));
807b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 1; i < current->OperandCount(); ++i) {
809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (current->OperandAt(i)->IsControlInstruction()) continue;
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LInstruction* dummy =
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          new(zone()) LDummyUse(UseAny(current->OperandAt(i)));
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      dummy->set_hydrogen_value(current);
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      chunk_->AddInstruction(dummy, current_block_);
814b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* successor;
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (current->IsControlInstruction() &&
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) &&
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        successor != NULL) {
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr = new(zone()) LGoto(successor);
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr = current->CompileToLithium(this);
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  argument_count_ += current->argument_delta();
827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(argument_count_ >= 0);
828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr != NULL) {
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddInstruction(instr, current);
831b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
833b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  current_instruction_ = old_current;
834b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
835b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
836b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LChunkBuilder::AddInstruction(LInstruction* instr,
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   HInstruction* hydrogen_val) {
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Associate the hydrogen instruction first, since we may need it for
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the ClobbersRegisters() or ClobbersDoubleRegisters() calls below.
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  instr->set_hydrogen_value(hydrogen_val);
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if DEBUG
844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Make sure that the lithium instruction has either no fixed register
845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // constraints in temps or the result OR no uses that are only used at
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // start. If this invariant doesn't hold, the register allocator can decide
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to insert a split of a range immediately before the instruction due to an
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // already allocated register needing to be used for the instruction's fixed
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // register constraint. In this case, The register allocator won't see an
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // interference between the split child and the use-at-start (it would if
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the it was just a plain use), so it is free to move the split child into
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the same register that is used for the use-at-start.
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // See https://code.google.com/p/chromium/issues/detail?id=201590
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!(instr->ClobbersRegisters() &&
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        instr->ClobbersDoubleRegisters(isolate()))) {
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int fixed = 0;
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int used_at_start = 0;
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (UseIterator it(instr); !it.Done(); it.Advance()) {
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LUnallocated* operand = LUnallocated::cast(it.Current());
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (operand->IsUsedAtStart()) ++used_at_start;
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (instr->Output() != NULL) {
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed;
864b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TempIterator it(instr); !it.Done(); it.Advance()) {
866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LUnallocated* operand = LUnallocated::cast(it.Current());
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (operand->HasFixedPolicy()) ++fixed;
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(fixed == 0 || used_at_start == 0);
870b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
872b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr = AssignPointerMap(instr);
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_stress_environments && !instr->HasEnvironment()) {
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr = AssignEnvironment(instr);
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  chunk_->AddInstruction(instr, current_block_);
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CreateLazyBailoutForCall(current_block_, instr, hydrogen_val);
882b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
883b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
884b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
885b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new(zone()) LGoto(instr->FirstSuccessor());
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLInstruction* LChunkBuilder::DoPrologue(HPrologue* instr) {
8913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  LInstruction* result = new (zone()) LPrologue();
892f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (info_->scope()->NeedsContext()) {
8933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    result = MarkAsCall(result, instr);
8943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
8953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return result;
896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) {
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new(zone()) LDebugBreak();
901b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
902b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
903b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
9043fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
9053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HValue* value = instr->value();
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation r = value->representation();
9073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HType type = value->type();
9083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  ToBooleanICStub::Types expected = instr->expected_input_types();
9093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic();
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() ||
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      type.IsJSArray() || type.IsHeapNumber() || type.IsString();
913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* branch = new(zone()) LBranch(UseRegister(value));
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!easy_case &&
9153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ((!expected.Contains(ToBooleanICStub::SMI) && expected.NeedsMap()) ||
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       !expected.IsGeneric())) {
917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    branch = AssignEnvironment(branch);
9183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return branch;
920b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
921b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
922b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
9231e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockLInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->value()->representation().IsTagged());
9251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* value = UseRegisterAtStart(instr->value());
9263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return new(zone()) LCmpMapAndBranch(value);
927b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
928b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
929b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
930b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) {
931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  info()->MarkAsRequiresFrame();
9323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return DefineAsRegister(new(zone()) LArgumentsLength(Use(length->value())));
933b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
934b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
935b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
936b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  info()->MarkAsRequiresFrame();
9383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return DefineAsRegister(new(zone()) LArgumentsElements);
939b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
940b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
941b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLInstruction* LChunkBuilder::DoHasInPrototypeChainAndBranch(
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    HHasInPrototypeChainAndBranch* instr) {
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LOperand* object = UseRegister(instr->object());
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LOperand* prototype = UseRegister(instr->prototype());
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LHasInPrototypeChainAndBranch* result =
947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      new (zone()) LHasInPrototypeChainAndBranch(object, prototype);
948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return AssignEnvironment(result);
949b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
950b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
951b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
9523ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
9533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* receiver = UseRegister(instr->receiver());
9543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* function = UseRegisterAtStart(instr->function());
9553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function);
9563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return AssignEnvironment(DefineSameAsFirst(result));
9573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
9583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
960b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
961e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  LOperand* function = UseFixed(instr->function(), rdi);
962e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  LOperand* receiver = UseFixed(instr->receiver(), rax);
963e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  LOperand* length = UseFixed(instr->length(), rbx);
964e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  LOperand* elements = UseFixed(instr->elements(), rcx);
9653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LApplyArguments* result = new(zone()) LApplyArguments(function,
966e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                                receiver,
967e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                                length,
968e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                                elements);
969e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY);
970b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
971b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
972b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) {
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int argc = instr->OperandCount();
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < argc; ++i) {
976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* argument = UseOrConstant(instr->argument(i));
977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddInstruction(new(zone()) LPushArgument(argument), instr);
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoStoreCodeEntry(
984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HStoreCodeEntry* store_code_entry) {
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* function = UseRegister(store_code_entry->function());
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* code_object = UseTempRegister(store_code_entry->code_object());
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new(zone()) LStoreCodeEntry(function, code_object);
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoInnerAllocatedObject(
992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HInnerAllocatedObject* instr) {
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* base_object = UseRegisterAtStart(instr->base_object());
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* offset = UseRegisterOrConstantAtStart(instr->offset());
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DefineAsRegister(
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new(zone()) LInnerAllocatedObject(base_object, offset));
9971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
9981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
9991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
10003fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
10013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return instr->HasNoUses()
10023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ? NULL
10033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : DefineAsRegister(new(zone()) LThisFunction);
10043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
10053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
10063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
10071e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockLInstruction* LChunkBuilder::DoContext(HContext* instr) {
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->HasNoUses()) return NULL;
10091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (info()->IsStub()) {
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DefineFixed(new(zone()) LContext, rsi);
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
10131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DefineAsRegister(new(zone()) LContext);
10153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10183ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return MarkAsCall(new(zone()) LDeclareGlobals(context), instr);
1021b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1022b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1023b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoCallWithDescriptor(
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HCallWithDescriptor* instr) {
1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallInterfaceDescriptor descriptor = instr->descriptor();
1027f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK_EQ(descriptor.GetParameterCount() +
1028f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                LCallWithDescriptor::kImplicitRegisterParameterCount,
1029f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            instr->OperandCount());
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* target = UseRegisterOrConstantAtStart(instr->target());
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<LOperand*> ops(instr->OperandCount(), zone());
1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Target
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ops.Add(target, zone());
1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Context
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LOperand* op = UseFixed(instr->OperandAt(1), rsi);
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ops.Add(op, zone());
1038f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Load register parameters.
1039f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int i = 0;
1040f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (; i < descriptor.GetRegisterParameterCount(); i++) {
1041f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    op = UseFixed(instr->OperandAt(
1042f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                      i + LCallWithDescriptor::kImplicitRegisterParameterCount),
1043f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  descriptor.GetRegisterParameter(i));
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ops.Add(op, zone());
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1046f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Push stack parameters.
1047f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (; i < descriptor.GetParameterCount(); i++) {
1048f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    op = UseAny(instr->OperandAt(
1049f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        i + LCallWithDescriptor::kImplicitRegisterParameterCount));
1050f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AddInstruction(new (zone()) LPushArgument(op), instr);
1051f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LCallWithDescriptor* result = new(zone()) LCallWithDescriptor(
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      descriptor, ops, zone());
10553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (instr->syntactic_tail_call_mode() == TailCallMode::kAllow) {
10563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    result->MarkAsSyntacticTailCall();
10573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return MarkAsCall(DefineFixed(result, rax), instr);
1059b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1060b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1061b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1062257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochLInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
1064257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  LOperand* function = UseFixed(instr->function(), rdi);
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInvokeFunction* result = new(zone()) LInvokeFunction(context, function);
10663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (instr->syntactic_tail_call_mode() == TailCallMode::kAllow) {
10673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    result->MarkAsSyntacticTailCall();
10683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1069257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return MarkAsCall(DefineFixed(result, rax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1070257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1071257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1072257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1073b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (instr->op()) {
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kMathFloor:
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoMathFloor(instr);
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kMathRound:
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoMathRound(instr);
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kMathFround:
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoMathFround(instr);
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kMathAbs:
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoMathAbs(instr);
108313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kMathCos:
108413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return DoMathCos(instr);
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kMathLog:
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoMathLog(instr);
1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kMathExp:
1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoMathExp(instr);
108913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kMathSin:
109013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return DoMathSin(instr);
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kMathSqrt:
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoMathSqrt(instr);
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kMathPowHalf:
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoMathPowHalf(instr);
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kMathClz32:
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoMathClz32(instr);
1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NULL;
1100e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1101b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1102b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) {
11043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(instr->value()->representation().IsDouble());
1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* input = UseRegisterAtStart(instr->value());
11063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (instr->representation().IsInteger32()) {
11073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    LMathFloorI* result = new (zone()) LMathFloorI(input);
11083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
11093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
11103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK(instr->representation().IsDouble());
11113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    LMathFloorD* result = new (zone()) LMathFloorD(input);
11123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return DefineAsRegister(result);
11133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1114b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1115b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) {
11173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(instr->value()->representation().IsDouble());
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* input = UseRegister(instr->value());
11193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (instr->representation().IsInteger32()) {
11203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    LOperand* temp = FixedTemp(xmm4);
11213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    LMathRoundI* result = new (zone()) LMathRoundI(input, temp);
11223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
11233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
11243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK(instr->representation().IsDouble());
11253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    LMathRoundD* result = new (zone()) LMathRoundD(input);
11263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return DefineAsRegister(result);
11273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1128b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1129b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoMathFround(HUnaryMathOperation* instr) {
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* input = UseRegister(instr->value());
1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LMathFround* result = new (zone()) LMathFround(input);
1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DefineAsRegister(result);
1134b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1135b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1136b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseAny(instr->context());
1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* input = UseRegisterAtStart(instr->value());
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result =
1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DefineSameAsFirst(new(zone()) LMathAbs(context, input));
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation r = instr->value()->representation();
1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result);
1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!r.IsDouble()) result = AssignEnvironment(result);
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
1146b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1147b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1148b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->representation().IsDouble());
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->value()->representation().IsDouble());
115213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  LOperand* input = UseFixedDouble(instr->value(), xmm0);
115313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return MarkAsCall(DefineFixedDouble(new (zone()) LMathLog(input), xmm0),
115413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                    instr);
1155b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1156b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1157b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) {
1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* input = UseRegisterAtStart(instr->value());
1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LMathClz32* result = new(zone()) LMathClz32(input);
1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DefineAsRegister(result);
1162b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1163b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
116413e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochLInstruction* LChunkBuilder::DoMathCos(HUnaryMathOperation* instr) {
116513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(instr->representation().IsDouble());
116613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(instr->value()->representation().IsDouble());
116713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  LOperand* input = UseFixedDouble(instr->value(), xmm0);
116813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return MarkAsCall(DefineFixedDouble(new (zone()) LMathCos(input), xmm0),
116913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                    instr);
117013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
1171b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->representation().IsDouble());
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->value()->representation().IsDouble());
117513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  LOperand* input = UseFixedDouble(instr->value(), xmm0);
117613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return MarkAsCall(DefineFixedDouble(new (zone()) LMathExp(input), xmm0),
117713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                    instr);
1178b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1179b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
118013e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochLInstruction* LChunkBuilder::DoMathSin(HUnaryMathOperation* instr) {
118113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(instr->representation().IsDouble());
118213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(instr->value()->representation().IsDouble());
118313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  LOperand* input = UseFixedDouble(instr->value(), xmm0);
118413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return MarkAsCall(DefineFixedDouble(new (zone()) LMathSin(input), xmm0),
118513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                    instr);
118613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
1187b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) {
1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* input = UseAtStart(instr->value());
1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DefineAsRegister(new(zone()) LMathSqrt(input));
1191b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1192b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1193b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) {
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* input = UseRegisterAtStart(instr->value());
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LMathPowHalf* result = new(zone()) LMathPowHalf(input);
1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DefineSameAsFirst(result);
1198b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1199b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1200b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* constructor = UseFixed(instr->constructor(), rdi);
1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LCallNewArray* result = new(zone()) LCallNewArray(context, constructor);
1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return MarkAsCall(DefineFixed(result, rax), instr);
1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
12073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
12083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LCallRuntime* result = new(zone()) LCallRuntime(context);
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return MarkAsCall(DefineFixed(result, rax), instr);
1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoRor(HRor* instr) {
1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DoShift(Token::ROR, instr);
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoShr(HShr* instr) {
1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DoShift(Token::SHR, instr);
1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoSar(HSar* instr) {
1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DoShift(Token::SAR, instr);
1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoShl(HShl* instr) {
1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DoShift(Token::SHL, instr);
1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->representation().IsSmiOrInteger32()) {
1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->left()->representation().Equals(instr->representation()));
1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->right()->representation().Equals(instr->representation()));
1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->CheckFlag(HValue::kTruncatingToInt32));
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LOperand* right;
1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (SmiValuesAre32Bits() && instr->representation().IsSmi()) {
1245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // We don't support tagged immediates, so we request it in a register.
1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      right = UseRegisterAtStart(instr->BetterRightOperand());
1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      right = UseOrConstantAtStart(instr->BetterRightOperand());
1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DefineSameAsFirst(new(zone()) LBitI(left, right));
1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DoArithmeticT(instr->op(), instr);
12533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1254b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1255b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1256b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) {
1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->representation().IsSmiOrInteger32());
1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->left()->representation().Equals(instr->representation()));
1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->right()->representation().Equals(instr->representation()));
1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* dividend = UseRegister(instr->left());
1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t divisor = instr->right()->GetInteger32Constant();
1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I(
1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          dividend, divisor));
1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       divisor != 1 && divisor != -1)) {
1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->representation().IsInteger32());
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->left()->representation().Equals(instr->representation()));
1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->right()->representation().Equals(instr->representation()));
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* dividend = UseRegister(instr->left());
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t divisor = instr->right()->GetInteger32Constant();
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* temp1 = FixedTemp(rax);
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* temp2 = FixedTemp(rdx);
1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = DefineFixed(new(zone()) LDivByConstI(
1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          dividend, divisor, temp1, temp2), rdx);
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (divisor == 0 ||
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->representation().IsSmiOrInteger32());
1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->left()->representation().Equals(instr->representation()));
1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->right()->representation().Equals(instr->representation()));
1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* dividend = UseFixed(instr->left(), rax);
1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* divisor = UseRegister(instr->right());
1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* temp = FixedTemp(rdx);
1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = DefineFixed(new(zone()) LDivI(
1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          dividend, divisor, temp), rax);
1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr->CheckFlag(HValue::kCanOverflow) ||
1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
1310b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1311b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1312b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1313b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->representation().IsSmiOrInteger32()) {
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (instr->RightIsPowerOf2()) {
1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoDivByPowerOf2I(instr);
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (instr->right()->IsConstant()) {
1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoDivByConstI(instr);
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoDivI(instr);
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (instr->representation().IsDouble()) {
13231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return DoArithmeticD(Token::DIV, instr);
13241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else {
13251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return DoArithmeticT(Token::DIV, instr);
13261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
1327b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1328b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1329b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) {
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* dividend = UseRegisterAtStart(instr->left());
1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t divisor = instr->right()->GetInteger32Constant();
1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = DefineSameAsFirst(new(zone()) LFlooringDivByPowerOf2I(
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          dividend, divisor));
1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) {
1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->representation().IsInteger32());
1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->left()->representation().Equals(instr->representation()));
1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->right()->representation().Equals(instr->representation()));
1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* dividend = UseRegister(instr->left());
1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t divisor = instr->right()->GetInteger32Constant();
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* temp1 = FixedTemp(rax);
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* temp2 = FixedTemp(rdx);
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* temp3 =
1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ?
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      NULL : TempRegister();
1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result =
1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DefineFixed(new(zone()) LFlooringDivByConstI(dividend,
1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                   divisor,
1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                   temp1,
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                   temp2,
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                   temp3),
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  rdx);
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (divisor == 0 ||
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->representation().IsSmiOrInteger32());
1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->left()->representation().Equals(instr->representation()));
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->right()->representation().Equals(instr->representation()));
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* dividend = UseFixed(instr->left(), rax);
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* divisor = UseRegister(instr->right());
1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* temp = FixedTemp(rdx);
1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = DefineFixed(new(zone()) LFlooringDivI(
1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          dividend, divisor, temp), rax);
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr->CheckFlag(HValue::kCanOverflow)) {
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->RightIsPowerOf2()) {
1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DoFlooringDivByPowerOf2I(instr);
1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (instr->right()->IsConstant()) {
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DoFlooringDivByConstI(instr);
1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DoFlooringDivI(instr);
1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) {
1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->representation().IsSmiOrInteger32());
1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->left()->representation().Equals(instr->representation()));
1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->right()->representation().Equals(instr->representation()));
1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* dividend = UseRegisterAtStart(instr->left());
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t divisor = instr->right()->GetInteger32Constant();
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I(
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          dividend, divisor));
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->CheckFlag(HValue::kLeftCanBeNegative) &&
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoModByConstI(HMod* instr) {
1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->representation().IsSmiOrInteger32());
1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->left()->representation().Equals(instr->representation()));
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->right()->representation().Equals(instr->representation()));
1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* dividend = UseRegister(instr->left());
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t divisor = instr->right()->GetInteger32Constant();
1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* temp1 = FixedTemp(rax);
1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* temp2 = FixedTemp(rdx);
1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = DefineFixed(new(zone()) LModByConstI(
1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          dividend, divisor, temp1, temp2), rax);
1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoModI(HMod* instr) {
1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->representation().IsSmiOrInteger32());
1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->left()->representation().Equals(instr->representation()));
1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->right()->representation().Equals(instr->representation()));
1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* dividend = UseFixed(instr->left(), rax);
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* divisor = UseRegister(instr->right());
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* temp = FixedTemp(rdx);
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = DefineFixed(new(zone()) LModI(
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          dividend, divisor, temp), rdx);
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1449b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoMod(HMod* instr) {
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->representation().IsSmiOrInteger32()) {
1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (instr->RightIsPowerOf2()) {
1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoModByPowerOf2I(instr);
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (instr->right()->IsConstant()) {
1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoModByConstI(instr);
145544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    } else {
1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DoModI(instr);
145744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (instr->representation().IsDouble()) {
1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DoArithmeticD(Token::MOD, instr);
1460e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  } else {
1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DoArithmeticT(Token::MOD, instr);
1462e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1463b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1464b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1465b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1466b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoMul(HMul* instr) {
1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->representation().IsSmiOrInteger32()) {
1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->left()->representation().Equals(instr->representation()));
1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->right()->representation().Equals(instr->representation()));
1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1471109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    HValue* h_right = instr->BetterRightOperand();
1472109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LOperand* right = UseOrConstant(h_right);
14733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LMulI* mul = new(zone()) LMulI(left, right);
1474109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    int constant_value =
1475109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        h_right->IsConstant() ? HConstant::cast(h_right)->Integer32Value() : 0;
1476109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // |needs_environment| must mirror the cases where LCodeGen::DoMulI calls
1477109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // |DeoptimizeIf|.
1478109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    bool needs_environment =
1479109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        instr->CheckFlag(HValue::kCanOverflow) ||
1480109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
1481109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         (!right->IsConstantOperand() || constant_value <= 0));
1482109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (needs_environment) {
14833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      AssignEnvironment(mul);
14843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
14853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return DefineSameAsFirst(mul);
14861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else if (instr->representation().IsDouble()) {
14871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return DoArithmeticD(Token::MUL, instr);
14881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else {
14891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return DoArithmeticT(Token::MUL, instr);
14901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
1491b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1492b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1493b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1494b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoSub(HSub* instr) {
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->representation().IsSmiOrInteger32()) {
1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->left()->representation().Equals(instr->representation()));
1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->right()->representation().Equals(instr->representation()));
14981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    LOperand* left = UseRegisterAtStart(instr->left());
1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LOperand* right;
1500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (SmiValuesAre32Bits() && instr->representation().IsSmi()) {
1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // We don't support tagged immediates, so we request it in a register.
1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      right = UseRegisterAtStart(instr->right());
1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      right = UseOrConstantAtStart(instr->right());
1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
15063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LSubI* sub = new(zone()) LSubI(left, right);
15071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    LInstruction* result = DefineSameAsFirst(sub);
15081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    if (instr->CheckFlag(HValue::kCanOverflow)) {
15091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      result = AssignEnvironment(result);
15101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
15111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return result;
15121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else if (instr->representation().IsDouble()) {
15131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return DoArithmeticD(Token::SUB, instr);
15141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else {
15151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return DoArithmeticT(Token::SUB, instr);
15161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
1517b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1518b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1519b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1520b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->representation().IsSmiOrInteger32()) {
1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Check to see if it would be advantageous to use an lea instruction rather
1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // than an add. This is the case when no overflow check is needed and there
1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // are multiple uses of the add's inputs, so using a 3-register add will
1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // preserve all input values for later uses.
1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool use_lea = LAddI::UseLea(instr);
1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->left()->representation().Equals(instr->representation()));
1528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->right()->representation().Equals(instr->representation()));
1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* right_candidate = instr->BetterRightOperand();
1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* right;
1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (SmiValuesAre32Bits() && instr->representation().IsSmi()) {
1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // We cannot add a tagged immediate to a tagged value,
1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // so we request it in a register.
1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      right = UseRegisterAtStart(right_candidate);
1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      right = use_lea ? UseRegisterOrConstantAtStart(right_candidate)
1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      : UseOrConstantAtStart(right_candidate);
1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
15403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LAddI* add = new(zone()) LAddI(left, right);
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LInstruction* result = use_lea ? DefineAsRegister(add)
1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   : DefineSameAsFirst(add);
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (can_overflow) {
1545b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      result = AssignEnvironment(result);
1546b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
1547b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    return result;
1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (instr->representation().IsExternal()) {
1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(instr->IsConsistentExternalRepresentation());
1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool use_lea = LAddI::UseLea(instr);
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* left = UseRegisterAtStart(instr->left());
1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* right_candidate = instr->right();
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* right = use_lea
1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ? UseRegisterOrConstantAtStart(right_candidate)
1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : UseOrConstantAtStart(right_candidate);
1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LAddI* add = new(zone()) LAddI(left, right);
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LInstruction* result = use_lea
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ? DefineAsRegister(add)
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : DefineSameAsFirst(add);
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
1562b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  } else if (instr->representation().IsDouble()) {
1563e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return DoArithmeticD(Token::ADD, instr);
1564b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  } else {
1565b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    return DoArithmeticT(Token::ADD, instr);
1566b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
1567b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return NULL;
1568b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1569b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1570b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* left = NULL;
1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* right = NULL;
1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->left()->representation().Equals(instr->representation()));
1575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->right()->representation().Equals(instr->representation()));
1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->representation().IsSmi()) {
1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    left = UseRegisterAtStart(instr->BetterLeftOperand());
1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    right = UseAtStart(instr->BetterRightOperand());
1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (instr->representation().IsInteger32()) {
1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    left = UseRegisterAtStart(instr->BetterLeftOperand());
1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    right = UseOrConstantAtStart(instr->BetterRightOperand());
1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->representation().IsDouble());
1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    left = UseRegisterAtStart(instr->left());
1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    right = UseRegisterAtStart(instr->right());
1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LMathMinMax* minmax = new(zone()) LMathMinMax(left, right);
1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DefineSameAsFirst(minmax);
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1592b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoPower(HPower* instr) {
1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->representation().IsDouble());
1594e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // We call a C function for double power. It can't trigger a GC.
1595e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // We need to use fixed result register for the call.
1596e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  Representation exponent_type = instr->right()->representation();
1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->left()->representation().IsDouble());
1598e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  LOperand* left = UseFixedDouble(instr->left(), xmm2);
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* right =
1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      exponent_type.IsDouble()
1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ? UseFixedDouble(instr->right(), xmm1)
1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          : UseFixed(instr->right(), MathPowTaggedDescriptor::exponent());
16033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LPower* result = new(zone()) LPower(left, right);
16043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return MarkAsCall(DefineFixedDouble(result, xmm3), instr,
1605e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                    CAN_DEOPTIMIZE_EAGERLY);
1606b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1607b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1608b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
16093fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->left()->representation().IsTagged());
1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->right()->representation().IsTagged());
1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
16133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* left = UseFixed(instr->left(), rdx);
16143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* right = UseFixed(instr->right(), rax);
1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LCmpT* result = new(zone()) LCmpT(context, left, right);
16163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return MarkAsCall(DefineFixed(result, rax), instr);
16173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
16183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
16193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoCompareNumericAndBranch(
1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HCompareNumericAndBranch* instr) {
1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation r = instr->representation();
1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (r.IsSmiOrInteger32()) {
1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->left()->representation().Equals(r));
1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->right()->representation().Equals(r));
16263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LOperand* left = UseRegisterOrConstantAtStart(instr->left());
16271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    LOperand* right = UseOrConstantAtStart(instr->right());
1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone()) LCompareNumericAndBranch(left, right);
16293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else {
1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(r.IsDouble());
1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->left()->representation().IsDouble());
1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->right()->representation().IsDouble());
16333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LOperand* left;
16343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LOperand* right;
16353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (instr->left()->IsConstant() && instr->right()->IsConstant()) {
16363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      left = UseRegisterOrConstantAtStart(instr->left());
16373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      right = UseRegisterOrConstantAtStart(instr->right());
16383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else {
16393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      left = UseRegisterAtStart(instr->left());
16403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      right = UseRegisterAtStart(instr->right());
16413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone()) LCompareNumericAndBranch(left, right);
16431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
1644b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1645b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1646b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
16473fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
16483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    HCompareObjectEqAndBranch* instr) {
16491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* left = UseRegisterAtStart(instr->left());
1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* right = UseRegisterOrConstantAtStart(instr->right());
16513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return new(zone()) LCmpObjectEqAndBranch(left, right);
1652b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1653b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1654b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoCompareHoleAndBranch(
1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HCompareHoleAndBranch* instr) {
16573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* value = UseRegisterAtStart(instr->value());
1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new(zone()) LCmpHoleAndBranch(value);
1659257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1660257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1661257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
16623ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->value()->representation().IsTagged());
16643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* value = UseRegisterAtStart(instr->value());
16653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* temp = TempRegister();
16663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return new(zone()) LIsStringAndBranch(value, temp);
1667592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}
1668592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
1669592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
16703fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->value()->representation().IsTagged());
16723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return new(zone()) LIsSmiAndBranch(Use(instr->value()));
1673b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1674b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1675b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
16763fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
16773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    HIsUndetectableAndBranch* instr) {
1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->value()->representation().IsTagged());
16793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* value = UseRegisterAtStart(instr->value());
16803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* temp = TempRegister();
16813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return new(zone()) LIsUndetectableAndBranch(value, temp);
16823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
16833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
16843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
16853ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLInstruction* LChunkBuilder::DoStringCompareAndBranch(
16863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    HStringCompareAndBranch* instr) {
16873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->left()->representation().IsTagged());
1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->right()->representation().IsTagged());
1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
16913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* left = UseFixed(instr->left(), rdx);
16923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* right = UseFixed(instr->right(), rax);
16933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LStringCompareAndBranch* result =
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new(zone()) LStringCompareAndBranch(context, left, right);
16953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
16963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return MarkAsCall(result, instr);
1697592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}
1698592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
1699592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
17003fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch(
17013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    HHasInstanceTypeAndBranch* instr) {
1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->value()->representation().IsTagged());
17033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* value = UseRegisterAtStart(instr->value());
17043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return new(zone()) LHasInstanceTypeAndBranch(value);
1705e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
1706e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1707e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1708e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochLInstruction* LChunkBuilder::DoGetCachedArrayIndex(
1709e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    HGetCachedArrayIndex* instr)  {
1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->value()->representation().IsTagged());
1711e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  LOperand* value = UseRegisterAtStart(instr->value());
1712e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
17133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return DefineAsRegister(new(zone()) LGetCachedArrayIndex(value));
1714b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1715b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1716b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
17173fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
17183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    HHasCachedArrayIndexAndBranch* instr) {
1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(instr->value()->representation().IsTagged());
17203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* value = UseRegisterAtStart(instr->value());
17213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return new(zone()) LHasCachedArrayIndexAndBranch(value);
1722b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1723b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1724b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
17253fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLInstruction* LChunkBuilder::DoClassOfTestAndBranch(
17263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    HClassOfTestAndBranch* instr) {
17273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* value = UseRegister(instr->value());
17283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return new(zone()) LClassOfTestAndBranch(value,
17293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                           TempRegister(),
17303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                           TempRegister());
1731b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1732b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1733b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* string = UseRegisterAtStart(instr->string());
1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DefineAsRegister(new(zone()) LSeqStringGetChar(string, index));
17383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
17393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
17403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* string = UseRegisterAtStart(instr->string());
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* index = FLAG_debug_code
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ? UseRegisterAtStart(instr->index())
1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : UseRegisterOrConstantAtStart(instr->index());
1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* value = FLAG_debug_code
1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ? UseRegisterAtStart(instr->value())
1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : UseRegisterOrConstantAtStart(instr->value());
1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), rsi) : NULL;
1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = new(zone()) LSeqStringSetChar(context, string,
1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                       index, value);
1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_debug_code) {
1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = MarkAsCall(result, instr);
1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
17563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
17573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
17583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!FLAG_debug_code && instr->skip_check()) return NULL;
1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* length = !index->IsConstantOperand()
1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ? UseOrConstantAtStart(instr->length())
1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : UseAtStart(instr->length());
1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = new(zone()) LBoundsCheck(index, length);
1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!FLAG_debug_code || !instr->skip_check()) {
1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
17705d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch}
17715d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
17725d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
17731e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockLInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
17741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // The control instruction marking the end of a block that completed
17751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // abruptly (e.g., threw an exception).  There is nothing specific to do.
1776b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return NULL;
1777b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1778b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1779b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
17803fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) {
17813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return NULL;
17823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
17833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
17843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1785257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochLInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
1786257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // All HForceRepresentation instructions should be eliminated in the
1787257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // representation change phase of Hydrogen.
1788257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  UNREACHABLE();
1789257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return NULL;
1790257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1791257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1792257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1793b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoChange(HChange* instr) {
17941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Representation from = instr->from();
17951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Representation to = instr->to();
1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* val = instr->value();
1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (from.IsSmi()) {
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (to.IsTagged()) {
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LOperand* value = UseRegister(val);
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return DefineSameAsFirst(new(zone()) LDummyUse(value));
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    from = Representation::Tagged();
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
18041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (from.IsTagged()) {
18051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    if (to.IsDouble()) {
1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LOperand* value = UseRegister(val);
1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value));
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!val->representation().IsSmi()) result = AssignEnvironment(result);
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return result;
1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (to.IsSmi()) {
1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LOperand* value = UseRegister(val);
1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (val->type().IsSmi()) {
1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return DefineSameAsFirst(new(zone()) LDummyUse(value));
1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
18161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    } else {
1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(to.IsInteger32());
1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (val->type().IsSmi() || val->representation().IsSmi()) {
1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LOperand* value = UseRegister(val);
1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LOperand* value = UseRegister(val);
18233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        bool truncating = instr->CanTruncateToInt32();
18243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1);
1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LInstruction* result =
1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp));
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (!val->representation().IsSmi()) result = AssignEnvironment(result);
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return result;
18291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      }
18301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
18311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else if (from.IsDouble()) {
18321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    if (to.IsTagged()) {
1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      info()->MarkAsDeferredCalling();
1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LOperand* value = UseRegister(val);
18351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      LOperand* temp = TempRegister();
18361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      LUnallocated* result_temp = TempRegister();
18373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      LNumberTagD* result = new(zone()) LNumberTagD(value, temp);
18381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      return AssignPointerMap(Define(result, result_temp));
1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (to.IsSmi()) {
1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LOperand* value = UseRegister(val);
1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return AssignEnvironment(
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          DefineAsRegister(new(zone()) LDoubleToSmi(value)));
18431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    } else {
1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(to.IsInteger32());
1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LOperand* value = UseRegister(val);
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value));
1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return result;
18491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
18501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else if (from.IsInteger32()) {
1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    info()->MarkAsDeferredCalling();
18521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    if (to.IsTagged()) {
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!instr->CheckFlag(HValue::kCanOverflow)) {
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LOperand* value = UseRegister(val);
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return DefineAsRegister(new(zone()) LSmiTag(value));
1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (val->CheckFlag(HInstruction::kUint32)) {
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LOperand* value = UseRegister(val);
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LOperand* temp1 = TempRegister();
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LOperand* temp2 = FixedTemp(xmm1);
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return AssignPointerMap(DefineSameAsFirst(result));
18621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      } else {
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LOperand* value = UseRegister(val);
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LOperand* temp1 = SmiValuesAre32Bits() ? NULL : TempRegister();
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LOperand* temp2 = SmiValuesAre32Bits() ? NULL : FixedTemp(xmm1);
1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2);
1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return AssignPointerMap(DefineSameAsFirst(result));
18681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      }
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (to.IsSmi()) {
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LOperand* value = UseRegister(val);
1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (instr->CheckFlag(HValue::kCanOverflow)) {
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        result = AssignEnvironment(result);
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return result;
18761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    } else {
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(to.IsDouble());
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (val->CheckFlag(HInstruction::kUint32)) {
1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val)));
1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LOperand* value = Use(val);
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return DefineAsRegister(new(zone()) LInteger32ToDouble(value));
1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
18841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
18851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
18861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  UNREACHABLE();
1887b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return NULL;
1888b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1889b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1890b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
18921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* value = UseRegisterAtStart(instr->value());
1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = new(zone()) LCheckNonSmi(value);
1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!instr->value()->type().IsHeapObject()) {
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
1898b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1899b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1900b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
19021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* value = UseRegisterAtStart(instr->value());
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return AssignEnvironment(new(zone()) LCheckSmi(value));
1904b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1905b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1906b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLInstruction* LChunkBuilder::DoCheckArrayBufferNotNeutered(
1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    HCheckArrayBufferNotNeutered* instr) {
1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LOperand* view = UseRegisterAtStart(instr->value());
1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LCheckArrayBufferNotNeutered* result =
1911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      new (zone()) LCheckArrayBufferNotNeutered(view);
1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return AssignEnvironment(result);
1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
19171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* value = UseRegisterAtStart(instr->value());
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LCheckInstanceType* result = new(zone()) LCheckInstanceType(value);
1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return AssignEnvironment(result);
1920b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1921b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1922b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
19241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* value = UseRegisterAtStart(instr->value());
1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return AssignEnvironment(new(zone()) LCheckValue(value));
1926b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1927b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1928b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps;
19311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* value = UseRegisterAtStart(instr->value());
1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = AssignEnvironment(new(zone()) LCheckMaps(value));
1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->HasMigrationTarget()) {
1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    info()->MarkAsDeferredCalling();
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignPointerMap(result);
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
1938b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1939b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1940b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1941257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochLInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
1942257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HValue* value = instr->value();
1943257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Representation input_rep = value->representation();
1944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  LOperand* reg = UseRegister(value);
1945257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (input_rep.IsDouble()) {
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DefineAsRegister(new(zone()) LClampDToUint8(reg));
1947257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else if (input_rep.IsInteger32()) {
19483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return DefineSameAsFirst(new(zone()) LClampIToUint8(reg));
1949257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(input_rep.IsSmiOrTagged());
1951257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Register allocator doesn't (yet) support allocation of double
1952257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // temps. Reserve xmm1 explicitly.
19533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LClampTToUint8* result = new(zone()) LClampTToUint8(reg,
19543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                        FixedTemp(xmm1));
1955257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return AssignEnvironment(DefineSameAsFirst(result));
1956257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1957257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1958257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1959257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1960b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = info()->IsStub() ? UseFixed(instr->context(), rsi) : NULL;
1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count());
1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new(zone()) LReturn(
1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UseFixed(instr->value(), rax), context, parameter_count);
1965b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1966b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1967b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1968b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1969b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  Representation r = instr->representation();
1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (r.IsSmi()) {
1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DefineAsRegister(new(zone()) LConstantS);
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (r.IsInteger32()) {
19733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return DefineAsRegister(new(zone()) LConstantI);
1974b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  } else if (r.IsDouble()) {
1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return DefineAsRegister(new (zone()) LConstantD);
1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (r.IsExternal()) {
1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DefineAsRegister(new(zone()) LConstantE);
1978b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  } else if (r.IsTagged()) {
19793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return DefineAsRegister(new(zone()) LConstantT);
1980b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  } else {
1981b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    UNREACHABLE();
1982b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    return NULL;
1983b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
1984b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1985b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1986b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
19878b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochLInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
198913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  LOperand* vector = FixedTemp(LoadWithVectorDescriptor::VectorRegister());
1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
199113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  LLoadGlobalGeneric* result = new (zone()) LLoadGlobalGeneric(context, vector);
19928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  return MarkAsCall(DefineFixed(result, rax), instr);
19938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
19948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
19958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1996b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
1997e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  LOperand* context = UseRegisterAtStart(instr->value());
19983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LInstruction* result =
19993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      DefineAsRegister(new(zone()) LLoadContextSlot(context));
2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2004b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2005b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2006b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
20071e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockLInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
2008e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  LOperand* context;
2009e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  LOperand* value;
2010e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  LOperand* temp;
2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  context = UseRegister(instr->context());
2012e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  if (instr->NeedsWriteBarrier()) {
2013e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    value = UseTempRegister(instr->value());
2014e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    temp = TempRegister();
2015e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  } else {
2016e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    value = UseRegister(instr->value());
2017e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    temp = NULL;
2018e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
20193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LInstruction* result = new(zone()) LStoreContextSlot(context, value, temp);
2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2024b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2025b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2026b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
20271e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockLInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Use the special mov rax, moffs64 encoding for external
2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // memory accesses with 64-bit word-sized values.
2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->access().IsExternalMemory() &&
2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr->access().offset() == 0 &&
2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (instr->access().representation().IsSmi() ||
2033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       instr->access().representation().IsTagged() ||
2034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       instr->access().representation().IsHeapObject() ||
2035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       instr->access().representation().IsExternal())) {
2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* obj = UseRegisterOrConstantAtStart(instr->object());
2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DefineFixed(new(zone()) LLoadNamedField(obj), rax);
2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
20391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* obj = UseRegisterAtStart(instr->object());
20403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return DefineAsRegister(new(zone()) LLoadNamedField(obj));
20411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
20421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
20431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2044b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* object =
2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
204813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  LOperand* vector = FixedTemp(LoadWithVectorDescriptor::VectorRegister());
2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(
2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      context, object, vector);
20511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return MarkAsCall(DefineFixed(result, rax), instr);
2052b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2053b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2054b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2055b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoLoadFunctionPrototype(
2056b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    HLoadFunctionPrototype* instr) {
20571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return AssignEnvironment(DefineAsRegister(
20583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      new(zone()) LLoadFunctionPrototype(UseRegister(instr->function()))));
2059b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2060b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2061b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) {
2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DefineAsRegister(new(zone()) LLoadRoot);
20641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
20651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
20661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LChunkBuilder::FindDehoistedKeyDefinitions(HValue* candidate) {
2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We sign extend the dehoisted key at the definition point when the pointer
2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // size is 64-bit. For x32 port, we sign extend the dehoisted key at the use
2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // points and should not invoke this function. We can't use STATIC_ASSERT
2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // here as the pointer size is 32-bit for x32.
2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kPointerSize == kInt64Size);
2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BitVector* dehoisted_key_ids = chunk_->GetDehoistedKeyIds();
2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (dehoisted_key_ids->Contains(candidate->id())) return;
2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  dehoisted_key_ids->Add(candidate->id());
2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!candidate->IsPhi()) return;
2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < candidate->OperandCount(); ++i) {
2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FindDehoistedKeyDefinitions(candidate->OperandAt(i));
2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2080b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2081b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2082b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
2084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((kPointerSize == kInt64Size &&
2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          instr->key()->representation().IsInteger32()) ||
2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         (kPointerSize == kInt32Size &&
2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          instr->key()->representation().IsSmiOrInteger32()));
2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ElementsKind elements_kind = instr->elements_kind();
2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* key = NULL;
2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = NULL;
20911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kPointerSize == kInt64Size) {
2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    key = UseRegisterOrConstantAtStart(instr->key());
2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool clobbers_key = ExternalArrayOpRequiresTemp(
2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        instr->key()->representation(), elements_kind);
2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    key = clobbers_key
2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ? UseTempRegister(instr->key())
2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : UseRegisterOrConstantAtStart(instr->key());
2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
21011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((kPointerSize == kInt64Size) && instr->IsDehoisted()) {
2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FindDehoistedKeyDefinitions(instr->key());
2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
21053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!instr->is_fixed_typed_array()) {
2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* obj = UseRegisterAtStart(instr->elements());
2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result = DefineAsRegister(new (zone()) LLoadKeyed(obj, key, nullptr));
2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(
2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (instr->representation().IsInteger32() &&
2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         !(IsDoubleOrFloatElementsKind(elements_kind))) ||
2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (instr->representation().IsDouble() &&
2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         (IsDoubleOrFloatElementsKind(elements_kind))));
2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* backing_store = UseRegister(instr->elements());
2116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LOperand* backing_store_owner = UseAny(instr->backing_store_owner());
2117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result = DefineAsRegister(
2118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        new (zone()) LLoadKeyed(backing_store, key, backing_store_owner));
2119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool needs_environment;
2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (instr->is_fixed_typed_array()) {
2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // see LCodeGen::DoLoadKeyedExternalArray
2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    needs_environment = elements_kind == UINT32_ELEMENTS &&
2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        !instr->CheckFlag(HInstruction::kUint32);
2126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // see LCodeGen::DoLoadKeyedFixedDoubleArray and
2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // LCodeGen::DoLoadKeyedFixedArray
2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    needs_environment =
2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        instr->RequiresHoleCheck() ||
2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (instr->hole_mode() == CONVERT_HOLE_TO_UNDEFINED && info()->IsStub());
2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
21333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (needs_environment) {
2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = AssignEnvironment(result);
2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2138b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2139b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2140b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2141b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* object =
2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister());
214613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  LOperand* vector = FixedTemp(LoadWithVectorDescriptor::VectorRegister());
2147e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LLoadKeyedGeneric* result =
2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new(zone()) LLoadKeyedGeneric(context, object, key, vector);
2150e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  return MarkAsCall(DefineFixed(result, rax), instr);
2151b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2152b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2153b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ElementsKind elements_kind = instr->elements_kind();
21563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((kPointerSize == kInt64Size) && instr->IsDehoisted()) {
2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FindDehoistedKeyDefinitions(instr->key());
2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
21603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!instr->is_fixed_typed_array()) {
2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->elements()->representation().IsTagged());
2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool needs_write_barrier = instr->NeedsWriteBarrier();
2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* object = NULL;
2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* key = NULL;
2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* val = NULL;
2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Representation value_representation = instr->value()->representation();
2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (value_representation.IsDouble()) {
2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      object = UseRegisterAtStart(instr->elements());
2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      val = UseRegisterAtStart(instr->value());
2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      key = UseRegisterOrConstantAtStart(instr->key());
2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(value_representation.IsSmiOrTagged() ||
2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             value_representation.IsInteger32());
2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (needs_write_barrier) {
2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        object = UseTempRegister(instr->elements());
2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        val = UseTempRegister(instr->value());
2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        key = UseTempRegister(instr->key());
2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        object = UseRegisterAtStart(instr->elements());
2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        val = UseRegisterOrConstantAtStart(instr->value());
2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        key = UseRegisterOrConstantAtStart(instr->key());
2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
21863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone()) LStoreKeyed(object, key, val, nullptr);
2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
21893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(
2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       (instr->value()->representation().IsInteger32() &&
2192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       !IsDoubleOrFloatElementsKind(elements_kind)) ||
2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       (instr->value()->representation().IsDouble() &&
2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       IsDoubleOrFloatElementsKind(elements_kind)));
2195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(instr->elements()->representation().IsExternal());
2196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool val_is_temp_register = elements_kind == UINT8_CLAMPED_ELEMENTS ||
2197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              elements_kind == FLOAT32_ELEMENTS;
2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* val = val_is_temp_register ? UseTempRegister(instr->value())
21998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      : UseRegister(instr->value());
2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* key = NULL;
2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kPointerSize == kInt64Size) {
2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    key = UseRegisterOrConstantAtStart(instr->key());
2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool clobbers_key = ExternalArrayOpRequiresTemp(
2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        instr->key()->representation(), elements_kind);
2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    key = clobbers_key
2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ? UseTempRegister(instr->key())
2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : UseRegisterOrConstantAtStart(instr->key());
2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* backing_store = UseRegister(instr->elements());
2211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LOperand* backing_store_owner = UseAny(instr->backing_store_owner());
2212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new (zone()) LStoreKeyed(backing_store, key, val, backing_store_owner);
2213e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
2214e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2215e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
22163ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLInstruction* LChunkBuilder::DoTransitionElementsKind(
22173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    HTransitionElementsKind* instr) {
2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
22193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LOperand* object = UseRegister(instr->object());
22203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LOperand* new_map_reg = TempRegister();
22213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LOperand* temp_reg = TempRegister();
2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LTransitionElementsKind* result = new(zone()) LTransitionElementsKind(
2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        object, NULL, new_map_reg, temp_reg);
2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
22253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
22263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LOperand* object = UseFixed(instr->object(), rax);
2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* context = UseFixed(instr->context(), rsi);
22283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LTransitionElementsKind* result =
2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        new(zone()) LTransitionElementsKind(object, context, NULL, NULL);
2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MarkAsCall(result, instr);
22313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
22323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
22333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
22343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoTrapAllocationMemento(
2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HTrapAllocationMemento* instr) {
2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* object = UseRegister(instr->object());
2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* temp = TempRegister();
2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LTrapAllocationMemento* result =
2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new(zone()) LTrapAllocationMemento(object, temp);
2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return AssignEnvironment(result);
2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLInstruction* LChunkBuilder::DoMaybeGrowElements(HMaybeGrowElements* instr) {
2246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  info()->MarkAsDeferredCalling();
2247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
2248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LOperand* object = Use(instr->object());
2249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LOperand* elements = Use(instr->elements());
2250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LOperand* key = UseRegisterOrConstant(instr->key());
2251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LOperand* current_capacity = UseRegisterOrConstant(instr->current_capacity());
2252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LMaybeGrowElements* result = new (zone())
2254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LMaybeGrowElements(context, object, elements, key, current_capacity);
2255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DefineFixed(result, rax);
2256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return AssignPointerMap(AssignEnvironment(result));
2257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2260b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_in_object = instr->access().IsInobject();
2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_external_location = instr->access().IsExternalMemory() &&
2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr->access().offset() == 0;
22641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool needs_write_barrier = instr->NeedsWriteBarrier();
2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool needs_write_barrier_for_map = instr->has_transition() &&
2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr->NeedsWriteBarrierForMap();
2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* obj;
2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (needs_write_barrier) {
2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    obj = is_in_object
2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ? UseRegister(instr->object())
2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : UseTempRegister(instr->object());
2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (is_external_location) {
2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!is_in_object);
2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!needs_write_barrier);
2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!needs_write_barrier_for_map);
2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    obj = UseRegisterOrConstant(instr->object());
2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    obj = needs_write_barrier_for_map
2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ? UseRegister(instr->object())
2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : UseRegisterAtStart(instr->object());
2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
22831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool can_be_constant = instr->value()->IsConstant() &&
2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HConstant::cast(instr->value())->NotInNewSpace() &&
2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      !instr->field_representation().IsDouble();
2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* val;
2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (needs_write_barrier) {
2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    val = UseTempRegister(instr->value());
2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (is_external_location) {
2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    val = UseFixed(instr->value(), rax);
2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (can_be_constant) {
2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    val = UseRegisterOrConstant(instr->value());
2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (instr->field_representation().IsDouble()) {
2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    val = UseRegisterAtStart(instr->value());
2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    val = UseRegister(instr->value());
2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
23001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
23011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // We only need a scratch register if we have a write barrier or we
23021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // have a store into the properties array (not in-object-property).
2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* temp = (!is_in_object || needs_write_barrier ||
2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      needs_write_barrier_for_map) ? TempRegister() : NULL;
23051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
23063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return new(zone()) LStoreNamedField(obj, val, temp);
2307b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2308b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2309b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2310257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochLInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* left = UseFixed(instr->left(), rdx);
2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* right = UseFixed(instr->right(), rax);
2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return MarkAsCall(
2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DefineFixed(new(zone()) LStringAdd(context, left, right), rax), instr);
2316257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
2317257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
23191e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockLInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
232069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  LOperand* string = UseTempRegister(instr->string());
232169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  LOperand* index = UseTempRegister(instr->index());
2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseAny(instr->context());
2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LStringCharCodeAt* result =
2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new(zone()) LStringCharCodeAt(context, string, index);
2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return AssignPointerMap(DefineAsRegister(result));
2326b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2327b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2328b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
232944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockLInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
233044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOperand* char_code = UseRegister(instr->value());
2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseAny(instr->context());
2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LStringCharFromCode* result =
2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new(zone()) LStringCharFromCode(context, char_code);
233444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return AssignPointerMap(DefineAsRegister(result));
233544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
233644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
233744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
2339bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  LOperand* size = instr->size()->IsConstant() ? UseConstant(instr->size())
2340bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                               : UseRegister(instr->size());
2341bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (instr->IsAllocationFolded()) {
2342bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    LOperand* temp = TempRegister();
2343bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    LFastAllocate* result = new (zone()) LFastAllocate(size, temp);
2344bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return DefineAsRegister(result);
2345bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else {
2346bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    info()->MarkAsDeferredCalling();
2347bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    LOperand* context = UseAny(instr->context());
2348bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    LOperand* temp = TempRegister();
2349bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    LAllocate* result = new (zone()) LAllocate(context, size, temp);
2350bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return AssignPointerMap(DefineAsRegister(result));
2351bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
23523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
23533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
23543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2355b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(argument_count_ == 0);
2357e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  allocator_->MarkAsOsrEntry();
2358e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  current_block_->last_environment()->set_ast_id(instr->ast_id());
23593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return AssignEnvironment(new(zone()) LOsrEntry);
2360b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2361b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2362b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2363b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LParameter* result = new(zone()) LParameter;
2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->kind() == HParameter::STACK_PARAMETER) {
2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int spill_index = chunk()->GetParameterStackSlot(instr->index());
2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DefineAsSpilled(result, spill_index);
2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(info()->IsStub());
2370109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CallInterfaceDescriptor descriptor = graph()->descriptor();
2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int index = static_cast<int>(instr->index());
2372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register reg = descriptor.GetRegisterParameter(index);
2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return DefineFixed(result, reg);
2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2375b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2376b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2377b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2378b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Use an index that corresponds to the location in the unoptimized frame,
2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // which the optimized frame will subsume.
2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int env_index = instr->index();
2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int spill_index = 0;
2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->environment()->is_parameter_index(env_index)) {
2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    spill_index = chunk()->GetParameterStackSlot(env_index);
2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    spill_index = env_index - instr->environment()->first_local_index();
2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (spill_index > LUnallocated::kMaxFixedSlotIndex) {
2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Retry(kTooManySpillSlotsNeededForOSR);
2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      spill_index = 0;
2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2391109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    spill_index += StandardFrameConstants::kFixedSlotCount;
23927d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch  }
23933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index);
2394b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2395b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2396b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2397b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
2398e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // There are no real uses of the arguments object.
2399e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // arguments.length and element access are supported directly on
2400e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // stack arguments, and any real arguments object use causes a bailout.
2401e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // So this value is never used.
2402b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return NULL;
2403b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2404b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2405b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  instr->ReplayEnvironment(current_block_->last_environment());
2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // There are no real uses of a captured object.
2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2414b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  info()->MarkAsRequiresFrame();
2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* args = UseRegister(instr->arguments());
2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* length;
2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* index;
2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->length()->IsConstant() && instr->index()->IsConstant()) {
2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    length = UseRegisterOrConstant(instr->length());
2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    index = UseOrConstant(instr->index());
2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    length = UseTempRegister(instr->length());
2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    index = Use(instr->index());
2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
2427b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2428b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2429b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2430b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
2432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LOperand* value = UseFixed(instr->value(), rbx);
2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LTypeof* result = new(zone()) LTypeof(context, value);
2434e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  return MarkAsCall(DefineFixed(result, rax), instr);
2435b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2436b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2437b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
24383fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
24393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value()));
2440b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2441b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
24421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2443b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  instr->ReplayEnvironment(current_block_->last_environment());
2445b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return NULL;
2446b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2447b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2448b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2449b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  info()->MarkAsDeferredCalling();
24513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (instr->is_function_entry()) {
2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* context = UseFixed(instr->context(), rsi);
2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MarkAsCall(new(zone()) LStackCheck(context), instr);
24543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else {
2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->is_backwards_branch());
2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* context = UseAny(instr->context());
2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AssignEnvironment(
2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        AssignPointerMap(new(zone()) LStackCheck(context)));
24593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
2460b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2461b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2462b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2463b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
24641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  HEnvironment* outer = current_block_->last_environment();
2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  outer->set_ast_id(instr->ReturnId());
24661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  HConstant* undefined = graph()->GetConstantUndefined();
24673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  HEnvironment* inner = outer->CopyForInlining(
24683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      instr->closure(), instr->arguments_count(), instr->function(), undefined,
24693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      instr->inlining_kind(), instr->syntactic_tail_call_mode());
2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Only replay binding of arguments object if it wasn't removed from graph.
2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    inner->Bind(instr->arguments_var(), instr->arguments_object());
24733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inner->BindContext(instr->closure_context());
2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inner->set_entry(instr);
24761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  current_block_->UpdateEnvironment(inner);
2477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  chunk_->AddInlinedFunction(instr->shared());
2478b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return NULL;
2479b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
2480b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2481b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2482b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochLInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* pop = NULL;
2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnvironment* env = current_block_->last_environment();
2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (env->entry()->arguments_pushed()) {
2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int argument_count = env->arguments_environment()->parameter_count();
2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pop = new(zone()) LDrop(argument_count);
2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instr->argument_delta() == -argument_count);
2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
24933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEnvironment* outer = current_block_->last_environment()->
24943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      DiscardInlined(false);
24951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  current_block_->UpdateEnvironment(outer);
2496b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pop;
2498257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
2499257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2500257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
25013ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) {
2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOperand* context = UseFixed(instr->context(), rsi);
25033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* object = UseFixed(instr->enumerable(), rax);
2504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LForInPrepareMap* result = new(zone()) LForInPrepareMap(context, object);
25053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY);
25063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
25073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
25083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
25093ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) {
25103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* map = UseRegister(instr->map());
25113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return AssignEnvironment(DefineAsRegister(
25123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      new(zone()) LForInCacheArray(map)));
25133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
25143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
25153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
25163ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
25173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* value = UseRegisterAtStart(instr->value());
25183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* map = UseRegisterAtStart(instr->map());
25193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return AssignEnvironment(new(zone()) LCheckMapValue(value, map));
25203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
25213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
25223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
25233ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
25243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* object = UseRegister(instr->object());
25253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LOperand* index = UseTempRegister(instr->index());
2526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index);
2527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* result = DefineSameAsFirst(load);
2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return AssignPointerMap(result);
2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
2532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
2533b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2534b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif  // V8_TARGET_ARCH_X64
2535