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