11cb0ef41Sopenharmony_ci// Copyright 2014 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/compiler/int64-lowering.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include "src/compiler/common-operator.h" 81cb0ef41Sopenharmony_ci#include "src/compiler/diamond.h" 91cb0ef41Sopenharmony_ci#include "src/compiler/graph.h" 101cb0ef41Sopenharmony_ci#include "src/compiler/linkage.h" 111cb0ef41Sopenharmony_ci#include "src/compiler/machine-operator.h" 121cb0ef41Sopenharmony_ci#include "src/compiler/node-matchers.h" 131cb0ef41Sopenharmony_ci#include "src/compiler/node-properties.h" 141cb0ef41Sopenharmony_ci#include "src/compiler/node.h" 151cb0ef41Sopenharmony_ci#include "src/compiler/wasm-compiler.h" 161cb0ef41Sopenharmony_ci// TODO(wasm): Remove this include. 171cb0ef41Sopenharmony_ci#include "src/wasm/wasm-linkage.h" 181cb0ef41Sopenharmony_ci#include "src/zone/zone.h" 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_cinamespace v8 { 211cb0ef41Sopenharmony_cinamespace internal { 221cb0ef41Sopenharmony_cinamespace compiler { 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ciInt64Lowering::Int64Lowering( 251cb0ef41Sopenharmony_ci Graph* graph, MachineOperatorBuilder* machine, 261cb0ef41Sopenharmony_ci CommonOperatorBuilder* common, SimplifiedOperatorBuilder* simplified, 271cb0ef41Sopenharmony_ci Zone* zone, Signature<MachineRepresentation>* signature, 281cb0ef41Sopenharmony_ci std::unique_ptr<Int64LoweringSpecialCase> special_case) 291cb0ef41Sopenharmony_ci : zone_(zone), 301cb0ef41Sopenharmony_ci graph_(graph), 311cb0ef41Sopenharmony_ci machine_(machine), 321cb0ef41Sopenharmony_ci common_(common), 331cb0ef41Sopenharmony_ci simplified_(simplified), 341cb0ef41Sopenharmony_ci state_(graph->NodeCount(), State::kUnvisited), 351cb0ef41Sopenharmony_ci stack_(zone), 361cb0ef41Sopenharmony_ci replacements_(nullptr), 371cb0ef41Sopenharmony_ci signature_(signature), 381cb0ef41Sopenharmony_ci placeholder_(graph->NewNode(common->Dead())), 391cb0ef41Sopenharmony_ci special_case_(std::move(special_case)) { 401cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(graph); 411cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(graph->end()); 421cb0ef41Sopenharmony_ci replacements_ = zone->NewArray<Replacement>(graph->NodeCount()); 431cb0ef41Sopenharmony_ci memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount()); 441cb0ef41Sopenharmony_ci} 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_civoid Int64Lowering::LowerGraph() { 471cb0ef41Sopenharmony_ci if (!machine()->Is32()) { 481cb0ef41Sopenharmony_ci return; 491cb0ef41Sopenharmony_ci } 501cb0ef41Sopenharmony_ci stack_.push_back({graph()->end(), 0}); 511cb0ef41Sopenharmony_ci state_[graph()->end()->id()] = State::kOnStack; 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci while (!stack_.empty()) { 541cb0ef41Sopenharmony_ci NodeState& top = stack_.back(); 551cb0ef41Sopenharmony_ci if (top.input_index == top.node->InputCount()) { 561cb0ef41Sopenharmony_ci // All inputs of top have already been lowered, now lower top. 571cb0ef41Sopenharmony_ci stack_.pop_back(); 581cb0ef41Sopenharmony_ci state_[top.node->id()] = State::kVisited; 591cb0ef41Sopenharmony_ci LowerNode(top.node); 601cb0ef41Sopenharmony_ci } else { 611cb0ef41Sopenharmony_ci // Push the next input onto the stack. 621cb0ef41Sopenharmony_ci Node* input = top.node->InputAt(top.input_index++); 631cb0ef41Sopenharmony_ci if (state_[input->id()] == State::kUnvisited) { 641cb0ef41Sopenharmony_ci if (input->opcode() == IrOpcode::kPhi) { 651cb0ef41Sopenharmony_ci // To break cycles with phi nodes we push phis on a separate stack so 661cb0ef41Sopenharmony_ci // that they are processed after all other nodes. 671cb0ef41Sopenharmony_ci PreparePhiReplacement(input); 681cb0ef41Sopenharmony_ci stack_.push_front({input, 0}); 691cb0ef41Sopenharmony_ci } else if (input->opcode() == IrOpcode::kEffectPhi || 701cb0ef41Sopenharmony_ci input->opcode() == IrOpcode::kLoop) { 711cb0ef41Sopenharmony_ci stack_.push_front({input, 0}); 721cb0ef41Sopenharmony_ci } else { 731cb0ef41Sopenharmony_ci stack_.push_back({input, 0}); 741cb0ef41Sopenharmony_ci } 751cb0ef41Sopenharmony_ci state_[input->id()] = State::kOnStack; 761cb0ef41Sopenharmony_ci } 771cb0ef41Sopenharmony_ci } 781cb0ef41Sopenharmony_ci } 791cb0ef41Sopenharmony_ci} 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_cinamespace { 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ciint GetReturnIndexAfterLowering(const CallDescriptor* call_descriptor, 841cb0ef41Sopenharmony_ci int old_index) { 851cb0ef41Sopenharmony_ci int result = old_index; 861cb0ef41Sopenharmony_ci for (int i = 0; i < old_index; i++) { 871cb0ef41Sopenharmony_ci if (call_descriptor->GetReturnType(i).representation() == 881cb0ef41Sopenharmony_ci MachineRepresentation::kWord64) { 891cb0ef41Sopenharmony_ci result++; 901cb0ef41Sopenharmony_ci } 911cb0ef41Sopenharmony_ci } 921cb0ef41Sopenharmony_ci return result; 931cb0ef41Sopenharmony_ci} 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ciint GetReturnCountAfterLowering(const CallDescriptor* call_descriptor) { 961cb0ef41Sopenharmony_ci return GetReturnIndexAfterLowering( 971cb0ef41Sopenharmony_ci call_descriptor, static_cast<int>(call_descriptor->ReturnCount())); 981cb0ef41Sopenharmony_ci} 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ciint GetParameterIndexAfterLowering( 1011cb0ef41Sopenharmony_ci Signature<MachineRepresentation>* signature, int old_index) { 1021cb0ef41Sopenharmony_ci int result = old_index; 1031cb0ef41Sopenharmony_ci // Be robust towards special indexes (>= param count). 1041cb0ef41Sopenharmony_ci int max_to_check = 1051cb0ef41Sopenharmony_ci std::min(old_index, static_cast<int>(signature->parameter_count())); 1061cb0ef41Sopenharmony_ci for (int i = 0; i < max_to_check; i++) { 1071cb0ef41Sopenharmony_ci if (signature->GetParam(i) == MachineRepresentation::kWord64) { 1081cb0ef41Sopenharmony_ci result++; 1091cb0ef41Sopenharmony_ci } 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci return result; 1121cb0ef41Sopenharmony_ci} 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ciint GetReturnCountAfterLowering(Signature<MachineRepresentation>* signature) { 1151cb0ef41Sopenharmony_ci int result = static_cast<int>(signature->return_count()); 1161cb0ef41Sopenharmony_ci for (int i = 0; i < static_cast<int>(signature->return_count()); i++) { 1171cb0ef41Sopenharmony_ci if (signature->GetReturn(i) == MachineRepresentation::kWord64) { 1181cb0ef41Sopenharmony_ci result++; 1191cb0ef41Sopenharmony_ci } 1201cb0ef41Sopenharmony_ci } 1211cb0ef41Sopenharmony_ci return result; 1221cb0ef41Sopenharmony_ci} 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ci} // namespace 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_civoid Int64Lowering::LowerWord64AtomicBinop(Node* node, const Operator* op) { 1271cb0ef41Sopenharmony_ci DCHECK_EQ(5, node->InputCount()); 1281cb0ef41Sopenharmony_ci LowerMemoryBaseAndIndex(node); 1291cb0ef41Sopenharmony_ci Node* value = node->InputAt(2); 1301cb0ef41Sopenharmony_ci node->ReplaceInput(2, GetReplacementLow(value)); 1311cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, GetReplacementHigh(value)); 1321cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, op); 1331cb0ef41Sopenharmony_ci ReplaceNodeWithProjections(node); 1341cb0ef41Sopenharmony_ci} 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_civoid Int64Lowering::LowerWord64AtomicNarrowOp(Node* node, const Operator* op) { 1371cb0ef41Sopenharmony_ci DefaultLowering(node, true); 1381cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, op); 1391cb0ef41Sopenharmony_ci ReplaceNode(node, node, graph()->NewNode(common()->Int32Constant(0))); 1401cb0ef41Sopenharmony_ci} 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci// static 1431cb0ef41Sopenharmony_ciint Int64Lowering::GetParameterCountAfterLowering( 1441cb0ef41Sopenharmony_ci Signature<MachineRepresentation>* signature) { 1451cb0ef41Sopenharmony_ci // GetParameterIndexAfterLowering(parameter_count) returns the parameter count 1461cb0ef41Sopenharmony_ci // after lowering. 1471cb0ef41Sopenharmony_ci return GetParameterIndexAfterLowering( 1481cb0ef41Sopenharmony_ci signature, static_cast<int>(signature->parameter_count())); 1491cb0ef41Sopenharmony_ci} 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_civoid Int64Lowering::GetIndexNodes(Node* index, Node** index_low, 1521cb0ef41Sopenharmony_ci Node** index_high) { 1531cb0ef41Sopenharmony_ci#if defined(V8_TARGET_LITTLE_ENDIAN) 1541cb0ef41Sopenharmony_ci *index_low = index; 1551cb0ef41Sopenharmony_ci *index_high = graph()->NewNode(machine()->Int32Add(), index, 1561cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(4))); 1571cb0ef41Sopenharmony_ci#elif defined(V8_TARGET_BIG_ENDIAN) 1581cb0ef41Sopenharmony_ci *index_low = graph()->NewNode(machine()->Int32Add(), index, 1591cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(4))); 1601cb0ef41Sopenharmony_ci *index_high = index; 1611cb0ef41Sopenharmony_ci#endif 1621cb0ef41Sopenharmony_ci} 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_civoid Int64Lowering::LowerLoadOperator(Node* node, MachineRepresentation rep, 1651cb0ef41Sopenharmony_ci const Operator* load_op) { 1661cb0ef41Sopenharmony_ci if (rep == MachineRepresentation::kWord64) { 1671cb0ef41Sopenharmony_ci LowerMemoryBaseAndIndex(node); 1681cb0ef41Sopenharmony_ci Node* base = node->InputAt(0); 1691cb0ef41Sopenharmony_ci Node* index = node->InputAt(1); 1701cb0ef41Sopenharmony_ci Node* index_low; 1711cb0ef41Sopenharmony_ci Node* index_high; 1721cb0ef41Sopenharmony_ci GetIndexNodes(index, &index_low, &index_high); 1731cb0ef41Sopenharmony_ci Node* high_node; 1741cb0ef41Sopenharmony_ci if (node->InputCount() > 2) { 1751cb0ef41Sopenharmony_ci Node* effect_high = node->InputAt(2); 1761cb0ef41Sopenharmony_ci Node* control_high = node->InputAt(3); 1771cb0ef41Sopenharmony_ci high_node = graph()->NewNode(load_op, base, index_high, effect_high, 1781cb0ef41Sopenharmony_ci control_high); 1791cb0ef41Sopenharmony_ci // change the effect change from old_node --> old_effect to 1801cb0ef41Sopenharmony_ci // old_node --> high_node --> old_effect. 1811cb0ef41Sopenharmony_ci node->ReplaceInput(2, high_node); 1821cb0ef41Sopenharmony_ci } else { 1831cb0ef41Sopenharmony_ci high_node = graph()->NewNode(load_op, base, index_high); 1841cb0ef41Sopenharmony_ci } 1851cb0ef41Sopenharmony_ci node->ReplaceInput(1, index_low); 1861cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, load_op); 1871cb0ef41Sopenharmony_ci ReplaceNode(node, node, high_node); 1881cb0ef41Sopenharmony_ci } else { 1891cb0ef41Sopenharmony_ci DefaultLowering(node); 1901cb0ef41Sopenharmony_ci } 1911cb0ef41Sopenharmony_ci} 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_civoid Int64Lowering::LowerStoreOperator(Node* node, MachineRepresentation rep, 1941cb0ef41Sopenharmony_ci const Operator* store_op) { 1951cb0ef41Sopenharmony_ci if (rep == MachineRepresentation::kWord64) { 1961cb0ef41Sopenharmony_ci // We change the original store node to store the low word, and create 1971cb0ef41Sopenharmony_ci // a new store node to store the high word. The effect and control edges 1981cb0ef41Sopenharmony_ci // are copied from the original store to the new store node, the effect 1991cb0ef41Sopenharmony_ci // edge of the original store is redirected to the new store. 2001cb0ef41Sopenharmony_ci LowerMemoryBaseAndIndex(node); 2011cb0ef41Sopenharmony_ci Node* base = node->InputAt(0); 2021cb0ef41Sopenharmony_ci Node* index = node->InputAt(1); 2031cb0ef41Sopenharmony_ci Node* index_low; 2041cb0ef41Sopenharmony_ci Node* index_high; 2051cb0ef41Sopenharmony_ci GetIndexNodes(index, &index_low, &index_high); 2061cb0ef41Sopenharmony_ci Node* value = node->InputAt(2); 2071cb0ef41Sopenharmony_ci DCHECK(HasReplacementLow(value)); 2081cb0ef41Sopenharmony_ci DCHECK(HasReplacementHigh(value)); 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ci Node* high_node; 2111cb0ef41Sopenharmony_ci if (node->InputCount() > 3) { 2121cb0ef41Sopenharmony_ci Node* effect_high = node->InputAt(3); 2131cb0ef41Sopenharmony_ci Node* control_high = node->InputAt(4); 2141cb0ef41Sopenharmony_ci high_node = graph()->NewNode(store_op, base, index_high, 2151cb0ef41Sopenharmony_ci GetReplacementHigh(value), effect_high, 2161cb0ef41Sopenharmony_ci control_high); 2171cb0ef41Sopenharmony_ci node->ReplaceInput(3, high_node); 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_ci } else { 2201cb0ef41Sopenharmony_ci high_node = graph()->NewNode(store_op, base, index_high, 2211cb0ef41Sopenharmony_ci GetReplacementHigh(value)); 2221cb0ef41Sopenharmony_ci } 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ci node->ReplaceInput(1, index_low); 2251cb0ef41Sopenharmony_ci node->ReplaceInput(2, GetReplacementLow(value)); 2261cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, store_op); 2271cb0ef41Sopenharmony_ci ReplaceNode(node, node, high_node); 2281cb0ef41Sopenharmony_ci } else { 2291cb0ef41Sopenharmony_ci DefaultLowering(node, true); 2301cb0ef41Sopenharmony_ci } 2311cb0ef41Sopenharmony_ci} 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_civoid Int64Lowering::LowerNode(Node* node) { 2341cb0ef41Sopenharmony_ci switch (node->opcode()) { 2351cb0ef41Sopenharmony_ci case IrOpcode::kInt64Constant: { 2361cb0ef41Sopenharmony_ci int64_t value = OpParameter<int64_t>(node->op()); 2371cb0ef41Sopenharmony_ci Node* low_node = graph()->NewNode( 2381cb0ef41Sopenharmony_ci common()->Int32Constant(static_cast<int32_t>(value & 0xFFFFFFFF))); 2391cb0ef41Sopenharmony_ci Node* high_node = graph()->NewNode( 2401cb0ef41Sopenharmony_ci common()->Int32Constant(static_cast<int32_t>(value >> 32))); 2411cb0ef41Sopenharmony_ci ReplaceNode(node, low_node, high_node); 2421cb0ef41Sopenharmony_ci break; 2431cb0ef41Sopenharmony_ci } 2441cb0ef41Sopenharmony_ci case IrOpcode::kLoad: { 2451cb0ef41Sopenharmony_ci MachineRepresentation rep = 2461cb0ef41Sopenharmony_ci LoadRepresentationOf(node->op()).representation(); 2471cb0ef41Sopenharmony_ci LowerLoadOperator(node, rep, machine()->Load(MachineType::Int32())); 2481cb0ef41Sopenharmony_ci break; 2491cb0ef41Sopenharmony_ci } 2501cb0ef41Sopenharmony_ci case IrOpcode::kUnalignedLoad: { 2511cb0ef41Sopenharmony_ci MachineRepresentation rep = 2521cb0ef41Sopenharmony_ci LoadRepresentationOf(node->op()).representation(); 2531cb0ef41Sopenharmony_ci LowerLoadOperator(node, rep, 2541cb0ef41Sopenharmony_ci machine()->UnalignedLoad(MachineType::Int32())); 2551cb0ef41Sopenharmony_ci break; 2561cb0ef41Sopenharmony_ci } 2571cb0ef41Sopenharmony_ci case IrOpcode::kLoadImmutable: { 2581cb0ef41Sopenharmony_ci MachineRepresentation rep = 2591cb0ef41Sopenharmony_ci LoadRepresentationOf(node->op()).representation(); 2601cb0ef41Sopenharmony_ci LowerLoadOperator(node, rep, 2611cb0ef41Sopenharmony_ci machine()->LoadImmutable(MachineType::Int32())); 2621cb0ef41Sopenharmony_ci break; 2631cb0ef41Sopenharmony_ci } 2641cb0ef41Sopenharmony_ci case IrOpcode::kLoadFromObject: { 2651cb0ef41Sopenharmony_ci ObjectAccess access = ObjectAccessOf(node->op()); 2661cb0ef41Sopenharmony_ci LowerLoadOperator(node, access.machine_type.representation(), 2671cb0ef41Sopenharmony_ci simplified()->LoadFromObject(ObjectAccess( 2681cb0ef41Sopenharmony_ci MachineType::Int32(), access.write_barrier_kind))); 2691cb0ef41Sopenharmony_ci break; 2701cb0ef41Sopenharmony_ci } 2711cb0ef41Sopenharmony_ci case IrOpcode::kLoadImmutableFromObject: { 2721cb0ef41Sopenharmony_ci ObjectAccess access = ObjectAccessOf(node->op()); 2731cb0ef41Sopenharmony_ci LowerLoadOperator(node, access.machine_type.representation(), 2741cb0ef41Sopenharmony_ci simplified()->LoadImmutableFromObject(ObjectAccess( 2751cb0ef41Sopenharmony_ci MachineType::Int32(), access.write_barrier_kind))); 2761cb0ef41Sopenharmony_ci break; 2771cb0ef41Sopenharmony_ci } 2781cb0ef41Sopenharmony_ci case IrOpcode::kStore: { 2791cb0ef41Sopenharmony_ci StoreRepresentation store_rep = StoreRepresentationOf(node->op()); 2801cb0ef41Sopenharmony_ci LowerStoreOperator( 2811cb0ef41Sopenharmony_ci node, store_rep.representation(), 2821cb0ef41Sopenharmony_ci machine()->Store(StoreRepresentation( 2831cb0ef41Sopenharmony_ci MachineRepresentation::kWord32, store_rep.write_barrier_kind()))); 2841cb0ef41Sopenharmony_ci break; 2851cb0ef41Sopenharmony_ci } 2861cb0ef41Sopenharmony_ci case IrOpcode::kUnalignedStore: { 2871cb0ef41Sopenharmony_ci UnalignedStoreRepresentation store_rep = 2881cb0ef41Sopenharmony_ci UnalignedStoreRepresentationOf(node->op()); 2891cb0ef41Sopenharmony_ci LowerStoreOperator( 2901cb0ef41Sopenharmony_ci node, store_rep, 2911cb0ef41Sopenharmony_ci machine()->UnalignedStore(MachineRepresentation::kWord32)); 2921cb0ef41Sopenharmony_ci break; 2931cb0ef41Sopenharmony_ci } 2941cb0ef41Sopenharmony_ci case IrOpcode::kStoreToObject: { 2951cb0ef41Sopenharmony_ci ObjectAccess access = ObjectAccessOf(node->op()); 2961cb0ef41Sopenharmony_ci LowerStoreOperator(node, access.machine_type.representation(), 2971cb0ef41Sopenharmony_ci simplified()->StoreToObject(ObjectAccess( 2981cb0ef41Sopenharmony_ci MachineType::Int32(), access.write_barrier_kind))); 2991cb0ef41Sopenharmony_ci break; 3001cb0ef41Sopenharmony_ci } 3011cb0ef41Sopenharmony_ci case IrOpcode::kInitializeImmutableInObject: { 3021cb0ef41Sopenharmony_ci ObjectAccess access = ObjectAccessOf(node->op()); 3031cb0ef41Sopenharmony_ci LowerStoreOperator(node, access.machine_type.representation(), 3041cb0ef41Sopenharmony_ci simplified()->InitializeImmutableInObject(ObjectAccess( 3051cb0ef41Sopenharmony_ci MachineType::Int32(), access.write_barrier_kind))); 3061cb0ef41Sopenharmony_ci break; 3071cb0ef41Sopenharmony_ci } 3081cb0ef41Sopenharmony_ci case IrOpcode::kStart: { 3091cb0ef41Sopenharmony_ci int parameter_count = GetParameterCountAfterLowering(signature()); 3101cb0ef41Sopenharmony_ci // Only exchange the node if the parameter count actually changed. 3111cb0ef41Sopenharmony_ci if (parameter_count != static_cast<int>(signature()->parameter_count())) { 3121cb0ef41Sopenharmony_ci int delta = 3131cb0ef41Sopenharmony_ci parameter_count - static_cast<int>(signature()->parameter_count()); 3141cb0ef41Sopenharmony_ci int new_output_count = node->op()->ValueOutputCount() + delta; 3151cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Start(new_output_count)); 3161cb0ef41Sopenharmony_ci } 3171cb0ef41Sopenharmony_ci break; 3181cb0ef41Sopenharmony_ci } 3191cb0ef41Sopenharmony_ci case IrOpcode::kParameter: { 3201cb0ef41Sopenharmony_ci DCHECK_EQ(1, node->InputCount()); 3211cb0ef41Sopenharmony_ci int param_count = static_cast<int>(signature()->parameter_count()); 3221cb0ef41Sopenharmony_ci // Only exchange the node if the parameter count actually changed. We do 3231cb0ef41Sopenharmony_ci // not even have to do the default lowering because the the start node, 3241cb0ef41Sopenharmony_ci // the only input of a parameter node, only changes if the parameter count 3251cb0ef41Sopenharmony_ci // changes. 3261cb0ef41Sopenharmony_ci if (GetParameterCountAfterLowering(signature()) != param_count) { 3271cb0ef41Sopenharmony_ci int old_index = ParameterIndexOf(node->op()); 3281cb0ef41Sopenharmony_ci // Adjust old_index to be compliant with the signature. 3291cb0ef41Sopenharmony_ci --old_index; 3301cb0ef41Sopenharmony_ci int new_index = GetParameterIndexAfterLowering(signature(), old_index); 3311cb0ef41Sopenharmony_ci // Adjust new_index to consider the instance parameter. 3321cb0ef41Sopenharmony_ci ++new_index; 3331cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Parameter(new_index)); 3341cb0ef41Sopenharmony_ci 3351cb0ef41Sopenharmony_ci if (old_index < 0 || old_index >= param_count) { 3361cb0ef41Sopenharmony_ci // Special parameters (JS closure/context) don't have kWord64 3371cb0ef41Sopenharmony_ci // representation anyway. 3381cb0ef41Sopenharmony_ci break; 3391cb0ef41Sopenharmony_ci } 3401cb0ef41Sopenharmony_ci 3411cb0ef41Sopenharmony_ci if (signature()->GetParam(old_index) == 3421cb0ef41Sopenharmony_ci MachineRepresentation::kWord64) { 3431cb0ef41Sopenharmony_ci Node* high_node = graph()->NewNode(common()->Parameter(new_index + 1), 3441cb0ef41Sopenharmony_ci graph()->start()); 3451cb0ef41Sopenharmony_ci ReplaceNode(node, node, high_node); 3461cb0ef41Sopenharmony_ci } 3471cb0ef41Sopenharmony_ci } 3481cb0ef41Sopenharmony_ci break; 3491cb0ef41Sopenharmony_ci } 3501cb0ef41Sopenharmony_ci case IrOpcode::kReturn: { 3511cb0ef41Sopenharmony_ci int input_count = node->InputCount(); 3521cb0ef41Sopenharmony_ci DefaultLowering(node); 3531cb0ef41Sopenharmony_ci if (input_count != node->InputCount()) { 3541cb0ef41Sopenharmony_ci int new_return_count = GetReturnCountAfterLowering(signature()); 3551cb0ef41Sopenharmony_ci if (static_cast<int>(signature()->return_count()) != new_return_count) { 3561cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Return(new_return_count)); 3571cb0ef41Sopenharmony_ci } 3581cb0ef41Sopenharmony_ci } 3591cb0ef41Sopenharmony_ci break; 3601cb0ef41Sopenharmony_ci } 3611cb0ef41Sopenharmony_ci case IrOpcode::kTailCall: { 3621cb0ef41Sopenharmony_ci auto call_descriptor = 3631cb0ef41Sopenharmony_ci const_cast<CallDescriptor*>(CallDescriptorOf(node->op())); 3641cb0ef41Sopenharmony_ci bool returns_require_lowering = 3651cb0ef41Sopenharmony_ci GetReturnCountAfterLowering(call_descriptor) != 3661cb0ef41Sopenharmony_ci static_cast<int>(call_descriptor->ReturnCount()); 3671cb0ef41Sopenharmony_ci if (DefaultLowering(node) || returns_require_lowering) { 3681cb0ef41Sopenharmony_ci // Tail calls do not have return values, so adjusting the call 3691cb0ef41Sopenharmony_ci // descriptor is enough. 3701cb0ef41Sopenharmony_ci NodeProperties::ChangeOp( 3711cb0ef41Sopenharmony_ci node, common()->TailCall(LowerCallDescriptor(call_descriptor))); 3721cb0ef41Sopenharmony_ci } 3731cb0ef41Sopenharmony_ci break; 3741cb0ef41Sopenharmony_ci } 3751cb0ef41Sopenharmony_ci case IrOpcode::kCall: { 3761cb0ef41Sopenharmony_ci auto call_descriptor = CallDescriptorOf(node->op()); 3771cb0ef41Sopenharmony_ci 3781cb0ef41Sopenharmony_ci bool returns_require_lowering = 3791cb0ef41Sopenharmony_ci GetReturnCountAfterLowering(call_descriptor) != 3801cb0ef41Sopenharmony_ci static_cast<int>(call_descriptor->ReturnCount()); 3811cb0ef41Sopenharmony_ci if (DefaultLowering(node) || returns_require_lowering) { 3821cb0ef41Sopenharmony_ci // We have to adjust the call descriptor. 3831cb0ef41Sopenharmony_ci NodeProperties::ChangeOp( 3841cb0ef41Sopenharmony_ci node, common()->Call(LowerCallDescriptor(call_descriptor))); 3851cb0ef41Sopenharmony_ci } 3861cb0ef41Sopenharmony_ci if (returns_require_lowering) { 3871cb0ef41Sopenharmony_ci size_t return_arity = call_descriptor->ReturnCount(); 3881cb0ef41Sopenharmony_ci if (return_arity == 1) { 3891cb0ef41Sopenharmony_ci // We access the additional return values through projections. 3901cb0ef41Sopenharmony_ci ReplaceNodeWithProjections(node); 3911cb0ef41Sopenharmony_ci } else { 3921cb0ef41Sopenharmony_ci ZoneVector<Node*> projections(return_arity, zone()); 3931cb0ef41Sopenharmony_ci NodeProperties::CollectValueProjections(node, projections.data(), 3941cb0ef41Sopenharmony_ci return_arity); 3951cb0ef41Sopenharmony_ci for (size_t old_index = 0, new_index = 0; old_index < return_arity; 3961cb0ef41Sopenharmony_ci ++old_index, ++new_index) { 3971cb0ef41Sopenharmony_ci Node* use_node = projections[old_index]; 3981cb0ef41Sopenharmony_ci DCHECK_EQ(ProjectionIndexOf(use_node->op()), old_index); 3991cb0ef41Sopenharmony_ci DCHECK_EQ(GetReturnIndexAfterLowering(call_descriptor, 4001cb0ef41Sopenharmony_ci static_cast<int>(old_index)), 4011cb0ef41Sopenharmony_ci static_cast<int>(new_index)); 4021cb0ef41Sopenharmony_ci if (new_index != old_index) { 4031cb0ef41Sopenharmony_ci NodeProperties::ChangeOp( 4041cb0ef41Sopenharmony_ci use_node, common()->Projection(new_index)); 4051cb0ef41Sopenharmony_ci } 4061cb0ef41Sopenharmony_ci if (call_descriptor->GetReturnType(old_index).representation() == 4071cb0ef41Sopenharmony_ci MachineRepresentation::kWord64) { 4081cb0ef41Sopenharmony_ci Node* high_node = graph()->NewNode( 4091cb0ef41Sopenharmony_ci common()->Projection(new_index + 1), node, graph()->start()); 4101cb0ef41Sopenharmony_ci ReplaceNode(use_node, use_node, high_node); 4111cb0ef41Sopenharmony_ci ++new_index; 4121cb0ef41Sopenharmony_ci } 4131cb0ef41Sopenharmony_ci } 4141cb0ef41Sopenharmony_ci } 4151cb0ef41Sopenharmony_ci } 4161cb0ef41Sopenharmony_ci break; 4171cb0ef41Sopenharmony_ci } 4181cb0ef41Sopenharmony_ci case IrOpcode::kWord64And: { 4191cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 4201cb0ef41Sopenharmony_ci Node* left = node->InputAt(0); 4211cb0ef41Sopenharmony_ci Node* right = node->InputAt(1); 4221cb0ef41Sopenharmony_ci 4231cb0ef41Sopenharmony_ci Node* low_node = 4241cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32And(), GetReplacementLow(left), 4251cb0ef41Sopenharmony_ci GetReplacementLow(right)); 4261cb0ef41Sopenharmony_ci Node* high_node = 4271cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32And(), GetReplacementHigh(left), 4281cb0ef41Sopenharmony_ci GetReplacementHigh(right)); 4291cb0ef41Sopenharmony_ci ReplaceNode(node, low_node, high_node); 4301cb0ef41Sopenharmony_ci break; 4311cb0ef41Sopenharmony_ci } 4321cb0ef41Sopenharmony_ci case IrOpcode::kTruncateInt64ToInt32: { 4331cb0ef41Sopenharmony_ci DCHECK_EQ(1, node->InputCount()); 4341cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 4351cb0ef41Sopenharmony_ci ReplaceNode(node, GetReplacementLow(input), nullptr); 4361cb0ef41Sopenharmony_ci node->NullAllInputs(); 4371cb0ef41Sopenharmony_ci break; 4381cb0ef41Sopenharmony_ci } 4391cb0ef41Sopenharmony_ci case IrOpcode::kInt64Add: { 4401cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 4411cb0ef41Sopenharmony_ci 4421cb0ef41Sopenharmony_ci Node* right = node->InputAt(1); 4431cb0ef41Sopenharmony_ci node->ReplaceInput(1, GetReplacementLow(right)); 4441cb0ef41Sopenharmony_ci node->AppendInput(zone(), GetReplacementHigh(right)); 4451cb0ef41Sopenharmony_ci 4461cb0ef41Sopenharmony_ci Node* left = node->InputAt(0); 4471cb0ef41Sopenharmony_ci node->ReplaceInput(0, GetReplacementLow(left)); 4481cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, GetReplacementHigh(left)); 4491cb0ef41Sopenharmony_ci 4501cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, machine()->Int32PairAdd()); 4511cb0ef41Sopenharmony_ci // We access the additional return values through projections. 4521cb0ef41Sopenharmony_ci ReplaceNodeWithProjections(node); 4531cb0ef41Sopenharmony_ci break; 4541cb0ef41Sopenharmony_ci } 4551cb0ef41Sopenharmony_ci case IrOpcode::kInt64Sub: { 4561cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 4571cb0ef41Sopenharmony_ci 4581cb0ef41Sopenharmony_ci Node* right = node->InputAt(1); 4591cb0ef41Sopenharmony_ci node->ReplaceInput(1, GetReplacementLow(right)); 4601cb0ef41Sopenharmony_ci node->AppendInput(zone(), GetReplacementHigh(right)); 4611cb0ef41Sopenharmony_ci 4621cb0ef41Sopenharmony_ci Node* left = node->InputAt(0); 4631cb0ef41Sopenharmony_ci node->ReplaceInput(0, GetReplacementLow(left)); 4641cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, GetReplacementHigh(left)); 4651cb0ef41Sopenharmony_ci 4661cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, machine()->Int32PairSub()); 4671cb0ef41Sopenharmony_ci // We access the additional return values through projections. 4681cb0ef41Sopenharmony_ci ReplaceNodeWithProjections(node); 4691cb0ef41Sopenharmony_ci break; 4701cb0ef41Sopenharmony_ci } 4711cb0ef41Sopenharmony_ci case IrOpcode::kInt64Mul: { 4721cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 4731cb0ef41Sopenharmony_ci 4741cb0ef41Sopenharmony_ci Node* right = node->InputAt(1); 4751cb0ef41Sopenharmony_ci node->ReplaceInput(1, GetReplacementLow(right)); 4761cb0ef41Sopenharmony_ci node->AppendInput(zone(), GetReplacementHigh(right)); 4771cb0ef41Sopenharmony_ci 4781cb0ef41Sopenharmony_ci Node* left = node->InputAt(0); 4791cb0ef41Sopenharmony_ci node->ReplaceInput(0, GetReplacementLow(left)); 4801cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, GetReplacementHigh(left)); 4811cb0ef41Sopenharmony_ci 4821cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, machine()->Int32PairMul()); 4831cb0ef41Sopenharmony_ci // We access the additional return values through projections. 4841cb0ef41Sopenharmony_ci ReplaceNodeWithProjections(node); 4851cb0ef41Sopenharmony_ci break; 4861cb0ef41Sopenharmony_ci } 4871cb0ef41Sopenharmony_ci case IrOpcode::kWord64Or: { 4881cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 4891cb0ef41Sopenharmony_ci Node* left = node->InputAt(0); 4901cb0ef41Sopenharmony_ci Node* right = node->InputAt(1); 4911cb0ef41Sopenharmony_ci 4921cb0ef41Sopenharmony_ci Node* low_node = 4931cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Or(), GetReplacementLow(left), 4941cb0ef41Sopenharmony_ci GetReplacementLow(right)); 4951cb0ef41Sopenharmony_ci Node* high_node = 4961cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Or(), GetReplacementHigh(left), 4971cb0ef41Sopenharmony_ci GetReplacementHigh(right)); 4981cb0ef41Sopenharmony_ci ReplaceNode(node, low_node, high_node); 4991cb0ef41Sopenharmony_ci break; 5001cb0ef41Sopenharmony_ci } 5011cb0ef41Sopenharmony_ci case IrOpcode::kWord64Xor: { 5021cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 5031cb0ef41Sopenharmony_ci Node* left = node->InputAt(0); 5041cb0ef41Sopenharmony_ci Node* right = node->InputAt(1); 5051cb0ef41Sopenharmony_ci 5061cb0ef41Sopenharmony_ci Node* low_node = 5071cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Xor(), GetReplacementLow(left), 5081cb0ef41Sopenharmony_ci GetReplacementLow(right)); 5091cb0ef41Sopenharmony_ci Node* high_node = 5101cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Xor(), GetReplacementHigh(left), 5111cb0ef41Sopenharmony_ci GetReplacementHigh(right)); 5121cb0ef41Sopenharmony_ci ReplaceNode(node, low_node, high_node); 5131cb0ef41Sopenharmony_ci break; 5141cb0ef41Sopenharmony_ci } 5151cb0ef41Sopenharmony_ci case IrOpcode::kWord64Shl: { 5161cb0ef41Sopenharmony_ci // TODO(turbofan): if the shift count >= 32, then we can set the low word 5171cb0ef41Sopenharmony_ci // of the output to 0 and just calculate the high word. 5181cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 5191cb0ef41Sopenharmony_ci Node* shift = node->InputAt(1); 5201cb0ef41Sopenharmony_ci if (HasReplacementLow(shift)) { 5211cb0ef41Sopenharmony_ci // We do not have to care about the high word replacement, because 5221cb0ef41Sopenharmony_ci // the shift can only be between 0 and 63 anyways. 5231cb0ef41Sopenharmony_ci node->ReplaceInput(1, GetReplacementLow(shift)); 5241cb0ef41Sopenharmony_ci } 5251cb0ef41Sopenharmony_ci 5261cb0ef41Sopenharmony_ci Node* value = node->InputAt(0); 5271cb0ef41Sopenharmony_ci node->ReplaceInput(0, GetReplacementLow(value)); 5281cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, GetReplacementHigh(value)); 5291cb0ef41Sopenharmony_ci 5301cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, machine()->Word32PairShl()); 5311cb0ef41Sopenharmony_ci // We access the additional return values through projections. 5321cb0ef41Sopenharmony_ci ReplaceNodeWithProjections(node); 5331cb0ef41Sopenharmony_ci break; 5341cb0ef41Sopenharmony_ci } 5351cb0ef41Sopenharmony_ci case IrOpcode::kWord64Shr: { 5361cb0ef41Sopenharmony_ci // TODO(turbofan): if the shift count >= 32, then we can set the low word 5371cb0ef41Sopenharmony_ci // of the output to 0 and just calculate the high word. 5381cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 5391cb0ef41Sopenharmony_ci Node* shift = node->InputAt(1); 5401cb0ef41Sopenharmony_ci if (HasReplacementLow(shift)) { 5411cb0ef41Sopenharmony_ci // We do not have to care about the high word replacement, because 5421cb0ef41Sopenharmony_ci // the shift can only be between 0 and 63 anyways. 5431cb0ef41Sopenharmony_ci node->ReplaceInput(1, GetReplacementLow(shift)); 5441cb0ef41Sopenharmony_ci } 5451cb0ef41Sopenharmony_ci 5461cb0ef41Sopenharmony_ci Node* value = node->InputAt(0); 5471cb0ef41Sopenharmony_ci node->ReplaceInput(0, GetReplacementLow(value)); 5481cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, GetReplacementHigh(value)); 5491cb0ef41Sopenharmony_ci 5501cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, machine()->Word32PairShr()); 5511cb0ef41Sopenharmony_ci // We access the additional return values through projections. 5521cb0ef41Sopenharmony_ci ReplaceNodeWithProjections(node); 5531cb0ef41Sopenharmony_ci break; 5541cb0ef41Sopenharmony_ci } 5551cb0ef41Sopenharmony_ci case IrOpcode::kWord64Sar: { 5561cb0ef41Sopenharmony_ci // TODO(turbofan): if the shift count >= 32, then we can set the low word 5571cb0ef41Sopenharmony_ci // of the output to 0 and just calculate the high word. 5581cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 5591cb0ef41Sopenharmony_ci Node* shift = node->InputAt(1); 5601cb0ef41Sopenharmony_ci if (HasReplacementLow(shift)) { 5611cb0ef41Sopenharmony_ci // We do not have to care about the high word replacement, because 5621cb0ef41Sopenharmony_ci // the shift can only be between 0 and 63 anyways. 5631cb0ef41Sopenharmony_ci node->ReplaceInput(1, GetReplacementLow(shift)); 5641cb0ef41Sopenharmony_ci } 5651cb0ef41Sopenharmony_ci 5661cb0ef41Sopenharmony_ci Node* value = node->InputAt(0); 5671cb0ef41Sopenharmony_ci node->ReplaceInput(0, GetReplacementLow(value)); 5681cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, GetReplacementHigh(value)); 5691cb0ef41Sopenharmony_ci 5701cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, machine()->Word32PairSar()); 5711cb0ef41Sopenharmony_ci // We access the additional return values through projections. 5721cb0ef41Sopenharmony_ci ReplaceNodeWithProjections(node); 5731cb0ef41Sopenharmony_ci break; 5741cb0ef41Sopenharmony_ci } 5751cb0ef41Sopenharmony_ci case IrOpcode::kWord64Equal: { 5761cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 5771cb0ef41Sopenharmony_ci Node* left = node->InputAt(0); 5781cb0ef41Sopenharmony_ci Node* right = node->InputAt(1); 5791cb0ef41Sopenharmony_ci 5801cb0ef41Sopenharmony_ci // TODO(wasm): Use explicit comparisons and && here? 5811cb0ef41Sopenharmony_ci Node* replacement = graph()->NewNode( 5821cb0ef41Sopenharmony_ci machine()->Word32Equal(), 5831cb0ef41Sopenharmony_ci graph()->NewNode( 5841cb0ef41Sopenharmony_ci machine()->Word32Or(), 5851cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Xor(), GetReplacementLow(left), 5861cb0ef41Sopenharmony_ci GetReplacementLow(right)), 5871cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Xor(), GetReplacementHigh(left), 5881cb0ef41Sopenharmony_ci GetReplacementHigh(right))), 5891cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(0))); 5901cb0ef41Sopenharmony_ci 5911cb0ef41Sopenharmony_ci ReplaceNode(node, replacement, nullptr); 5921cb0ef41Sopenharmony_ci break; 5931cb0ef41Sopenharmony_ci } 5941cb0ef41Sopenharmony_ci case IrOpcode::kInt64LessThan: { 5951cb0ef41Sopenharmony_ci LowerComparison(node, machine()->Int32LessThan(), 5961cb0ef41Sopenharmony_ci machine()->Uint32LessThan()); 5971cb0ef41Sopenharmony_ci break; 5981cb0ef41Sopenharmony_ci } 5991cb0ef41Sopenharmony_ci case IrOpcode::kInt64LessThanOrEqual: { 6001cb0ef41Sopenharmony_ci LowerComparison(node, machine()->Int32LessThan(), 6011cb0ef41Sopenharmony_ci machine()->Uint32LessThanOrEqual()); 6021cb0ef41Sopenharmony_ci break; 6031cb0ef41Sopenharmony_ci } 6041cb0ef41Sopenharmony_ci case IrOpcode::kUint64LessThan: { 6051cb0ef41Sopenharmony_ci LowerComparison(node, machine()->Uint32LessThan(), 6061cb0ef41Sopenharmony_ci machine()->Uint32LessThan()); 6071cb0ef41Sopenharmony_ci break; 6081cb0ef41Sopenharmony_ci } 6091cb0ef41Sopenharmony_ci case IrOpcode::kUint64LessThanOrEqual: { 6101cb0ef41Sopenharmony_ci LowerComparison(node, machine()->Uint32LessThan(), 6111cb0ef41Sopenharmony_ci machine()->Uint32LessThanOrEqual()); 6121cb0ef41Sopenharmony_ci break; 6131cb0ef41Sopenharmony_ci } 6141cb0ef41Sopenharmony_ci case IrOpcode::kSignExtendWord32ToInt64: 6151cb0ef41Sopenharmony_ci case IrOpcode::kChangeInt32ToInt64: { 6161cb0ef41Sopenharmony_ci DCHECK_EQ(1, node->InputCount()); 6171cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 6181cb0ef41Sopenharmony_ci if (HasReplacementLow(input)) { 6191cb0ef41Sopenharmony_ci input = GetReplacementLow(input); 6201cb0ef41Sopenharmony_ci } 6211cb0ef41Sopenharmony_ci // We use SAR to preserve the sign in the high word. 6221cb0ef41Sopenharmony_ci ReplaceNode( 6231cb0ef41Sopenharmony_ci node, input, 6241cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Sar(), input, 6251cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(31)))); 6261cb0ef41Sopenharmony_ci node->NullAllInputs(); 6271cb0ef41Sopenharmony_ci break; 6281cb0ef41Sopenharmony_ci } 6291cb0ef41Sopenharmony_ci case IrOpcode::kChangeUint32ToUint64: { 6301cb0ef41Sopenharmony_ci DCHECK_EQ(1, node->InputCount()); 6311cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 6321cb0ef41Sopenharmony_ci if (HasReplacementLow(input)) { 6331cb0ef41Sopenharmony_ci input = GetReplacementLow(input); 6341cb0ef41Sopenharmony_ci } 6351cb0ef41Sopenharmony_ci ReplaceNode(node, input, graph()->NewNode(common()->Int32Constant(0))); 6361cb0ef41Sopenharmony_ci node->NullAllInputs(); 6371cb0ef41Sopenharmony_ci break; 6381cb0ef41Sopenharmony_ci } 6391cb0ef41Sopenharmony_ci case IrOpcode::kBitcastInt64ToFloat64: { 6401cb0ef41Sopenharmony_ci DCHECK_EQ(1, node->InputCount()); 6411cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 6421cb0ef41Sopenharmony_ci Node* stack_slot = graph()->NewNode( 6431cb0ef41Sopenharmony_ci machine()->StackSlot(MachineRepresentation::kWord64)); 6441cb0ef41Sopenharmony_ci 6451cb0ef41Sopenharmony_ci Node* store_high_word = graph()->NewNode( 6461cb0ef41Sopenharmony_ci machine()->Store( 6471cb0ef41Sopenharmony_ci StoreRepresentation(MachineRepresentation::kWord32, 6481cb0ef41Sopenharmony_ci WriteBarrierKind::kNoWriteBarrier)), 6491cb0ef41Sopenharmony_ci stack_slot, 6501cb0ef41Sopenharmony_ci graph()->NewNode( 6511cb0ef41Sopenharmony_ci common()->Int32Constant(kInt64UpperHalfMemoryOffset)), 6521cb0ef41Sopenharmony_ci GetReplacementHigh(input), graph()->start(), graph()->start()); 6531cb0ef41Sopenharmony_ci 6541cb0ef41Sopenharmony_ci Node* store_low_word = graph()->NewNode( 6551cb0ef41Sopenharmony_ci machine()->Store( 6561cb0ef41Sopenharmony_ci StoreRepresentation(MachineRepresentation::kWord32, 6571cb0ef41Sopenharmony_ci WriteBarrierKind::kNoWriteBarrier)), 6581cb0ef41Sopenharmony_ci stack_slot, 6591cb0ef41Sopenharmony_ci graph()->NewNode( 6601cb0ef41Sopenharmony_ci common()->Int32Constant(kInt64LowerHalfMemoryOffset)), 6611cb0ef41Sopenharmony_ci GetReplacementLow(input), store_high_word, graph()->start()); 6621cb0ef41Sopenharmony_ci 6631cb0ef41Sopenharmony_ci Node* load = 6641cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Load(MachineType::Float64()), stack_slot, 6651cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(0)), 6661cb0ef41Sopenharmony_ci store_low_word, graph()->start()); 6671cb0ef41Sopenharmony_ci 6681cb0ef41Sopenharmony_ci ReplaceNode(node, load, nullptr); 6691cb0ef41Sopenharmony_ci break; 6701cb0ef41Sopenharmony_ci } 6711cb0ef41Sopenharmony_ci case IrOpcode::kBitcastFloat64ToInt64: { 6721cb0ef41Sopenharmony_ci DCHECK_EQ(1, node->InputCount()); 6731cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 6741cb0ef41Sopenharmony_ci if (HasReplacementLow(input)) { 6751cb0ef41Sopenharmony_ci input = GetReplacementLow(input); 6761cb0ef41Sopenharmony_ci } 6771cb0ef41Sopenharmony_ci Node* stack_slot = graph()->NewNode( 6781cb0ef41Sopenharmony_ci machine()->StackSlot(MachineRepresentation::kWord64)); 6791cb0ef41Sopenharmony_ci Node* store = graph()->NewNode( 6801cb0ef41Sopenharmony_ci machine()->Store( 6811cb0ef41Sopenharmony_ci StoreRepresentation(MachineRepresentation::kFloat64, 6821cb0ef41Sopenharmony_ci WriteBarrierKind::kNoWriteBarrier)), 6831cb0ef41Sopenharmony_ci stack_slot, graph()->NewNode(common()->Int32Constant(0)), input, 6841cb0ef41Sopenharmony_ci graph()->start(), graph()->start()); 6851cb0ef41Sopenharmony_ci 6861cb0ef41Sopenharmony_ci Node* high_node = graph()->NewNode( 6871cb0ef41Sopenharmony_ci machine()->Load(MachineType::Int32()), stack_slot, 6881cb0ef41Sopenharmony_ci graph()->NewNode( 6891cb0ef41Sopenharmony_ci common()->Int32Constant(kInt64UpperHalfMemoryOffset)), 6901cb0ef41Sopenharmony_ci store, graph()->start()); 6911cb0ef41Sopenharmony_ci 6921cb0ef41Sopenharmony_ci Node* low_node = graph()->NewNode( 6931cb0ef41Sopenharmony_ci machine()->Load(MachineType::Int32()), stack_slot, 6941cb0ef41Sopenharmony_ci graph()->NewNode( 6951cb0ef41Sopenharmony_ci common()->Int32Constant(kInt64LowerHalfMemoryOffset)), 6961cb0ef41Sopenharmony_ci store, graph()->start()); 6971cb0ef41Sopenharmony_ci ReplaceNode(node, low_node, high_node); 6981cb0ef41Sopenharmony_ci break; 6991cb0ef41Sopenharmony_ci } 7001cb0ef41Sopenharmony_ci case IrOpcode::kWord64RolLowerable: 7011cb0ef41Sopenharmony_ci DCHECK(machine()->Word32Rol().IsSupported()); 7021cb0ef41Sopenharmony_ci V8_FALLTHROUGH; 7031cb0ef41Sopenharmony_ci case IrOpcode::kWord64RorLowerable: { 7041cb0ef41Sopenharmony_ci DCHECK_EQ(3, node->InputCount()); 7051cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 7061cb0ef41Sopenharmony_ci Node* shift = HasReplacementLow(node->InputAt(1)) 7071cb0ef41Sopenharmony_ci ? GetReplacementLow(node->InputAt(1)) 7081cb0ef41Sopenharmony_ci : node->InputAt(1); 7091cb0ef41Sopenharmony_ci Int32Matcher m(shift); 7101cb0ef41Sopenharmony_ci if (m.HasResolvedValue()) { 7111cb0ef41Sopenharmony_ci // Precondition: 0 <= shift < 64. 7121cb0ef41Sopenharmony_ci int32_t shift_value = m.ResolvedValue() & 0x3F; 7131cb0ef41Sopenharmony_ci if (shift_value == 0) { 7141cb0ef41Sopenharmony_ci ReplaceNode(node, GetReplacementLow(input), 7151cb0ef41Sopenharmony_ci GetReplacementHigh(input)); 7161cb0ef41Sopenharmony_ci } else if (shift_value == 32) { 7171cb0ef41Sopenharmony_ci ReplaceNode(node, GetReplacementHigh(input), 7181cb0ef41Sopenharmony_ci GetReplacementLow(input)); 7191cb0ef41Sopenharmony_ci } else { 7201cb0ef41Sopenharmony_ci Node* low_input; 7211cb0ef41Sopenharmony_ci Node* high_input; 7221cb0ef41Sopenharmony_ci if (shift_value < 32) { 7231cb0ef41Sopenharmony_ci low_input = GetReplacementLow(input); 7241cb0ef41Sopenharmony_ci high_input = GetReplacementHigh(input); 7251cb0ef41Sopenharmony_ci } else { 7261cb0ef41Sopenharmony_ci low_input = GetReplacementHigh(input); 7271cb0ef41Sopenharmony_ci high_input = GetReplacementLow(input); 7281cb0ef41Sopenharmony_ci } 7291cb0ef41Sopenharmony_ci int32_t masked_shift_value = shift_value & 0x1F; 7301cb0ef41Sopenharmony_ci Node* masked_shift = 7311cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(masked_shift_value)); 7321cb0ef41Sopenharmony_ci Node* inv_shift = graph()->NewNode( 7331cb0ef41Sopenharmony_ci common()->Int32Constant(32 - masked_shift_value)); 7341cb0ef41Sopenharmony_ci 7351cb0ef41Sopenharmony_ci auto* op1 = machine()->Word32Shr(); 7361cb0ef41Sopenharmony_ci auto* op2 = machine()->Word32Shl(); 7371cb0ef41Sopenharmony_ci bool is_ror = node->opcode() == IrOpcode::kWord64RorLowerable; 7381cb0ef41Sopenharmony_ci if (!is_ror) std::swap(op1, op2); 7391cb0ef41Sopenharmony_ci 7401cb0ef41Sopenharmony_ci Node* low_node = 7411cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Or(), 7421cb0ef41Sopenharmony_ci graph()->NewNode(op1, low_input, masked_shift), 7431cb0ef41Sopenharmony_ci graph()->NewNode(op2, high_input, inv_shift)); 7441cb0ef41Sopenharmony_ci Node* high_node = 7451cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Or(), 7461cb0ef41Sopenharmony_ci graph()->NewNode(op1, high_input, masked_shift), 7471cb0ef41Sopenharmony_ci graph()->NewNode(op2, low_input, inv_shift)); 7481cb0ef41Sopenharmony_ci ReplaceNode(node, low_node, high_node); 7491cb0ef41Sopenharmony_ci } 7501cb0ef41Sopenharmony_ci } else { 7511cb0ef41Sopenharmony_ci Node* safe_shift = shift; 7521cb0ef41Sopenharmony_ci if (!machine()->Word32ShiftIsSafe()) { 7531cb0ef41Sopenharmony_ci safe_shift = 7541cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32And(), shift, 7551cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(0x1F))); 7561cb0ef41Sopenharmony_ci } 7571cb0ef41Sopenharmony_ci 7581cb0ef41Sopenharmony_ci bool is_ror = node->opcode() == IrOpcode::kWord64RorLowerable; 7591cb0ef41Sopenharmony_ci Node* inv_mask = 7601cb0ef41Sopenharmony_ci is_ror ? graph()->NewNode( 7611cb0ef41Sopenharmony_ci machine()->Word32Xor(), 7621cb0ef41Sopenharmony_ci graph()->NewNode( 7631cb0ef41Sopenharmony_ci machine()->Word32Shr(), 7641cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(-1)), 7651cb0ef41Sopenharmony_ci safe_shift), 7661cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(-1))) 7671cb0ef41Sopenharmony_ci : graph()->NewNode( 7681cb0ef41Sopenharmony_ci machine()->Word32Shl(), 7691cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(-1)), 7701cb0ef41Sopenharmony_ci safe_shift); 7711cb0ef41Sopenharmony_ci 7721cb0ef41Sopenharmony_ci Node* bit_mask = 7731cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Xor(), inv_mask, 7741cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(-1))); 7751cb0ef41Sopenharmony_ci 7761cb0ef41Sopenharmony_ci // We have to mask the shift value for this comparison. If 7771cb0ef41Sopenharmony_ci // !machine()->Word32ShiftIsSafe() then the masking should already be 7781cb0ef41Sopenharmony_ci // part of the graph. 7791cb0ef41Sopenharmony_ci Node* masked_shift6 = shift; 7801cb0ef41Sopenharmony_ci if (machine()->Word32ShiftIsSafe()) { 7811cb0ef41Sopenharmony_ci masked_shift6 = 7821cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32And(), shift, 7831cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(0x3F))); 7841cb0ef41Sopenharmony_ci } 7851cb0ef41Sopenharmony_ci 7861cb0ef41Sopenharmony_ci Diamond lt32( 7871cb0ef41Sopenharmony_ci graph(), common(), 7881cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Int32LessThan(), masked_shift6, 7891cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(32)))); 7901cb0ef41Sopenharmony_ci lt32.Chain(NodeProperties::GetControlInput(node)); 7911cb0ef41Sopenharmony_ci 7921cb0ef41Sopenharmony_ci // The low word and the high word can be swapped either at the input or 7931cb0ef41Sopenharmony_ci // at the output. We swap the inputs so that shift does not have to be 7941cb0ef41Sopenharmony_ci // kept for so long in a register. 7951cb0ef41Sopenharmony_ci Node* input_low = 7961cb0ef41Sopenharmony_ci lt32.Phi(MachineRepresentation::kWord32, GetReplacementLow(input), 7971cb0ef41Sopenharmony_ci GetReplacementHigh(input)); 7981cb0ef41Sopenharmony_ci Node* input_high = 7991cb0ef41Sopenharmony_ci lt32.Phi(MachineRepresentation::kWord32, GetReplacementHigh(input), 8001cb0ef41Sopenharmony_ci GetReplacementLow(input)); 8011cb0ef41Sopenharmony_ci 8021cb0ef41Sopenharmony_ci const Operator* oper = 8031cb0ef41Sopenharmony_ci is_ror ? machine()->Word32Ror() : machine()->Word32Rol().op(); 8041cb0ef41Sopenharmony_ci 8051cb0ef41Sopenharmony_ci Node* rotate_low = graph()->NewNode(oper, input_low, safe_shift); 8061cb0ef41Sopenharmony_ci Node* rotate_high = graph()->NewNode(oper, input_high, safe_shift); 8071cb0ef41Sopenharmony_ci 8081cb0ef41Sopenharmony_ci auto* mask1 = bit_mask; 8091cb0ef41Sopenharmony_ci auto* mask2 = inv_mask; 8101cb0ef41Sopenharmony_ci if (!is_ror) std::swap(mask1, mask2); 8111cb0ef41Sopenharmony_ci 8121cb0ef41Sopenharmony_ci Node* low_node = graph()->NewNode( 8131cb0ef41Sopenharmony_ci machine()->Word32Or(), 8141cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32And(), rotate_low, mask1), 8151cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32And(), rotate_high, mask2)); 8161cb0ef41Sopenharmony_ci Node* high_node = graph()->NewNode( 8171cb0ef41Sopenharmony_ci machine()->Word32Or(), 8181cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32And(), rotate_high, mask1), 8191cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32And(), rotate_low, mask2)); 8201cb0ef41Sopenharmony_ci ReplaceNode(node, low_node, high_node); 8211cb0ef41Sopenharmony_ci } 8221cb0ef41Sopenharmony_ci break; 8231cb0ef41Sopenharmony_ci } 8241cb0ef41Sopenharmony_ci case IrOpcode::kWord64ClzLowerable: { 8251cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 8261cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 8271cb0ef41Sopenharmony_ci Diamond d( 8281cb0ef41Sopenharmony_ci graph(), common(), 8291cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Equal(), GetReplacementHigh(input), 8301cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(0)))); 8311cb0ef41Sopenharmony_ci d.Chain(NodeProperties::GetControlInput(node)); 8321cb0ef41Sopenharmony_ci 8331cb0ef41Sopenharmony_ci Node* low_node = d.Phi( 8341cb0ef41Sopenharmony_ci MachineRepresentation::kWord32, 8351cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Int32Add(), 8361cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Clz(), 8371cb0ef41Sopenharmony_ci GetReplacementLow(input)), 8381cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(32))), 8391cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Clz(), GetReplacementHigh(input))); 8401cb0ef41Sopenharmony_ci ReplaceNode(node, low_node, graph()->NewNode(common()->Int32Constant(0))); 8411cb0ef41Sopenharmony_ci break; 8421cb0ef41Sopenharmony_ci } 8431cb0ef41Sopenharmony_ci case IrOpcode::kWord64CtzLowerable: { 8441cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 8451cb0ef41Sopenharmony_ci DCHECK(machine()->Word32Ctz().IsSupported()); 8461cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 8471cb0ef41Sopenharmony_ci Diamond d( 8481cb0ef41Sopenharmony_ci graph(), common(), 8491cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Equal(), GetReplacementLow(input), 8501cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(0)))); 8511cb0ef41Sopenharmony_ci d.Chain(NodeProperties::GetControlInput(node)); 8521cb0ef41Sopenharmony_ci 8531cb0ef41Sopenharmony_ci Node* low_node = 8541cb0ef41Sopenharmony_ci d.Phi(MachineRepresentation::kWord32, 8551cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Int32Add(), 8561cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Ctz().op(), 8571cb0ef41Sopenharmony_ci GetReplacementHigh(input)), 8581cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(32))), 8591cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Ctz().op(), 8601cb0ef41Sopenharmony_ci GetReplacementLow(input))); 8611cb0ef41Sopenharmony_ci ReplaceNode(node, low_node, graph()->NewNode(common()->Int32Constant(0))); 8621cb0ef41Sopenharmony_ci break; 8631cb0ef41Sopenharmony_ci } 8641cb0ef41Sopenharmony_ci case IrOpcode::kWord64Ror: 8651cb0ef41Sopenharmony_ci case IrOpcode::kWord64Rol: 8661cb0ef41Sopenharmony_ci case IrOpcode::kWord64Ctz: 8671cb0ef41Sopenharmony_ci case IrOpcode::kWord64Clz: 8681cb0ef41Sopenharmony_ci FATAL("%s operator should not be used in 32-bit systems", 8691cb0ef41Sopenharmony_ci node->op()->mnemonic()); 8701cb0ef41Sopenharmony_ci case IrOpcode::kWord64Popcnt: { 8711cb0ef41Sopenharmony_ci DCHECK_EQ(1, node->InputCount()); 8721cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 8731cb0ef41Sopenharmony_ci // We assume that a Word64Popcnt node only has been created if 8741cb0ef41Sopenharmony_ci // Word32Popcnt is actually supported. 8751cb0ef41Sopenharmony_ci DCHECK(machine()->Word32Popcnt().IsSupported()); 8761cb0ef41Sopenharmony_ci ReplaceNode(node, graph()->NewNode( 8771cb0ef41Sopenharmony_ci machine()->Int32Add(), 8781cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Popcnt().op(), 8791cb0ef41Sopenharmony_ci GetReplacementLow(input)), 8801cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Popcnt().op(), 8811cb0ef41Sopenharmony_ci GetReplacementHigh(input))), 8821cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(0))); 8831cb0ef41Sopenharmony_ci break; 8841cb0ef41Sopenharmony_ci } 8851cb0ef41Sopenharmony_ci case IrOpcode::kPhi: { 8861cb0ef41Sopenharmony_ci MachineRepresentation rep = PhiRepresentationOf(node->op()); 8871cb0ef41Sopenharmony_ci if (rep == MachineRepresentation::kWord64) { 8881cb0ef41Sopenharmony_ci // The replacement nodes have already been created, we only have to 8891cb0ef41Sopenharmony_ci // replace placeholder nodes. 8901cb0ef41Sopenharmony_ci Node* low_node = GetReplacementLow(node); 8911cb0ef41Sopenharmony_ci Node* high_node = GetReplacementHigh(node); 8921cb0ef41Sopenharmony_ci for (int i = 0; i < node->op()->ValueInputCount(); i++) { 8931cb0ef41Sopenharmony_ci low_node->ReplaceInput(i, GetReplacementLow(node->InputAt(i))); 8941cb0ef41Sopenharmony_ci high_node->ReplaceInput(i, GetReplacementHigh(node->InputAt(i))); 8951cb0ef41Sopenharmony_ci } 8961cb0ef41Sopenharmony_ci } else { 8971cb0ef41Sopenharmony_ci DefaultLowering(node); 8981cb0ef41Sopenharmony_ci } 8991cb0ef41Sopenharmony_ci break; 9001cb0ef41Sopenharmony_ci } 9011cb0ef41Sopenharmony_ci case IrOpcode::kLoopExitValue: { 9021cb0ef41Sopenharmony_ci MachineRepresentation rep = LoopExitValueRepresentationOf(node->op()); 9031cb0ef41Sopenharmony_ci if (rep == MachineRepresentation::kWord64) { 9041cb0ef41Sopenharmony_ci Node* low_node = graph()->NewNode( 9051cb0ef41Sopenharmony_ci common()->LoopExitValue(MachineRepresentation::kWord32), 9061cb0ef41Sopenharmony_ci GetReplacementLow(node->InputAt(0)), node->InputAt(1)); 9071cb0ef41Sopenharmony_ci Node* high_node = graph()->NewNode( 9081cb0ef41Sopenharmony_ci common()->LoopExitValue(MachineRepresentation::kWord32), 9091cb0ef41Sopenharmony_ci GetReplacementHigh(node->InputAt(0)), node->InputAt(1)); 9101cb0ef41Sopenharmony_ci ReplaceNode(node, low_node, high_node); 9111cb0ef41Sopenharmony_ci } else { 9121cb0ef41Sopenharmony_ci DefaultLowering(node); 9131cb0ef41Sopenharmony_ci } 9141cb0ef41Sopenharmony_ci break; 9151cb0ef41Sopenharmony_ci } 9161cb0ef41Sopenharmony_ci case IrOpcode::kWord64ReverseBytes: { 9171cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 9181cb0ef41Sopenharmony_ci ReplaceNode(node, 9191cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32ReverseBytes(), 9201cb0ef41Sopenharmony_ci GetReplacementHigh(input)), 9211cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32ReverseBytes(), 9221cb0ef41Sopenharmony_ci GetReplacementLow(input))); 9231cb0ef41Sopenharmony_ci break; 9241cb0ef41Sopenharmony_ci } 9251cb0ef41Sopenharmony_ci case IrOpcode::kSignExtendWord8ToInt64: { 9261cb0ef41Sopenharmony_ci DCHECK_EQ(1, node->InputCount()); 9271cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 9281cb0ef41Sopenharmony_ci if (HasReplacementLow(input)) { 9291cb0ef41Sopenharmony_ci input = GetReplacementLow(input); 9301cb0ef41Sopenharmony_ci } 9311cb0ef41Sopenharmony_ci // Sign extend low node to Int32 9321cb0ef41Sopenharmony_ci input = graph()->NewNode(machine()->SignExtendWord8ToInt32(), input); 9331cb0ef41Sopenharmony_ci 9341cb0ef41Sopenharmony_ci // We use SAR to preserve the sign in the high word. 9351cb0ef41Sopenharmony_ci ReplaceNode( 9361cb0ef41Sopenharmony_ci node, input, 9371cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Sar(), input, 9381cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(31)))); 9391cb0ef41Sopenharmony_ci node->NullAllInputs(); 9401cb0ef41Sopenharmony_ci break; 9411cb0ef41Sopenharmony_ci } 9421cb0ef41Sopenharmony_ci case IrOpcode::kSignExtendWord16ToInt64: { 9431cb0ef41Sopenharmony_ci DCHECK_EQ(1, node->InputCount()); 9441cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 9451cb0ef41Sopenharmony_ci if (HasReplacementLow(input)) { 9461cb0ef41Sopenharmony_ci input = GetReplacementLow(input); 9471cb0ef41Sopenharmony_ci } 9481cb0ef41Sopenharmony_ci // Sign extend low node to Int32 9491cb0ef41Sopenharmony_ci input = graph()->NewNode(machine()->SignExtendWord16ToInt32(), input); 9501cb0ef41Sopenharmony_ci 9511cb0ef41Sopenharmony_ci // We use SAR to preserve the sign in the high word. 9521cb0ef41Sopenharmony_ci ReplaceNode( 9531cb0ef41Sopenharmony_ci node, input, 9541cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Sar(), input, 9551cb0ef41Sopenharmony_ci graph()->NewNode(common()->Int32Constant(31)))); 9561cb0ef41Sopenharmony_ci node->NullAllInputs(); 9571cb0ef41Sopenharmony_ci break; 9581cb0ef41Sopenharmony_ci } 9591cb0ef41Sopenharmony_ci case IrOpcode::kWord64AtomicLoad: { 9601cb0ef41Sopenharmony_ci DCHECK_EQ(4, node->InputCount()); 9611cb0ef41Sopenharmony_ci AtomicLoadParameters params = AtomicLoadParametersOf(node->op()); 9621cb0ef41Sopenharmony_ci DefaultLowering(node, true); 9631cb0ef41Sopenharmony_ci if (params.representation() == MachineType::Uint64()) { 9641cb0ef41Sopenharmony_ci NodeProperties::ChangeOp( 9651cb0ef41Sopenharmony_ci node, machine()->Word32AtomicPairLoad(params.order())); 9661cb0ef41Sopenharmony_ci ReplaceNodeWithProjections(node); 9671cb0ef41Sopenharmony_ci } else { 9681cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, machine()->Word32AtomicLoad(params)); 9691cb0ef41Sopenharmony_ci ReplaceNode(node, node, graph()->NewNode(common()->Int32Constant(0))); 9701cb0ef41Sopenharmony_ci } 9711cb0ef41Sopenharmony_ci break; 9721cb0ef41Sopenharmony_ci } 9731cb0ef41Sopenharmony_ci case IrOpcode::kWord64AtomicStore: { 9741cb0ef41Sopenharmony_ci DCHECK_EQ(5, node->InputCount()); 9751cb0ef41Sopenharmony_ci AtomicStoreParameters params = AtomicStoreParametersOf(node->op()); 9761cb0ef41Sopenharmony_ci if (params.representation() == MachineRepresentation::kWord64) { 9771cb0ef41Sopenharmony_ci LowerMemoryBaseAndIndex(node); 9781cb0ef41Sopenharmony_ci Node* value = node->InputAt(2); 9791cb0ef41Sopenharmony_ci node->ReplaceInput(2, GetReplacementLow(value)); 9801cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, GetReplacementHigh(value)); 9811cb0ef41Sopenharmony_ci NodeProperties::ChangeOp( 9821cb0ef41Sopenharmony_ci node, machine()->Word32AtomicPairStore(params.order())); 9831cb0ef41Sopenharmony_ci } else { 9841cb0ef41Sopenharmony_ci DefaultLowering(node, true); 9851cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, machine()->Word32AtomicStore(params)); 9861cb0ef41Sopenharmony_ci } 9871cb0ef41Sopenharmony_ci break; 9881cb0ef41Sopenharmony_ci } 9891cb0ef41Sopenharmony_ci#define ATOMIC_CASE(name) \ 9901cb0ef41Sopenharmony_ci case IrOpcode::kWord64Atomic##name: { \ 9911cb0ef41Sopenharmony_ci MachineType type = AtomicOpType(node->op()); \ 9921cb0ef41Sopenharmony_ci if (type == MachineType::Uint64()) { \ 9931cb0ef41Sopenharmony_ci LowerWord64AtomicBinop(node, machine()->Word32AtomicPair##name()); \ 9941cb0ef41Sopenharmony_ci } else { \ 9951cb0ef41Sopenharmony_ci LowerWord64AtomicNarrowOp(node, machine()->Word32Atomic##name(type)); \ 9961cb0ef41Sopenharmony_ci } \ 9971cb0ef41Sopenharmony_ci break; \ 9981cb0ef41Sopenharmony_ci } 9991cb0ef41Sopenharmony_ci ATOMIC_CASE(Add) 10001cb0ef41Sopenharmony_ci ATOMIC_CASE(Sub) 10011cb0ef41Sopenharmony_ci ATOMIC_CASE(And) 10021cb0ef41Sopenharmony_ci ATOMIC_CASE(Or) 10031cb0ef41Sopenharmony_ci ATOMIC_CASE(Xor) 10041cb0ef41Sopenharmony_ci ATOMIC_CASE(Exchange) 10051cb0ef41Sopenharmony_ci#undef ATOMIC_CASE 10061cb0ef41Sopenharmony_ci case IrOpcode::kWord64AtomicCompareExchange: { 10071cb0ef41Sopenharmony_ci MachineType type = AtomicOpType(node->op()); 10081cb0ef41Sopenharmony_ci if (type == MachineType::Uint64()) { 10091cb0ef41Sopenharmony_ci LowerMemoryBaseAndIndex(node); 10101cb0ef41Sopenharmony_ci Node* old_value = node->InputAt(2); 10111cb0ef41Sopenharmony_ci Node* new_value = node->InputAt(3); 10121cb0ef41Sopenharmony_ci node->ReplaceInput(2, GetReplacementLow(old_value)); 10131cb0ef41Sopenharmony_ci node->ReplaceInput(3, GetReplacementHigh(old_value)); 10141cb0ef41Sopenharmony_ci node->InsertInput(zone(), 4, GetReplacementLow(new_value)); 10151cb0ef41Sopenharmony_ci node->InsertInput(zone(), 5, GetReplacementHigh(new_value)); 10161cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, 10171cb0ef41Sopenharmony_ci machine()->Word32AtomicPairCompareExchange()); 10181cb0ef41Sopenharmony_ci ReplaceNodeWithProjections(node); 10191cb0ef41Sopenharmony_ci } else { 10201cb0ef41Sopenharmony_ci DCHECK(type == MachineType::Uint32() || type == MachineType::Uint16() || 10211cb0ef41Sopenharmony_ci type == MachineType::Uint8()); 10221cb0ef41Sopenharmony_ci DefaultLowering(node, true); 10231cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, 10241cb0ef41Sopenharmony_ci machine()->Word32AtomicCompareExchange(type)); 10251cb0ef41Sopenharmony_ci ReplaceNode(node, node, graph()->NewNode(common()->Int32Constant(0))); 10261cb0ef41Sopenharmony_ci } 10271cb0ef41Sopenharmony_ci break; 10281cb0ef41Sopenharmony_ci } 10291cb0ef41Sopenharmony_ci case IrOpcode::kI64x2Splat: { 10301cb0ef41Sopenharmony_ci DCHECK_EQ(1, node->InputCount()); 10311cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 10321cb0ef41Sopenharmony_ci node->ReplaceInput(0, GetReplacementLow(input)); 10331cb0ef41Sopenharmony_ci node->AppendInput(zone(), GetReplacementHigh(input)); 10341cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, machine()->I64x2SplatI32Pair()); 10351cb0ef41Sopenharmony_ci break; 10361cb0ef41Sopenharmony_ci } 10371cb0ef41Sopenharmony_ci case IrOpcode::kI64x2ExtractLane: { 10381cb0ef41Sopenharmony_ci DCHECK_EQ(1, node->InputCount()); 10391cb0ef41Sopenharmony_ci Node* input = node->InputAt(0); 10401cb0ef41Sopenharmony_ci int32_t lane = OpParameter<int32_t>(node->op()); 10411cb0ef41Sopenharmony_ci ReplaceNode( 10421cb0ef41Sopenharmony_ci node, graph()->NewNode(machine()->I32x4ExtractLane(lane * 2), input), 10431cb0ef41Sopenharmony_ci graph()->NewNode(machine()->I32x4ExtractLane(lane * 2 + 1), input)); 10441cb0ef41Sopenharmony_ci break; 10451cb0ef41Sopenharmony_ci } 10461cb0ef41Sopenharmony_ci case IrOpcode::kI64x2ReplaceLane: { 10471cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 10481cb0ef41Sopenharmony_ci int32_t lane = OpParameter<int32_t>(node->op()); 10491cb0ef41Sopenharmony_ci Node* input = node->InputAt(1); 10501cb0ef41Sopenharmony_ci node->ReplaceInput(1, GetReplacementLow(input)); 10511cb0ef41Sopenharmony_ci node->AppendInput(zone(), GetReplacementHigh(input)); 10521cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, machine()->I64x2ReplaceLaneI32Pair(lane)); 10531cb0ef41Sopenharmony_ci break; 10541cb0ef41Sopenharmony_ci } 10551cb0ef41Sopenharmony_ci 10561cb0ef41Sopenharmony_ci default: { DefaultLowering(node); } 10571cb0ef41Sopenharmony_ci } 10581cb0ef41Sopenharmony_ci} 10591cb0ef41Sopenharmony_ci 10601cb0ef41Sopenharmony_civoid Int64Lowering::LowerComparison(Node* node, const Operator* high_word_op, 10611cb0ef41Sopenharmony_ci const Operator* low_word_op) { 10621cb0ef41Sopenharmony_ci DCHECK_EQ(2, node->InputCount()); 10631cb0ef41Sopenharmony_ci Node* left = node->InputAt(0); 10641cb0ef41Sopenharmony_ci Node* right = node->InputAt(1); 10651cb0ef41Sopenharmony_ci Node* replacement = graph()->NewNode( 10661cb0ef41Sopenharmony_ci machine()->Word32Or(), 10671cb0ef41Sopenharmony_ci graph()->NewNode(high_word_op, GetReplacementHigh(left), 10681cb0ef41Sopenharmony_ci GetReplacementHigh(right)), 10691cb0ef41Sopenharmony_ci graph()->NewNode( 10701cb0ef41Sopenharmony_ci machine()->Word32And(), 10711cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Word32Equal(), GetReplacementHigh(left), 10721cb0ef41Sopenharmony_ci GetReplacementHigh(right)), 10731cb0ef41Sopenharmony_ci graph()->NewNode(low_word_op, GetReplacementLow(left), 10741cb0ef41Sopenharmony_ci GetReplacementLow(right)))); 10751cb0ef41Sopenharmony_ci 10761cb0ef41Sopenharmony_ci ReplaceNode(node, replacement, nullptr); 10771cb0ef41Sopenharmony_ci} 10781cb0ef41Sopenharmony_ci 10791cb0ef41Sopenharmony_cibool Int64Lowering::DefaultLowering(Node* node, bool low_word_only) { 10801cb0ef41Sopenharmony_ci bool something_changed = false; 10811cb0ef41Sopenharmony_ci for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) { 10821cb0ef41Sopenharmony_ci Node* input = node->InputAt(i); 10831cb0ef41Sopenharmony_ci if (HasReplacementLow(input)) { 10841cb0ef41Sopenharmony_ci something_changed = true; 10851cb0ef41Sopenharmony_ci node->ReplaceInput(i, GetReplacementLow(input)); 10861cb0ef41Sopenharmony_ci } 10871cb0ef41Sopenharmony_ci if (!low_word_only && HasReplacementHigh(input)) { 10881cb0ef41Sopenharmony_ci something_changed = true; 10891cb0ef41Sopenharmony_ci node->InsertInput(zone(), i + 1, GetReplacementHigh(input)); 10901cb0ef41Sopenharmony_ci } 10911cb0ef41Sopenharmony_ci } 10921cb0ef41Sopenharmony_ci return something_changed; 10931cb0ef41Sopenharmony_ci} 10941cb0ef41Sopenharmony_ci 10951cb0ef41Sopenharmony_ciconst CallDescriptor* Int64Lowering::LowerCallDescriptor( 10961cb0ef41Sopenharmony_ci const CallDescriptor* call_descriptor) { 10971cb0ef41Sopenharmony_ci if (special_case_) { 10981cb0ef41Sopenharmony_ci auto replacement = special_case_->replacements.find(call_descriptor); 10991cb0ef41Sopenharmony_ci if (replacement != special_case_->replacements.end()) { 11001cb0ef41Sopenharmony_ci return replacement->second; 11011cb0ef41Sopenharmony_ci } 11021cb0ef41Sopenharmony_ci } 11031cb0ef41Sopenharmony_ci return GetI32WasmCallDescriptor(zone(), call_descriptor); 11041cb0ef41Sopenharmony_ci} 11051cb0ef41Sopenharmony_ci 11061cb0ef41Sopenharmony_civoid Int64Lowering::ReplaceNode(Node* old, Node* new_low, Node* new_high) { 11071cb0ef41Sopenharmony_ci // if new_low == nullptr, then also new_high == nullptr. 11081cb0ef41Sopenharmony_ci DCHECK(new_low != nullptr || new_high == nullptr); 11091cb0ef41Sopenharmony_ci replacements_[old->id()].low = new_low; 11101cb0ef41Sopenharmony_ci replacements_[old->id()].high = new_high; 11111cb0ef41Sopenharmony_ci} 11121cb0ef41Sopenharmony_ci 11131cb0ef41Sopenharmony_cibool Int64Lowering::HasReplacementLow(Node* node) { 11141cb0ef41Sopenharmony_ci return replacements_[node->id()].low != nullptr; 11151cb0ef41Sopenharmony_ci} 11161cb0ef41Sopenharmony_ci 11171cb0ef41Sopenharmony_ciNode* Int64Lowering::GetReplacementLow(Node* node) { 11181cb0ef41Sopenharmony_ci Node* result = replacements_[node->id()].low; 11191cb0ef41Sopenharmony_ci DCHECK(result); 11201cb0ef41Sopenharmony_ci return result; 11211cb0ef41Sopenharmony_ci} 11221cb0ef41Sopenharmony_ci 11231cb0ef41Sopenharmony_cibool Int64Lowering::HasReplacementHigh(Node* node) { 11241cb0ef41Sopenharmony_ci return replacements_[node->id()].high != nullptr; 11251cb0ef41Sopenharmony_ci} 11261cb0ef41Sopenharmony_ci 11271cb0ef41Sopenharmony_ciNode* Int64Lowering::GetReplacementHigh(Node* node) { 11281cb0ef41Sopenharmony_ci Node* result = replacements_[node->id()].high; 11291cb0ef41Sopenharmony_ci DCHECK(result); 11301cb0ef41Sopenharmony_ci return result; 11311cb0ef41Sopenharmony_ci} 11321cb0ef41Sopenharmony_ci 11331cb0ef41Sopenharmony_civoid Int64Lowering::PreparePhiReplacement(Node* phi) { 11341cb0ef41Sopenharmony_ci MachineRepresentation rep = PhiRepresentationOf(phi->op()); 11351cb0ef41Sopenharmony_ci if (rep == MachineRepresentation::kWord64) { 11361cb0ef41Sopenharmony_ci // We have to create the replacements for a phi node before we actually 11371cb0ef41Sopenharmony_ci // lower the phi to break potential cycles in the graph. The replacements of 11381cb0ef41Sopenharmony_ci // input nodes do not exist yet, so we use a placeholder node to pass the 11391cb0ef41Sopenharmony_ci // graph verifier. 11401cb0ef41Sopenharmony_ci int value_count = phi->op()->ValueInputCount(); 11411cb0ef41Sopenharmony_ci Node** inputs_low = zone()->NewArray<Node*>(value_count + 1); 11421cb0ef41Sopenharmony_ci Node** inputs_high = zone()->NewArray<Node*>(value_count + 1); 11431cb0ef41Sopenharmony_ci for (int i = 0; i < value_count; i++) { 11441cb0ef41Sopenharmony_ci inputs_low[i] = placeholder_; 11451cb0ef41Sopenharmony_ci inputs_high[i] = placeholder_; 11461cb0ef41Sopenharmony_ci } 11471cb0ef41Sopenharmony_ci inputs_low[value_count] = NodeProperties::GetControlInput(phi, 0); 11481cb0ef41Sopenharmony_ci inputs_high[value_count] = NodeProperties::GetControlInput(phi, 0); 11491cb0ef41Sopenharmony_ci ReplaceNode(phi, 11501cb0ef41Sopenharmony_ci graph()->NewNode( 11511cb0ef41Sopenharmony_ci common()->Phi(MachineRepresentation::kWord32, value_count), 11521cb0ef41Sopenharmony_ci value_count + 1, inputs_low, false), 11531cb0ef41Sopenharmony_ci graph()->NewNode( 11541cb0ef41Sopenharmony_ci common()->Phi(MachineRepresentation::kWord32, value_count), 11551cb0ef41Sopenharmony_ci value_count + 1, inputs_high, false)); 11561cb0ef41Sopenharmony_ci } 11571cb0ef41Sopenharmony_ci} 11581cb0ef41Sopenharmony_ci 11591cb0ef41Sopenharmony_civoid Int64Lowering::ReplaceNodeWithProjections(Node* node) { 11601cb0ef41Sopenharmony_ci DCHECK(node != nullptr); 11611cb0ef41Sopenharmony_ci Node* low_node = 11621cb0ef41Sopenharmony_ci graph()->NewNode(common()->Projection(0), node, graph()->start()); 11631cb0ef41Sopenharmony_ci Node* high_node = 11641cb0ef41Sopenharmony_ci graph()->NewNode(common()->Projection(1), node, graph()->start()); 11651cb0ef41Sopenharmony_ci ReplaceNode(node, low_node, high_node); 11661cb0ef41Sopenharmony_ci} 11671cb0ef41Sopenharmony_ci 11681cb0ef41Sopenharmony_civoid Int64Lowering::LowerMemoryBaseAndIndex(Node* node) { 11691cb0ef41Sopenharmony_ci DCHECK(node != nullptr); 11701cb0ef41Sopenharmony_ci // Low word only replacements for memory operands for 32-bit address space. 11711cb0ef41Sopenharmony_ci Node* base = node->InputAt(0); 11721cb0ef41Sopenharmony_ci Node* index = node->InputAt(1); 11731cb0ef41Sopenharmony_ci if (HasReplacementLow(base)) { 11741cb0ef41Sopenharmony_ci node->ReplaceInput(0, GetReplacementLow(base)); 11751cb0ef41Sopenharmony_ci } 11761cb0ef41Sopenharmony_ci if (HasReplacementLow(index)) { 11771cb0ef41Sopenharmony_ci node->ReplaceInput(1, GetReplacementLow(index)); 11781cb0ef41Sopenharmony_ci } 11791cb0ef41Sopenharmony_ci} 11801cb0ef41Sopenharmony_ci 11811cb0ef41Sopenharmony_ci} // namespace compiler 11821cb0ef41Sopenharmony_ci} // namespace internal 11831cb0ef41Sopenharmony_ci} // namespace v8 1184