1109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// found in the LICENSE file.
4109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
5109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/int64-lowering.h"
6109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/common-operator.h"
73b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#include "src/compiler/diamond.h"
8109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/graph.h"
9109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/linkage.h"
10109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/machine-operator.h"
113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#include "src/compiler/node-matchers.h"
12109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/node-properties.h"
13109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
14109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/node.h"
1562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h"
16109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/wasm/wasm-module.h"
17f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/zone/zone.h"
18109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
19109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace v8 {
20109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace internal {
21109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace compiler {
22109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
23109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochInt64Lowering::Int64Lowering(Graph* graph, MachineOperatorBuilder* machine,
24109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                             CommonOperatorBuilder* common, Zone* zone,
25109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                             Signature<MachineRepresentation>* signature)
26109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    : zone_(zone),
27109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      graph_(graph),
28109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      machine_(machine),
29109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      common_(common),
303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      state_(graph, 3),
31109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      stack_(zone),
323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      replacements_(nullptr),
333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      signature_(signature),
343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      placeholder_(graph->NewNode(common->Parameter(-2, "placeholder"),
353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                  graph->start())) {
3613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK_NOT_NULL(graph);
3713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK_NOT_NULL(graph->end());
383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  replacements_ = zone->NewArray<Replacement>(graph->NodeCount());
39109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount());
40109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
41109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
42109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid Int64Lowering::LowerGraph() {
433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (!machine()->Is32()) {
44109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return;
45109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  stack_.push_back({graph()->end(), 0});
47109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  state_.Set(graph()->end(), State::kOnStack);
48109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
49109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  while (!stack_.empty()) {
503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    NodeState& top = stack_.back();
513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (top.input_index == top.node->InputCount()) {
523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // All inputs of top have already been lowered, now lower top.
533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      stack_.pop_back();
543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      state_.Set(top.node, State::kVisited);
553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      LowerNode(top.node);
56109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    } else {
573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // Push the next input onto the stack.
583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* input = top.node->InputAt(top.input_index++);
593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (state_.Get(input) == State::kUnvisited) {
603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (input->opcode() == IrOpcode::kPhi) {
613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          // To break cycles with phi nodes we push phis on a separate stack so
623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          // that they are processed after all other nodes.
633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          PreparePhiReplacement(input);
643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          stack_.push_front({input, 0});
6562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        } else if (input->opcode() == IrOpcode::kEffectPhi ||
6662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                   input->opcode() == IrOpcode::kLoop) {
67c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          stack_.push_front({input, 0});
683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        } else {
693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          stack_.push_back({input, 0});
70109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        }
713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        state_.Set(input, State::kOnStack);
72109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
73109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
74109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
75109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
76109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
77109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochstatic int GetParameterIndexAfterLowering(
78109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Signature<MachineRepresentation>* signature, int old_index) {
79109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int result = old_index;
80109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (int i = 0; i < old_index; i++) {
81109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (signature->GetParam(i) == MachineRepresentation::kWord64) {
82109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      result++;
83109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
84109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
85109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return result;
86109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
87109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
88bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochint Int64Lowering::GetParameterCountAfterLowering(
89109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Signature<MachineRepresentation>* signature) {
90bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // GetParameterIndexAfterLowering(parameter_count) returns the parameter count
91bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // after lowering.
92109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return GetParameterIndexAfterLowering(
93109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      signature, static_cast<int>(signature->parameter_count()));
94109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
95109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
96109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochstatic int GetReturnCountAfterLowering(
97109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Signature<MachineRepresentation>* signature) {
98109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int result = static_cast<int>(signature->return_count());
99109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (int i = 0; i < static_cast<int>(signature->return_count()); i++) {
100109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (signature->GetReturn(i) == MachineRepresentation::kWord64) {
101109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      result++;
102109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
103109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
104109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return result;
105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
10713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Int64Lowering::GetIndexNodes(Node* index, Node*& index_low,
10813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                  Node*& index_high) {
10962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (HasReplacementLow(index)) {
11062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    index = GetReplacementLow(index);
11162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
11213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(V8_TARGET_LITTLE_ENDIAN)
11313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  index_low = index;
11413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  index_high = graph()->NewNode(machine()->Int32Add(), index,
11513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                graph()->NewNode(common()->Int32Constant(4)));
11613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif defined(V8_TARGET_BIG_ENDIAN)
11713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  index_low = graph()->NewNode(machine()->Int32Add(), index,
11813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                               graph()->NewNode(common()->Int32Constant(4)));
11913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  index_high = index;
12013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif
12113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
12213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
12313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(V8_TARGET_LITTLE_ENDIAN)
12413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochconst int Int64Lowering::kLowerWordOffset = 0;
12513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochconst int Int64Lowering::kHigherWordOffset = 4;
12613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif defined(V8_TARGET_BIG_ENDIAN)
12713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochconst int Int64Lowering::kLowerWordOffset = 4;
12813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochconst int Int64Lowering::kHigherWordOffset = 0;
12913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif
13013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
131109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid Int64Lowering::LowerNode(Node* node) {
132109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  switch (node->opcode()) {
133109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case IrOpcode::kInt64Constant: {
134109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      int64_t value = OpParameter<int64_t>(node);
135109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Node* low_node = graph()->NewNode(
136109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          common()->Int32Constant(static_cast<int32_t>(value & 0xFFFFFFFF)));
137109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Node* high_node = graph()->NewNode(
138109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          common()->Int32Constant(static_cast<int32_t>(value >> 32)));
139109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      ReplaceNode(node, low_node, high_node);
140109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
141109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case IrOpcode::kLoad:
143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case IrOpcode::kUnalignedLoad: {
144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MachineRepresentation rep;
145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (node->opcode() == IrOpcode::kLoad) {
146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        rep = LoadRepresentationOf(node->op()).representation();
147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        DCHECK(node->opcode() == IrOpcode::kUnalignedLoad);
149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        rep = UnalignedLoadRepresentationOf(node->op()).representation();
150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
151109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (rep == MachineRepresentation::kWord64) {
153109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        Node* base = node->InputAt(0);
154109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        Node* index = node->InputAt(1);
15513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Node* index_low;
15613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Node* index_high;
15713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        GetIndexNodes(index, index_low, index_high);
158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        const Operator* load_op;
159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (node->opcode() == IrOpcode::kLoad) {
161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          load_op = machine()->Load(MachineType::Int32());
162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        } else {
163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          DCHECK(node->opcode() == IrOpcode::kUnalignedLoad);
164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          load_op = machine()->UnalignedLoad(MachineType::Int32());
165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
167109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        Node* high_node;
168109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (node->InputCount() > 2) {
169109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          Node* effect_high = node->InputAt(2);
170109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          Node* control_high = node->InputAt(3);
171109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          high_node = graph()->NewNode(load_op, base, index_high, effect_high,
172109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                       control_high);
173109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // change the effect change from old_node --> old_effect to
174109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // old_node --> high_node --> old_effect.
175109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          node->ReplaceInput(2, high_node);
176109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        } else {
177109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          high_node = graph()->NewNode(load_op, base, index_high);
178109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        }
17913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        node->ReplaceInput(1, index_low);
180109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        NodeProperties::ChangeOp(node, load_op);
181109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        ReplaceNode(node, node, high_node);
1823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {
1833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        DefaultLowering(node);
184109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
185109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
186109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case IrOpcode::kStore:
188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case IrOpcode::kUnalignedStore: {
189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MachineRepresentation rep;
190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (node->opcode() == IrOpcode::kStore) {
191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        rep = StoreRepresentationOf(node->op()).representation();
192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        DCHECK(node->opcode() == IrOpcode::kUnalignedStore);
194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        rep = UnalignedStoreRepresentationOf(node->op());
195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (rep == MachineRepresentation::kWord64) {
198109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // We change the original store node to store the low word, and create
199109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // a new store node to store the high word. The effect and control edges
200109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // are copied from the original store to the new store node, the effect
201109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // edge of the original store is redirected to the new store.
202109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        Node* base = node->InputAt(0);
203109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        Node* index = node->InputAt(1);
20413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Node* index_low;
20513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Node* index_high;
20613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        GetIndexNodes(index, index_low, index_high);
207109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        Node* value = node->InputAt(2);
208109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DCHECK(HasReplacementLow(value));
209109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DCHECK(HasReplacementHigh(value));
210109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        const Operator* store_op;
212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (node->opcode() == IrOpcode::kStore) {
213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          WriteBarrierKind write_barrier_kind =
214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              StoreRepresentationOf(node->op()).write_barrier_kind();
215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          store_op = machine()->Store(StoreRepresentation(
216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              MachineRepresentation::kWord32, write_barrier_kind));
217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        } else {
218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          DCHECK(node->opcode() == IrOpcode::kUnalignedStore);
219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          store_op = machine()->UnalignedStore(MachineRepresentation::kWord32);
220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
221109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
222109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        Node* high_node;
223109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (node->InputCount() > 3) {
224109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          Node* effect_high = node->InputAt(3);
225109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          Node* control_high = node->InputAt(4);
226109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          high_node = graph()->NewNode(store_op, base, index_high,
227109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                       GetReplacementHigh(value), effect_high,
228109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                       control_high);
229109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          node->ReplaceInput(3, high_node);
230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
231109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        } else {
232109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          high_node = graph()->NewNode(store_op, base, index_high,
233109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                       GetReplacementHigh(value));
234109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        }
235109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
23613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        node->ReplaceInput(1, index_low);
237109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        node->ReplaceInput(2, GetReplacementLow(value));
238109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        NodeProperties::ChangeOp(node, store_op);
239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        ReplaceNode(node, node, high_node);
2403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {
24162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        DefaultLowering(node, true);
242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
243109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
244109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
245109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case IrOpcode::kStart: {
246109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      int parameter_count = GetParameterCountAfterLowering(signature());
247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Only exchange the node if the parameter count actually changed.
248c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (parameter_count != static_cast<int>(signature()->parameter_count())) {
249109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        int delta =
250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            parameter_count - static_cast<int>(signature()->parameter_count());
251109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        int new_output_count = node->op()->ValueOutputCount() + delta;
252109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        NodeProperties::ChangeOp(node, common()->Start(new_output_count));
253109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
254109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
255109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
256109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case IrOpcode::kParameter: {
257109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      DCHECK(node->InputCount() == 1);
258109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Only exchange the node if the parameter count actually changed. We do
259109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // not even have to do the default lowering because the the start node,
260109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // the only input of a parameter node, only changes if the parameter count
261109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // changes.
262109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (GetParameterCountAfterLowering(signature()) !=
263c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          static_cast<int>(signature()->parameter_count())) {
264109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        int old_index = ParameterIndexOf(node->op());
265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        int new_index = GetParameterIndexAfterLowering(signature(), old_index);
266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        NodeProperties::ChangeOp(node, common()->Parameter(new_index));
267109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
268109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        Node* high_node = nullptr;
269109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (signature()->GetParam(old_index) ==
270109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            MachineRepresentation::kWord64) {
271109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          high_node = graph()->NewNode(common()->Parameter(new_index + 1),
272109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                       graph()->start());
273109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        }
274109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        ReplaceNode(node, node, high_node);
275109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
276109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
277109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
278109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case IrOpcode::kReturn: {
279109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      DefaultLowering(node);
280109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      int new_return_count = GetReturnCountAfterLowering(signature());
281c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (static_cast<int>(signature()->return_count()) != new_return_count) {
282109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        NodeProperties::ChangeOp(node, common()->Return(new_return_count));
283109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
284109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
285109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
286109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case IrOpcode::kCall: {
287bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      // TODO(turbofan): Make WASM code const-correct wrt. CallDescriptor.
288bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CallDescriptor* descriptor =
289bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          const_cast<CallDescriptor*>(CallDescriptorOf(node->op()));
290109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (DefaultLowering(node) ||
291109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          (descriptor->ReturnCount() == 1 &&
292109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           descriptor->GetReturnType(0) == MachineType::Int64())) {
293109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // We have to adjust the call descriptor.
294109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        const Operator* op = common()->Call(
295109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            wasm::ModuleEnv::GetI32WasmCallDescriptor(zone(), descriptor));
296109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        NodeProperties::ChangeOp(node, op);
297109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
298109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (descriptor->ReturnCount() == 1 &&
299109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          descriptor->GetReturnType(0) == MachineType::Int64()) {
300109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // We access the additional return values through projections.
30113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Node* low_node =
30213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            graph()->NewNode(common()->Projection(0), node, graph()->start());
30313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Node* high_node =
30413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            graph()->NewNode(common()->Projection(1), node, graph()->start());
305109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        ReplaceNode(node, low_node, high_node);
306109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
307109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
308109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
3093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kWord64And: {
3103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 2);
3113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* left = node->InputAt(0);
3123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* right = node->InputAt(1);
3133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* low_node =
3153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(machine()->Word32And(), GetReplacementLow(left),
3163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           GetReplacementLow(right));
3173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* high_node =
3183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(machine()->Word32And(), GetReplacementHigh(left),
3193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           GetReplacementHigh(right));
3203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, low_node, high_node);
3213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
3223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
3233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kTruncateInt64ToInt32: {
3243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 1);
3253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* input = node->InputAt(0);
3263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, GetReplacementLow(input), nullptr);
3273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->NullAllInputs();
3283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
3293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
3303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kInt64Add: {
3313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 2);
3323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* right = node->InputAt(1);
3343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->ReplaceInput(1, GetReplacementLow(right));
3353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->AppendInput(zone(), GetReplacementHigh(right));
3363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* left = node->InputAt(0);
3383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->ReplaceInput(0, GetReplacementLow(left));
3393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->InsertInput(zone(), 1, GetReplacementHigh(left));
3403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      NodeProperties::ChangeOp(node, machine()->Int32PairAdd());
3423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // We access the additional return values through projections.
34313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* low_node =
34413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Projection(0), node, graph()->start());
34513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* high_node =
34613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Projection(1), node, graph()->start());
3473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, low_node, high_node);
3483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
3493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
3503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kInt64Sub: {
3513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 2);
3523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* right = node->InputAt(1);
3543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->ReplaceInput(1, GetReplacementLow(right));
3553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->AppendInput(zone(), GetReplacementHigh(right));
3563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* left = node->InputAt(0);
3583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->ReplaceInput(0, GetReplacementLow(left));
3593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->InsertInput(zone(), 1, GetReplacementHigh(left));
3603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      NodeProperties::ChangeOp(node, machine()->Int32PairSub());
3623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // We access the additional return values through projections.
36313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* low_node =
36413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Projection(0), node, graph()->start());
36513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* high_node =
36613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Projection(1), node, graph()->start());
3673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, low_node, high_node);
3683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
3693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
3703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kInt64Mul: {
3713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 2);
3723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* right = node->InputAt(1);
3743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->ReplaceInput(1, GetReplacementLow(right));
3753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->AppendInput(zone(), GetReplacementHigh(right));
3763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* left = node->InputAt(0);
3783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->ReplaceInput(0, GetReplacementLow(left));
3793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->InsertInput(zone(), 1, GetReplacementHigh(left));
3803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      NodeProperties::ChangeOp(node, machine()->Int32PairMul());
3823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // We access the additional return values through projections.
38313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* low_node =
38413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Projection(0), node, graph()->start());
38513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* high_node =
38613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Projection(1), node, graph()->start());
3873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, low_node, high_node);
3883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
3893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
3903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kWord64Or: {
3913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 2);
3923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* left = node->InputAt(0);
3933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* right = node->InputAt(1);
3943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* low_node =
3963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(machine()->Word32Or(), GetReplacementLow(left),
3973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           GetReplacementLow(right));
3983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* high_node =
3993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(machine()->Word32Or(), GetReplacementHigh(left),
4003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           GetReplacementHigh(right));
4013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, low_node, high_node);
4023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
4033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
4043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kWord64Xor: {
4053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 2);
4063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* left = node->InputAt(0);
4073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* right = node->InputAt(1);
4083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* low_node =
4103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(machine()->Word32Xor(), GetReplacementLow(left),
4113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           GetReplacementLow(right));
4123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* high_node =
4133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(machine()->Word32Xor(), GetReplacementHigh(left),
4143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           GetReplacementHigh(right));
4153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, low_node, high_node);
4163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
4173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
4183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kWord64Shl: {
4193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // TODO(turbofan): if the shift count >= 32, then we can set the low word
4203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // of the output to 0 and just calculate the high word.
4213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 2);
4223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* shift = node->InputAt(1);
4233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (HasReplacementLow(shift)) {
4243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // We do not have to care about the high word replacement, because
4253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // the shift can only be between 0 and 63 anyways.
4263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        node->ReplaceInput(1, GetReplacementLow(shift));
4273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
4283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* value = node->InputAt(0);
4303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->ReplaceInput(0, GetReplacementLow(value));
4313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->InsertInput(zone(), 1, GetReplacementHigh(value));
4323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      NodeProperties::ChangeOp(node, machine()->Word32PairShl());
4343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // We access the additional return values through projections.
43513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* low_node =
43613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Projection(0), node, graph()->start());
43713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* high_node =
43813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Projection(1), node, graph()->start());
4393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, low_node, high_node);
4403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
4413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
4423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kWord64Shr: {
4433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // TODO(turbofan): if the shift count >= 32, then we can set the low word
4443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // of the output to 0 and just calculate the high word.
4453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 2);
4463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* shift = node->InputAt(1);
4473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (HasReplacementLow(shift)) {
4483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // We do not have to care about the high word replacement, because
4493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // the shift can only be between 0 and 63 anyways.
4503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        node->ReplaceInput(1, GetReplacementLow(shift));
4513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
4523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* value = node->InputAt(0);
4543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->ReplaceInput(0, GetReplacementLow(value));
4553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->InsertInput(zone(), 1, GetReplacementHigh(value));
4563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      NodeProperties::ChangeOp(node, machine()->Word32PairShr());
4583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // We access the additional return values through projections.
45913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* low_node =
46013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Projection(0), node, graph()->start());
46113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* high_node =
46213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Projection(1), node, graph()->start());
4633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, low_node, high_node);
4643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
4653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
4663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kWord64Sar: {
4673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // TODO(turbofan): if the shift count >= 32, then we can set the low word
4683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // of the output to 0 and just calculate the high word.
4693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 2);
4703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* shift = node->InputAt(1);
4713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (HasReplacementLow(shift)) {
4723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // We do not have to care about the high word replacement, because
4733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // the shift can only be between 0 and 63 anyways.
4743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        node->ReplaceInput(1, GetReplacementLow(shift));
4753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
4763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* value = node->InputAt(0);
4783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->ReplaceInput(0, GetReplacementLow(value));
4793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->InsertInput(zone(), 1, GetReplacementHigh(value));
4803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      NodeProperties::ChangeOp(node, machine()->Word32PairSar());
4823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // We access the additional return values through projections.
48313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* low_node =
48413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Projection(0), node, graph()->start());
48513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* high_node =
48613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Projection(1), node, graph()->start());
4873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, low_node, high_node);
4883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
4893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
4903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kWord64Equal: {
4913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 2);
4923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* left = node->InputAt(0);
4933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* right = node->InputAt(1);
4943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // TODO(wasm): Use explicit comparisons and && here?
4963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* replacement = graph()->NewNode(
4973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          machine()->Word32Equal(),
4983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(
4993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              machine()->Word32Or(),
5003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              graph()->NewNode(machine()->Word32Xor(), GetReplacementLow(left),
5013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                               GetReplacementLow(right)),
5023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              graph()->NewNode(machine()->Word32Xor(), GetReplacementHigh(left),
5033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                               GetReplacementHigh(right))),
5043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(common()->Int32Constant(0)));
5053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
5063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, replacement, nullptr);
5073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
5083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
5093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kInt64LessThan: {
5103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      LowerComparison(node, machine()->Int32LessThan(),
5113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      machine()->Uint32LessThan());
5123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
5133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
5143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kInt64LessThanOrEqual: {
5153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      LowerComparison(node, machine()->Int32LessThan(),
5163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      machine()->Uint32LessThanOrEqual());
5173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
5183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
5193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kUint64LessThan: {
5203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      LowerComparison(node, machine()->Uint32LessThan(),
5213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      machine()->Uint32LessThan());
5223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
5233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
5243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kUint64LessThanOrEqual: {
5253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      LowerComparison(node, machine()->Uint32LessThan(),
5263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      machine()->Uint32LessThanOrEqual());
5273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
5283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
5293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kChangeInt32ToInt64: {
5303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 1);
5313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* input = node->InputAt(0);
5323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (HasReplacementLow(input)) {
5333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        input = GetReplacementLow(input);
5343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
5353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // We use SAR to preserve the sign in the high word.
5363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(
5373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          node, input,
5383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(machine()->Word32Sar(), input,
5393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           graph()->NewNode(common()->Int32Constant(31))));
5403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->NullAllInputs();
5413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
5423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
5433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kChangeUint32ToUint64: {
5443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 1);
5453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* input = node->InputAt(0);
5463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (HasReplacementLow(input)) {
5473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        input = GetReplacementLow(input);
5483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
5493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, input, graph()->NewNode(common()->Int32Constant(0)));
5503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      node->NullAllInputs();
5513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
5523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
5533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kBitcastInt64ToFloat64: {
5543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 1);
5553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* input = node->InputAt(0);
5563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* stack_slot = graph()->NewNode(
5573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          machine()->StackSlot(MachineRepresentation::kWord64));
5583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
5593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* store_high_word = graph()->NewNode(
5603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          machine()->Store(
5613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              StoreRepresentation(MachineRepresentation::kWord32,
5623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                  WriteBarrierKind::kNoWriteBarrier)),
56313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          stack_slot,
56413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Int32Constant(kHigherWordOffset)),
5653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          GetReplacementHigh(input), graph()->start(), graph()->start());
5663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
5673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* store_low_word = graph()->NewNode(
5683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          machine()->Store(
5693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              StoreRepresentation(MachineRepresentation::kWord32,
5703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                  WriteBarrierKind::kNoWriteBarrier)),
57113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          stack_slot,
57213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Int32Constant(kLowerWordOffset)),
5733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          GetReplacementLow(input), store_high_word, graph()->start());
5743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
5753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* load =
5763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(machine()->Load(MachineType::Float64()), stack_slot,
5773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           graph()->NewNode(common()->Int32Constant(0)),
5783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           store_low_word, graph()->start());
5793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
5803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, load, nullptr);
5813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
5823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
5833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kBitcastFloat64ToInt64: {
5843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 1);
5853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* input = node->InputAt(0);
5863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (HasReplacementLow(input)) {
5873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        input = GetReplacementLow(input);
5883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
5893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* stack_slot = graph()->NewNode(
5903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          machine()->StackSlot(MachineRepresentation::kWord64));
5913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* store = graph()->NewNode(
5923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          machine()->Store(
5933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              StoreRepresentation(MachineRepresentation::kFloat64,
5943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                  WriteBarrierKind::kNoWriteBarrier)),
5953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          stack_slot, graph()->NewNode(common()->Int32Constant(0)), input,
5963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->start(), graph()->start());
5973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
59813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* high_node = graph()->NewNode(
59913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          machine()->Load(MachineType::Int32()), stack_slot,
60013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Int32Constant(kHigherWordOffset)), store,
60113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->start());
6023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
60313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* low_node = graph()->NewNode(
60413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          machine()->Load(MachineType::Int32()), stack_slot,
60513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->NewNode(common()->Int32Constant(kLowerWordOffset)), store,
60613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          graph()->start());
6073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, low_node, high_node);
6083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
6093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
6103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kWord64Ror: {
6113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 2);
6123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* input = node->InputAt(0);
6133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* shift = HasReplacementLow(node->InputAt(1))
6143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                        ? GetReplacementLow(node->InputAt(1))
6153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                        : node->InputAt(1);
6163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Int32Matcher m(shift);
6173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (m.HasValue()) {
6183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // Precondition: 0 <= shift < 64.
6193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        int32_t shift_value = m.Value() & 0x3f;
6203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (shift_value == 0) {
6213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          ReplaceNode(node, GetReplacementLow(input),
6223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      GetReplacementHigh(input));
6233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        } else if (shift_value == 32) {
6243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          ReplaceNode(node, GetReplacementHigh(input),
6253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      GetReplacementLow(input));
6263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        } else {
6273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          Node* low_input;
6283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          Node* high_input;
6293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          if (shift_value < 32) {
6303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            low_input = GetReplacementLow(input);
6313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            high_input = GetReplacementHigh(input);
6323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          } else {
6333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            low_input = GetReplacementHigh(input);
6343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            high_input = GetReplacementLow(input);
6353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          }
6363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          int32_t masked_shift_value = shift_value & 0x1f;
6373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          Node* masked_shift =
6383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              graph()->NewNode(common()->Int32Constant(masked_shift_value));
6393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          Node* inv_shift = graph()->NewNode(
6403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              common()->Int32Constant(32 - masked_shift_value));
6413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
6423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          Node* low_node = graph()->NewNode(
6433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              machine()->Word32Or(),
6443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              graph()->NewNode(machine()->Word32Shr(), low_input, masked_shift),
6453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              graph()->NewNode(machine()->Word32Shl(), high_input, inv_shift));
6463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          Node* high_node = graph()->NewNode(
6473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              machine()->Word32Or(), graph()->NewNode(machine()->Word32Shr(),
6483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                      high_input, masked_shift),
6493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              graph()->NewNode(machine()->Word32Shl(), low_input, inv_shift));
6503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          ReplaceNode(node, low_node, high_node);
6513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
6523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {
6533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Node* safe_shift = shift;
6543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (!machine()->Word32ShiftIsSafe()) {
6553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          safe_shift =
6563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              graph()->NewNode(machine()->Word32And(), shift,
6573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                               graph()->NewNode(common()->Int32Constant(0x1f)));
6583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
6593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
6603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // By creating this bit-mask with SAR and SHL we do not have to deal
6613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // with shift == 0 as a special case.
6623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Node* inv_mask = graph()->NewNode(
6633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            machine()->Word32Shl(),
6643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            graph()->NewNode(machine()->Word32Sar(),
6653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                             graph()->NewNode(common()->Int32Constant(
6663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                 std::numeric_limits<int32_t>::min())),
6673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                             safe_shift),
6683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            graph()->NewNode(common()->Int32Constant(1)));
6693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
6703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Node* bit_mask =
6713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            graph()->NewNode(machine()->Word32Xor(), inv_mask,
6723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                             graph()->NewNode(common()->Int32Constant(-1)));
6733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
6743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // We have to mask the shift value for this comparison. If
6753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // !machine()->Word32ShiftIsSafe() then the masking should already be
6763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // part of the graph.
6773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Node* masked_shift6 = shift;
6783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (machine()->Word32ShiftIsSafe()) {
6793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          masked_shift6 =
6803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              graph()->NewNode(machine()->Word32And(), shift,
6813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                               graph()->NewNode(common()->Int32Constant(0x3f)));
6823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
6833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
6843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Diamond lt32(
6853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            graph(), common(),
6863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            graph()->NewNode(machine()->Int32LessThan(), masked_shift6,
6873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                             graph()->NewNode(common()->Int32Constant(32))));
6883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
6893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // The low word and the high word can be swapped either at the input or
6903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // at the output. We swap the inputs so that shift does not have to be
6913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // kept for so long in a register.
6923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Node* input_low =
6933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            lt32.Phi(MachineRepresentation::kWord32, GetReplacementLow(input),
6943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                     GetReplacementHigh(input));
6953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Node* input_high =
6963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            lt32.Phi(MachineRepresentation::kWord32, GetReplacementHigh(input),
6973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                     GetReplacementLow(input));
6983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
6993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Node* rotate_low =
7003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            graph()->NewNode(machine()->Word32Ror(), input_low, safe_shift);
7013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Node* rotate_high =
7023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            graph()->NewNode(machine()->Word32Ror(), input_high, safe_shift);
7033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
7043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Node* low_node = graph()->NewNode(
7053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            machine()->Word32Or(),
7063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            graph()->NewNode(machine()->Word32And(), rotate_low, bit_mask),
7073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            graph()->NewNode(machine()->Word32And(), rotate_high, inv_mask));
7083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
7093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Node* high_node = graph()->NewNode(
7103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            machine()->Word32Or(),
7113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            graph()->NewNode(machine()->Word32And(), rotate_high, bit_mask),
7123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            graph()->NewNode(machine()->Word32And(), rotate_low, inv_mask));
7133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
7143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        ReplaceNode(node, low_node, high_node);
7153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
7163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
7173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
7183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kWord64Clz: {
7193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 1);
7203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* input = node->InputAt(0);
7213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Diamond d(
7223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph(), common(),
7233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(machine()->Word32Equal(), GetReplacementHigh(input),
7243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           graph()->NewNode(common()->Int32Constant(0))));
7253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
7263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* low_node = d.Phi(
7273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          MachineRepresentation::kWord32,
7283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(machine()->Int32Add(),
7293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           graph()->NewNode(machine()->Word32Clz(),
7303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                            GetReplacementLow(input)),
7313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           graph()->NewNode(common()->Int32Constant(32))),
7323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(machine()->Word32Clz(), GetReplacementHigh(input)));
7333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, low_node, graph()->NewNode(common()->Int32Constant(0)));
7343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
7353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
7363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kWord64Ctz: {
7373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 1);
7383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(machine()->Word32Ctz().IsSupported());
7393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* input = node->InputAt(0);
7403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Diamond d(
7413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph(), common(),
7423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(machine()->Word32Equal(), GetReplacementLow(input),
7433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           graph()->NewNode(common()->Int32Constant(0))));
7443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* low_node =
7453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          d.Phi(MachineRepresentation::kWord32,
7463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                graph()->NewNode(machine()->Int32Add(),
7473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                 graph()->NewNode(machine()->Word32Ctz().op(),
7483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                  GetReplacementHigh(input)),
7493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                 graph()->NewNode(common()->Int32Constant(32))),
7503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                graph()->NewNode(machine()->Word32Ctz().op(),
7513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                 GetReplacementLow(input)));
7523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, low_node, graph()->NewNode(common()->Int32Constant(0)));
7533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
7543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
7553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kWord64Popcnt: {
7563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(node->InputCount() == 1);
7573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Node* input = node->InputAt(0);
7583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // We assume that a Word64Popcnt node only has been created if
7593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // Word32Popcnt is actually supported.
7603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(machine()->Word32Popcnt().IsSupported());
7613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ReplaceNode(node, graph()->NewNode(
7623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                            machine()->Int32Add(),
7633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                            graph()->NewNode(machine()->Word32Popcnt().op(),
7643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                             GetReplacementLow(input)),
7653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                            graph()->NewNode(machine()->Word32Popcnt().op(),
7663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                             GetReplacementHigh(input))),
7673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                  graph()->NewNode(common()->Int32Constant(0)));
7683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
7693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
7703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kPhi: {
7713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      MachineRepresentation rep = PhiRepresentationOf(node->op());
7723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (rep == MachineRepresentation::kWord64) {
7733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // The replacement nodes have already been created, we only have to
7743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // replace placeholder nodes.
7753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Node* low_node = GetReplacementLow(node);
7763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Node* high_node = GetReplacementHigh(node);
7773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        for (int i = 0; i < node->op()->ValueInputCount(); i++) {
7783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          low_node->ReplaceInput(i, GetReplacementLow(node->InputAt(i)));
7793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          high_node->ReplaceInput(i, GetReplacementHigh(node->InputAt(i)));
7803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
7813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {
7823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        DefaultLowering(node);
7833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
7843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
7853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
786f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case IrOpcode::kProjection: {
787f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Node* call = node->InputAt(0);
788f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DCHECK_EQ(IrOpcode::kCall, call->opcode());
789f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      CallDescriptor* descriptor =
790f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          const_cast<CallDescriptor*>(CallDescriptorOf(call->op()));
791f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      for (size_t i = 0; i < descriptor->ReturnCount(); i++) {
792f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (descriptor->GetReturnType(i) == MachineType::Int64()) {
793f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          UNREACHABLE();  // TODO(titzer): implement multiple i64 returns.
794f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
795f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
796f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
797f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
798f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case IrOpcode::kWord64ReverseBytes: {
799f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Node* input = node->InputAt(0);
800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ReplaceNode(node, graph()->NewNode(machine()->Word32ReverseBytes().op(),
801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         GetReplacementHigh(input)),
802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                  graph()->NewNode(machine()->Word32ReverseBytes().op(),
803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                   GetReplacementLow(input)));
804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
8063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
807109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    default: { DefaultLowering(node); }
808109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
8093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}  // NOLINT(readability/fn_size)
8103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
8113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Int64Lowering::LowerComparison(Node* node, const Operator* high_word_op,
8123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                    const Operator* low_word_op) {
8133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(node->InputCount() == 2);
8143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Node* left = node->InputAt(0);
8153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Node* right = node->InputAt(1);
8163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Node* replacement = graph()->NewNode(
8173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      machine()->Word32Or(),
8183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      graph()->NewNode(high_word_op, GetReplacementHigh(left),
8193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                       GetReplacementHigh(right)),
8203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      graph()->NewNode(
8213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          machine()->Word32And(),
8223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(machine()->Word32Equal(), GetReplacementHigh(left),
8233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           GetReplacementHigh(right)),
8243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          graph()->NewNode(low_word_op, GetReplacementLow(left),
8253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           GetReplacementLow(right))));
8263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
8273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  ReplaceNode(node, replacement, nullptr);
828109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
829109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
83062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool Int64Lowering::DefaultLowering(Node* node, bool low_word_only) {
831109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool something_changed = false;
832109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) {
833109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Node* input = node->InputAt(i);
834109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (HasReplacementLow(input)) {
835109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      something_changed = true;
836109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      node->ReplaceInput(i, GetReplacementLow(input));
837109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
83862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!low_word_only && HasReplacementHigh(input)) {
839109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      something_changed = true;
840109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      node->InsertInput(zone(), i + 1, GetReplacementHigh(input));
841109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
842109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
843109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return something_changed;
844109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
845109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
846109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid Int64Lowering::ReplaceNode(Node* old, Node* new_low, Node* new_high) {
847109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // if new_low == nullptr, then also new_high == nullptr.
848109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(new_low != nullptr || new_high == nullptr);
849109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  replacements_[old->id()].low = new_low;
850109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  replacements_[old->id()].high = new_high;
851109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
852109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
853109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool Int64Lowering::HasReplacementLow(Node* node) {
854109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return replacements_[node->id()].low != nullptr;
855109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
856109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
857109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* Int64Lowering::GetReplacementLow(Node* node) {
858109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Node* result = replacements_[node->id()].low;
859109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(result);
860109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return result;
861109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
862109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
863109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool Int64Lowering::HasReplacementHigh(Node* node) {
864109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return replacements_[node->id()].high != nullptr;
865109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
866109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
867109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* Int64Lowering::GetReplacementHigh(Node* node) {
868109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Node* result = replacements_[node->id()].high;
869109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(result);
870109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return result;
871109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
8723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
8733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Int64Lowering::PreparePhiReplacement(Node* phi) {
8743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  MachineRepresentation rep = PhiRepresentationOf(phi->op());
8753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (rep == MachineRepresentation::kWord64) {
8763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // We have to create the replacements for a phi node before we actually
8773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // lower the phi to break potential cycles in the graph. The replacements of
8783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // input nodes do not exist yet, so we use a placeholder node to pass the
8793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // graph verifier.
8803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    int value_count = phi->op()->ValueInputCount();
8813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Node** inputs_low = zone()->NewArray<Node*>(value_count + 1);
8823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Node** inputs_high = zone()->NewArray<Node*>(value_count + 1);
8833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    for (int i = 0; i < value_count; i++) {
8843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      inputs_low[i] = placeholder_;
8853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      inputs_high[i] = placeholder_;
8863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
8873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    inputs_low[value_count] = NodeProperties::GetControlInput(phi, 0);
8883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    inputs_high[value_count] = NodeProperties::GetControlInput(phi, 0);
8893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    ReplaceNode(phi,
8903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                graph()->NewNode(
8913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                    common()->Phi(MachineRepresentation::kWord32, value_count),
8923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                    value_count + 1, inputs_low, false),
8933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                graph()->NewNode(
8943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                    common()->Phi(MachineRepresentation::kWord32, value_count),
8953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                    value_count + 1, inputs_high, false));
8963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
8973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
898109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}  // namespace compiler
899109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}  // namespace internal
900109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}  // namespace v8
901