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