15e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
25e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
35e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org// found in the LICENSE file.
45e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
55e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org#include "src/compiler/change-lowering.h"
6d71b62088ad094b1187c06c92d1f27fab56aaddbmachenbach@chromium.org#include "src/compiler/machine-operator.h"
75e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
85e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org#include "src/compiler/js-graph.h"
95e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgnamespace v8 {
115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgnamespace internal {
125e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgnamespace compiler {
135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgChangeLowering::~ChangeLowering() {}
155e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgReduction ChangeLowering::Reduce(Node* node) {
185e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* control = graph()->start();
195e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  switch (node->opcode()) {
205e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case IrOpcode::kChangeBitToBool:
215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return ChangeBitToBool(node->InputAt(0), control);
225e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case IrOpcode::kChangeBoolToBit:
235e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return ChangeBoolToBit(node->InputAt(0));
245e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case IrOpcode::kChangeFloat64ToTagged:
255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return ChangeFloat64ToTagged(node->InputAt(0), control);
265e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case IrOpcode::kChangeInt32ToTagged:
275e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return ChangeInt32ToTagged(node->InputAt(0), control);
285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case IrOpcode::kChangeTaggedToFloat64:
295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return ChangeTaggedToFloat64(node->InputAt(0), control);
305e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case IrOpcode::kChangeTaggedToInt32:
31d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org      return ChangeTaggedToUI32(node->InputAt(0), control, kSigned);
32e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    case IrOpcode::kChangeTaggedToUint32:
33d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org      return ChangeTaggedToUI32(node->InputAt(0), control, kUnsigned);
34e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    case IrOpcode::kChangeUint32ToTagged:
35e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      return ChangeUint32ToTagged(node->InputAt(0), control);
365e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    default:
375e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return NoChange();
385e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  }
395e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  UNREACHABLE();
405e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return NoChange();
415e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
425e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
435e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
445e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgNode* ChangeLowering::HeapNumberValueIndexConstant() {
455e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  STATIC_ASSERT(HeapNumber::kValueOffset % kPointerSize == 0);
465e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  const int heap_number_value_offset =
476313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      ((HeapNumber::kValueOffset / kPointerSize) * (machine()->Is64() ? 8 : 4));
485e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return jsgraph()->Int32Constant(heap_number_value_offset - kHeapObjectTag);
495e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
505e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
515e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
52e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgNode* ChangeLowering::SmiMaxValueConstant() {
536313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  const int smi_value_size = machine()->Is32() ? SmiTagging<4>::SmiValueSize()
54ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                               : SmiTagging<8>::SmiValueSize();
55e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  return jsgraph()->Int32Constant(
56e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      -(static_cast<int>(0xffffffffu << (smi_value_size - 1)) + 1));
57e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
58e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
59e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
605e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgNode* ChangeLowering::SmiShiftBitsConstant() {
616313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  const int smi_shift_size = machine()->Is32() ? SmiTagging<4>::SmiShiftSize()
62ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                               : SmiTagging<8>::SmiShiftSize();
635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return jsgraph()->Int32Constant(smi_shift_size + kSmiTagSize);
645e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
67e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgNode* ChangeLowering::AllocateHeapNumberWithValue(Node* value, Node* control) {
68e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // The AllocateHeapNumber() runtime function does not use the context, so we
69e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // can safely pass in Smi zero here.
70e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* context = jsgraph()->ZeroConstant();
71e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* effect = graph()->NewNode(common()->ValueEffect(1), value);
72e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  const Runtime::Function* function =
73e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      Runtime::FunctionForId(Runtime::kAllocateHeapNumber);
74e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  DCHECK_EQ(0, function->nargs);
75e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  CallDescriptor* desc = linkage()->GetRuntimeCallDescriptor(
76e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      function->function_id, 0, Operator::kNoProperties);
77e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* heap_number = graph()->NewNode(
78e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      common()->Call(desc), jsgraph()->CEntryStubConstant(),
79e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      jsgraph()->ExternalConstant(ExternalReference(function, isolate())),
80e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      jsgraph()->Int32Constant(function->nargs), context, effect, control);
81e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* store = graph()->NewNode(
826313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      machine()->Store(StoreRepresentation(kMachFloat64, kNoWriteBarrier)),
836313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      heap_number, HeapNumberValueIndexConstant(), value, heap_number, control);
84e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  return graph()->NewNode(common()->Finish(1), heap_number, store);
85e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
86e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
87e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
88e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgNode* ChangeLowering::ChangeSmiToInt32(Node* value) {
89e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant());
906313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  if (machine()->Is64()) {
91e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value);
92e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
93e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  return value;
94e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
95e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
96e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
97e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgNode* ChangeLowering::LoadHeapNumberValue(Node* value, Node* control) {
98e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  return graph()->NewNode(machine()->Load(kMachFloat64), value,
99e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org                          HeapNumberValueIndexConstant(),
100e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org                          graph()->NewNode(common()->ControlEffect(), control));
101e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
102e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
103e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
1045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgReduction ChangeLowering::ChangeBitToBool(Node* val, Node* control) {
1055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* branch = graph()->NewNode(common()->Branch(), val, control);
1065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* true_value = jsgraph()->TrueConstant();
1095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* false_value = jsgraph()->FalseConstant();
1125e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
11442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Node* phi = graph()->NewNode(
11542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org      common()->Phi(static_cast<MachineType>(kTypeBool | kRepTagged), 2),
11642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org      true_value, false_value, merge);
1175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1185e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return Replace(phi);
1195e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
1205e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1225e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgReduction ChangeLowering::ChangeBoolToBit(Node* val) {
1235e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return Replace(
1245e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      graph()->NewNode(machine()->WordEqual(), val, jsgraph()->TrueConstant()));
1255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
1265e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1275e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgReduction ChangeLowering::ChangeFloat64ToTagged(Node* val, Node* control) {
1295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return Replace(AllocateHeapNumberWithValue(val, control));
1305e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
1315e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1335e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgReduction ChangeLowering::ChangeInt32ToTagged(Node* val, Node* control) {
1346313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  if (machine()->Is64()) {
1355e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    return Replace(
1365e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        graph()->NewNode(machine()->Word64Shl(),
1375e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                         graph()->NewNode(machine()->ChangeInt32ToInt64(), val),
1385e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                         SmiShiftBitsConstant()));
1395e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  }
1405e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1415e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), val, val);
1425e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* ovf = graph()->NewNode(common()->Projection(1), add);
1435e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1445e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* branch = graph()->NewNode(common()->Branch(), ovf, control);
1455e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1465e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1475e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* heap_number = AllocateHeapNumberWithValue(
1485e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      graph()->NewNode(machine()->ChangeInt32ToFloat64(), val), if_true);
1495e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1505e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1515e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* smi = graph()->NewNode(common()->Projection(0), add);
1525e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1535e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
15442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), heap_number,
15542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org                               smi, merge);
1565e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1575e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return Replace(phi);
1585e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
1595e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1605e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
161d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.orgReduction ChangeLowering::ChangeTaggedToUI32(Node* val, Node* control,
162d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org                                             Signedness signedness) {
1635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  STATIC_ASSERT(kSmiTag == 0);
1645e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  STATIC_ASSERT(kSmiTagMask == 1);
1655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* tag = graph()->NewNode(machine()->WordAnd(), val,
1675e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                               jsgraph()->Int32Constant(kSmiTagMask));
1685e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* branch = graph()->NewNode(common()->Branch(), tag, control);
1695e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1705e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1712c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  const Operator* op = (signedness == kSigned)
1722c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                           ? machine()->ChangeFloat64ToInt32()
1732c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                           : machine()->ChangeFloat64ToUint32();
1745fc1eed70f85bd1e9d0833742945798d6ef49cf0machenbach@chromium.org  Node* change = graph()->NewNode(op, LoadHeapNumberValue(val, if_true));
1755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1765e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
177e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* number = ChangeSmiToInt32(val);
1785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
18042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Node* phi = graph()->NewNode(
18142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org      common()->Phi((signedness == kSigned) ? kMachInt32 : kMachUint32, 2),
18242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org      change, number, merge);
1835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return Replace(phi);
1855e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
1865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgReduction ChangeLowering::ChangeTaggedToFloat64(Node* val, Node* control) {
1895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  STATIC_ASSERT(kSmiTag == 0);
1905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  STATIC_ASSERT(kSmiTagMask == 1);
1915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1925e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* tag = graph()->NewNode(machine()->WordAnd(), val,
1935e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                               jsgraph()->Int32Constant(kSmiTagMask));
1945e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* branch = graph()->NewNode(common()->Branch(), tag, control);
1955e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
197e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* load = LoadHeapNumberValue(val, if_true);
1985e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
200e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* number = graph()->NewNode(machine()->ChangeInt32ToFloat64(),
201e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org                                  ChangeSmiToInt32(val));
2025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
2035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
20442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Node* phi =
20542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org      graph()->NewNode(common()->Phi(kMachFloat64, 2), load, number, merge);
2065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
2075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return Replace(phi);
2085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
2095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
2105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
211e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgReduction ChangeLowering::ChangeUint32ToTagged(Node* val, Node* control) {
212e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  STATIC_ASSERT(kSmiTag == 0);
213e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  STATIC_ASSERT(kSmiTagMask == 1);
214e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
215e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* cmp = graph()->NewNode(machine()->Uint32LessThanOrEqual(), val,
216e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org                               SmiMaxValueConstant());
217e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* branch = graph()->NewNode(common()->Branch(), cmp, control);
218e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
219e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
220e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* smi = graph()->NewNode(
221e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      machine()->WordShl(),
2226313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      machine()->Is64()
223e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          ? graph()->NewNode(machine()->ChangeUint32ToUint64(), val)
224e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          : val,
225e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      SmiShiftBitsConstant());
226e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
227e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
228e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* heap_number = AllocateHeapNumberWithValue(
229e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      graph()->NewNode(machine()->ChangeUint32ToFloat64(), val), if_false);
230e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
231e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
23242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), smi,
23342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org                               heap_number, merge);
234e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
235e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  return Replace(phi);
236e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
237e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
238e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
2395e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgIsolate* ChangeLowering::isolate() const { return jsgraph()->isolate(); }
2405e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
2415e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
2425e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgGraph* ChangeLowering::graph() const { return jsgraph()->graph(); }
2435e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
2445e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
2455e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgCommonOperatorBuilder* ChangeLowering::common() const {
2465e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return jsgraph()->common();
2475e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
2485e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
249d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org
250d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.orgMachineOperatorBuilder* ChangeLowering::machine() const {
251d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  return jsgraph()->machine();
252d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org}
253d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org
2545e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}  // namespace compiler
2555e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}  // namespace internal
2565e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}  // namespace v8
257