11cb0ef41Sopenharmony_ci// Copyright 2015 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/effect-control-linearizer.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "include/v8-fast-api-calls.h"
81cb0ef41Sopenharmony_ci#include "src/base/bits.h"
91cb0ef41Sopenharmony_ci#include "src/codegen/code-factory.h"
101cb0ef41Sopenharmony_ci#include "src/codegen/interface-descriptors-inl.h"
111cb0ef41Sopenharmony_ci#include "src/codegen/machine-type.h"
121cb0ef41Sopenharmony_ci#include "src/common/ptr-compr-inl.h"
131cb0ef41Sopenharmony_ci#include "src/compiler/access-builder.h"
141cb0ef41Sopenharmony_ci#include "src/compiler/compiler-source-position-table.h"
151cb0ef41Sopenharmony_ci#include "src/compiler/fast-api-calls.h"
161cb0ef41Sopenharmony_ci#include "src/compiler/feedback-source.h"
171cb0ef41Sopenharmony_ci#include "src/compiler/graph-assembler.h"
181cb0ef41Sopenharmony_ci#include "src/compiler/js-graph.h"
191cb0ef41Sopenharmony_ci#include "src/compiler/js-heap-broker.h"
201cb0ef41Sopenharmony_ci#include "src/compiler/linkage.h"
211cb0ef41Sopenharmony_ci#include "src/compiler/memory-lowering.h"
221cb0ef41Sopenharmony_ci#include "src/compiler/node-matchers.h"
231cb0ef41Sopenharmony_ci#include "src/compiler/node-origin-table.h"
241cb0ef41Sopenharmony_ci#include "src/compiler/node-properties.h"
251cb0ef41Sopenharmony_ci#include "src/compiler/node.h"
261cb0ef41Sopenharmony_ci#include "src/compiler/schedule.h"
271cb0ef41Sopenharmony_ci#include "src/compiler/select-lowering.h"
281cb0ef41Sopenharmony_ci#include "src/execution/frames.h"
291cb0ef41Sopenharmony_ci#include "src/heap/factory-inl.h"
301cb0ef41Sopenharmony_ci#include "src/objects/heap-number.h"
311cb0ef41Sopenharmony_ci#include "src/objects/oddball.h"
321cb0ef41Sopenharmony_ci#include "src/objects/ordered-hash-table.h"
331cb0ef41Sopenharmony_ci#include "src/objects/turbofan-types.h"
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_cinamespace v8 {
361cb0ef41Sopenharmony_cinamespace internal {
371cb0ef41Sopenharmony_cinamespace compiler {
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_cienum class MaintainSchedule { kMaintain, kDiscard };
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ciclass EffectControlLinearizer {
421cb0ef41Sopenharmony_ci public:
431cb0ef41Sopenharmony_ci  EffectControlLinearizer(JSGraph* js_graph, Schedule* schedule,
441cb0ef41Sopenharmony_ci                          JSGraphAssembler* graph_assembler, Zone* temp_zone,
451cb0ef41Sopenharmony_ci                          SourcePositionTable* source_positions,
461cb0ef41Sopenharmony_ci                          NodeOriginTable* node_origins,
471cb0ef41Sopenharmony_ci                          MaintainSchedule maintain_schedule,
481cb0ef41Sopenharmony_ci                          JSHeapBroker* broker)
491cb0ef41Sopenharmony_ci      : js_graph_(js_graph),
501cb0ef41Sopenharmony_ci        schedule_(schedule),
511cb0ef41Sopenharmony_ci        temp_zone_(temp_zone),
521cb0ef41Sopenharmony_ci        maintain_schedule_(maintain_schedule),
531cb0ef41Sopenharmony_ci        source_positions_(source_positions),
541cb0ef41Sopenharmony_ci        node_origins_(node_origins),
551cb0ef41Sopenharmony_ci        broker_(broker),
561cb0ef41Sopenharmony_ci        graph_assembler_(graph_assembler),
571cb0ef41Sopenharmony_ci        frame_state_zapper_(nullptr) {}
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci  void Run();
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci private:
621cb0ef41Sopenharmony_ci  void UpdateEffectControlForNode(Node* node);
631cb0ef41Sopenharmony_ci  void ProcessNode(Node* node, Node** frame_state);
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  bool TryWireInStateEffect(Node* node, Node* frame_state);
661cb0ef41Sopenharmony_ci  Node* LowerChangeBitToTagged(Node* node);
671cb0ef41Sopenharmony_ci  Node* LowerChangeInt31ToTaggedSigned(Node* node);
681cb0ef41Sopenharmony_ci  Node* LowerChangeInt32ToTagged(Node* node);
691cb0ef41Sopenharmony_ci  Node* LowerChangeInt64ToTagged(Node* node);
701cb0ef41Sopenharmony_ci  Node* LowerChangeUint32ToTagged(Node* node);
711cb0ef41Sopenharmony_ci  Node* LowerChangeUint64ToTagged(Node* node);
721cb0ef41Sopenharmony_ci  Node* LowerChangeFloat64ToTagged(Node* node);
731cb0ef41Sopenharmony_ci  Node* LowerChangeFloat64ToTaggedPointer(Node* node);
741cb0ef41Sopenharmony_ci  Node* LowerChangeTaggedSignedToInt32(Node* node);
751cb0ef41Sopenharmony_ci  Node* LowerChangeTaggedSignedToInt64(Node* node);
761cb0ef41Sopenharmony_ci  Node* LowerChangeTaggedToBit(Node* node);
771cb0ef41Sopenharmony_ci  Node* LowerChangeTaggedToInt32(Node* node);
781cb0ef41Sopenharmony_ci  Node* LowerChangeTaggedToUint32(Node* node);
791cb0ef41Sopenharmony_ci  Node* LowerChangeTaggedToInt64(Node* node);
801cb0ef41Sopenharmony_ci  Node* LowerChangeTaggedToTaggedSigned(Node* node);
811cb0ef41Sopenharmony_ci  Node* LowerCheckInternalizedString(Node* node, Node* frame_state);
821cb0ef41Sopenharmony_ci  void LowerCheckMaps(Node* node, Node* frame_state);
831cb0ef41Sopenharmony_ci  Node* LowerCompareMaps(Node* node);
841cb0ef41Sopenharmony_ci  Node* LowerCheckNumber(Node* node, Node* frame_state);
851cb0ef41Sopenharmony_ci  Node* LowerCheckClosure(Node* node, Node* frame_state);
861cb0ef41Sopenharmony_ci  Node* LowerCheckReceiver(Node* node, Node* frame_state);
871cb0ef41Sopenharmony_ci  Node* LowerCheckReceiverOrNullOrUndefined(Node* node, Node* frame_state);
881cb0ef41Sopenharmony_ci  Node* LowerCheckString(Node* node, Node* frame_state);
891cb0ef41Sopenharmony_ci  Node* LowerCheckBigInt(Node* node, Node* frame_state);
901cb0ef41Sopenharmony_ci  Node* LowerCheckSymbol(Node* node, Node* frame_state);
911cb0ef41Sopenharmony_ci  void LowerCheckIf(Node* node, Node* frame_state);
921cb0ef41Sopenharmony_ci  Node* LowerCheckedInt32Add(Node* node, Node* frame_state);
931cb0ef41Sopenharmony_ci  Node* LowerCheckedInt32Sub(Node* node, Node* frame_state);
941cb0ef41Sopenharmony_ci  Node* LowerCheckedInt32Div(Node* node, Node* frame_state);
951cb0ef41Sopenharmony_ci  Node* LowerCheckedInt32Mod(Node* node, Node* frame_state);
961cb0ef41Sopenharmony_ci  Node* LowerCheckedUint32Div(Node* node, Node* frame_state);
971cb0ef41Sopenharmony_ci  Node* LowerCheckedUint32Mod(Node* node, Node* frame_state);
981cb0ef41Sopenharmony_ci  Node* LowerCheckedInt32Mul(Node* node, Node* frame_state);
991cb0ef41Sopenharmony_ci  Node* LowerCheckedInt32ToTaggedSigned(Node* node, Node* frame_state);
1001cb0ef41Sopenharmony_ci  Node* LowerCheckedInt64ToInt32(Node* node, Node* frame_state);
1011cb0ef41Sopenharmony_ci  Node* LowerCheckedInt64ToTaggedSigned(Node* node, Node* frame_state);
1021cb0ef41Sopenharmony_ci  Node* LowerCheckedUint32Bounds(Node* node, Node* frame_state);
1031cb0ef41Sopenharmony_ci  Node* LowerCheckedUint32ToInt32(Node* node, Node* frame_state);
1041cb0ef41Sopenharmony_ci  Node* LowerCheckedUint32ToTaggedSigned(Node* node, Node* frame_state);
1051cb0ef41Sopenharmony_ci  Node* LowerCheckedUint64Bounds(Node* node, Node* frame_state);
1061cb0ef41Sopenharmony_ci  Node* LowerCheckedUint64ToInt32(Node* node, Node* frame_state);
1071cb0ef41Sopenharmony_ci  Node* LowerCheckedUint64ToTaggedSigned(Node* node, Node* frame_state);
1081cb0ef41Sopenharmony_ci  Node* LowerCheckedFloat64ToInt32(Node* node, Node* frame_state);
1091cb0ef41Sopenharmony_ci  Node* LowerCheckedFloat64ToInt64(Node* node, Node* frame_state);
1101cb0ef41Sopenharmony_ci  Node* LowerCheckedTaggedSignedToInt32(Node* node, Node* frame_state);
1111cb0ef41Sopenharmony_ci  Node* LowerCheckedTaggedToArrayIndex(Node* node, Node* frame_state);
1121cb0ef41Sopenharmony_ci  Node* LowerCheckedTaggedToInt32(Node* node, Node* frame_state);
1131cb0ef41Sopenharmony_ci  Node* LowerCheckedTaggedToInt64(Node* node, Node* frame_state);
1141cb0ef41Sopenharmony_ci  Node* LowerCheckedTaggedToFloat64(Node* node, Node* frame_state);
1151cb0ef41Sopenharmony_ci  Node* LowerCheckedTaggedToTaggedSigned(Node* node, Node* frame_state);
1161cb0ef41Sopenharmony_ci  Node* LowerCheckedTaggedToTaggedPointer(Node* node, Node* frame_state);
1171cb0ef41Sopenharmony_ci  Node* LowerChangeInt64ToBigInt(Node* node);
1181cb0ef41Sopenharmony_ci  Node* LowerChangeUint64ToBigInt(Node* node);
1191cb0ef41Sopenharmony_ci  Node* LowerTruncateBigIntToWord64(Node* node);
1201cb0ef41Sopenharmony_ci  Node* LowerChangeTaggedToFloat64(Node* node);
1211cb0ef41Sopenharmony_ci  void TruncateTaggedPointerToBit(Node* node, GraphAssemblerLabel<1>* done);
1221cb0ef41Sopenharmony_ci  Node* LowerTruncateTaggedToBit(Node* node);
1231cb0ef41Sopenharmony_ci  Node* LowerTruncateTaggedPointerToBit(Node* node);
1241cb0ef41Sopenharmony_ci  Node* LowerTruncateTaggedToFloat64(Node* node);
1251cb0ef41Sopenharmony_ci  Node* LowerTruncateTaggedToWord32(Node* node);
1261cb0ef41Sopenharmony_ci  Node* LowerCheckedTruncateTaggedToWord32(Node* node, Node* frame_state);
1271cb0ef41Sopenharmony_ci  Node* LowerAllocate(Node* node);
1281cb0ef41Sopenharmony_ci  Node* LowerNumberToString(Node* node);
1291cb0ef41Sopenharmony_ci  Node* LowerObjectIsArrayBufferView(Node* node);
1301cb0ef41Sopenharmony_ci  Node* LowerObjectIsBigInt(Node* node);
1311cb0ef41Sopenharmony_ci  Node* LowerObjectIsCallable(Node* node);
1321cb0ef41Sopenharmony_ci  Node* LowerObjectIsConstructor(Node* node);
1331cb0ef41Sopenharmony_ci  Node* LowerObjectIsDetectableCallable(Node* node);
1341cb0ef41Sopenharmony_ci  Node* LowerObjectIsMinusZero(Node* node);
1351cb0ef41Sopenharmony_ci  Node* LowerNumberIsMinusZero(Node* node);
1361cb0ef41Sopenharmony_ci  Node* LowerObjectIsNaN(Node* node);
1371cb0ef41Sopenharmony_ci  Node* LowerNumberIsNaN(Node* node);
1381cb0ef41Sopenharmony_ci  Node* LowerObjectIsNonCallable(Node* node);
1391cb0ef41Sopenharmony_ci  Node* LowerObjectIsNumber(Node* node);
1401cb0ef41Sopenharmony_ci  Node* LowerObjectIsReceiver(Node* node);
1411cb0ef41Sopenharmony_ci  Node* LowerObjectIsSmi(Node* node);
1421cb0ef41Sopenharmony_ci  Node* LowerObjectIsString(Node* node);
1431cb0ef41Sopenharmony_ci  Node* LowerObjectIsSymbol(Node* node);
1441cb0ef41Sopenharmony_ci  Node* LowerObjectIsUndetectable(Node* node);
1451cb0ef41Sopenharmony_ci  Node* LowerNumberIsFloat64Hole(Node* node);
1461cb0ef41Sopenharmony_ci  Node* LowerNumberIsFinite(Node* node);
1471cb0ef41Sopenharmony_ci  Node* LowerObjectIsFiniteNumber(Node* node);
1481cb0ef41Sopenharmony_ci  Node* LowerNumberIsInteger(Node* node);
1491cb0ef41Sopenharmony_ci  Node* LowerObjectIsInteger(Node* node);
1501cb0ef41Sopenharmony_ci  Node* LowerNumberIsSafeInteger(Node* node);
1511cb0ef41Sopenharmony_ci  Node* LowerObjectIsSafeInteger(Node* node);
1521cb0ef41Sopenharmony_ci  Node* LowerArgumentsLength(Node* node);
1531cb0ef41Sopenharmony_ci  Node* LowerRestLength(Node* node);
1541cb0ef41Sopenharmony_ci  Node* LowerNewDoubleElements(Node* node);
1551cb0ef41Sopenharmony_ci  Node* LowerNewSmiOrObjectElements(Node* node);
1561cb0ef41Sopenharmony_ci  Node* LowerNewArgumentsElements(Node* node);
1571cb0ef41Sopenharmony_ci  Node* LowerNewConsString(Node* node);
1581cb0ef41Sopenharmony_ci  Node* LowerSameValue(Node* node);
1591cb0ef41Sopenharmony_ci  Node* LowerSameValueNumbersOnly(Node* node);
1601cb0ef41Sopenharmony_ci  Node* LowerNumberSameValue(Node* node);
1611cb0ef41Sopenharmony_ci  Node* LowerDeadValue(Node* node);
1621cb0ef41Sopenharmony_ci  Node* LowerStringConcat(Node* node);
1631cb0ef41Sopenharmony_ci  Node* LowerStringToNumber(Node* node);
1641cb0ef41Sopenharmony_ci  Node* LowerStringCharCodeAt(Node* node);
1651cb0ef41Sopenharmony_ci  Node* StringCharCodeAt(Node* receiver, Node* position);
1661cb0ef41Sopenharmony_ci  Node* LowerStringCodePointAt(Node* node);
1671cb0ef41Sopenharmony_ci  Node* LowerStringToLowerCaseIntl(Node* node);
1681cb0ef41Sopenharmony_ci  Node* LowerStringToUpperCaseIntl(Node* node);
1691cb0ef41Sopenharmony_ci  Node* LowerStringFromSingleCharCode(Node* node);
1701cb0ef41Sopenharmony_ci  Node* LowerStringFromSingleCodePoint(Node* node);
1711cb0ef41Sopenharmony_ci  Node* LowerStringIndexOf(Node* node);
1721cb0ef41Sopenharmony_ci  Node* LowerStringSubstring(Node* node);
1731cb0ef41Sopenharmony_ci  Node* LowerStringFromCodePointAt(Node* node);
1741cb0ef41Sopenharmony_ci  Node* LowerStringLength(Node* node);
1751cb0ef41Sopenharmony_ci  Node* LowerStringEqual(Node* node);
1761cb0ef41Sopenharmony_ci  Node* LowerStringLessThan(Node* node);
1771cb0ef41Sopenharmony_ci  Node* LowerStringLessThanOrEqual(Node* node);
1781cb0ef41Sopenharmony_ci  Node* LowerBigIntAdd(Node* node, Node* frame_state);
1791cb0ef41Sopenharmony_ci  Node* LowerBigIntSubtract(Node* node, Node* frame_state);
1801cb0ef41Sopenharmony_ci  Node* LowerBigIntNegate(Node* node);
1811cb0ef41Sopenharmony_ci  Node* LowerCheckFloat64Hole(Node* node, Node* frame_state);
1821cb0ef41Sopenharmony_ci  Node* LowerCheckNotTaggedHole(Node* node, Node* frame_state);
1831cb0ef41Sopenharmony_ci  Node* LowerConvertTaggedHoleToUndefined(Node* node);
1841cb0ef41Sopenharmony_ci  void LowerCheckEqualsInternalizedString(Node* node, Node* frame_state);
1851cb0ef41Sopenharmony_ci  void LowerCheckEqualsSymbol(Node* node, Node* frame_state);
1861cb0ef41Sopenharmony_ci  Node* LowerTypeOf(Node* node);
1871cb0ef41Sopenharmony_ci  Node* LowerToBoolean(Node* node);
1881cb0ef41Sopenharmony_ci  Node* LowerPlainPrimitiveToNumber(Node* node);
1891cb0ef41Sopenharmony_ci  Node* LowerPlainPrimitiveToWord32(Node* node);
1901cb0ef41Sopenharmony_ci  Node* LowerPlainPrimitiveToFloat64(Node* node);
1911cb0ef41Sopenharmony_ci  Node* LowerEnsureWritableFastElements(Node* node);
1921cb0ef41Sopenharmony_ci  Node* LowerMaybeGrowFastElements(Node* node, Node* frame_state);
1931cb0ef41Sopenharmony_ci  void LowerTransitionElementsKind(Node* node);
1941cb0ef41Sopenharmony_ci  Node* LowerLoadFieldByIndex(Node* node);
1951cb0ef41Sopenharmony_ci  Node* LowerLoadMessage(Node* node);
1961cb0ef41Sopenharmony_ci  Node* AdaptFastCallTypedArrayArgument(Node* node,
1971cb0ef41Sopenharmony_ci                                        ElementsKind expected_elements_kind,
1981cb0ef41Sopenharmony_ci                                        GraphAssemblerLabel<0>* bailout);
1991cb0ef41Sopenharmony_ci  Node* AdaptFastCallArgument(Node* node, CTypeInfo arg_type,
2001cb0ef41Sopenharmony_ci                              GraphAssemblerLabel<0>* if_error);
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ci  struct AdaptOverloadedFastCallResult {
2031cb0ef41Sopenharmony_ci    Node* target_address;
2041cb0ef41Sopenharmony_ci    Node* argument;
2051cb0ef41Sopenharmony_ci  };
2061cb0ef41Sopenharmony_ci  AdaptOverloadedFastCallResult AdaptOverloadedFastCallArgument(
2071cb0ef41Sopenharmony_ci      Node* node, const FastApiCallFunctionVector& c_functions,
2081cb0ef41Sopenharmony_ci      const fast_api_call::OverloadsResolutionResult&
2091cb0ef41Sopenharmony_ci          overloads_resolution_result,
2101cb0ef41Sopenharmony_ci      GraphAssemblerLabel<0>* if_error);
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ci  Node* WrapFastCall(const CallDescriptor* call_descriptor, int inputs_size,
2131cb0ef41Sopenharmony_ci                     Node** inputs, Node* target,
2141cb0ef41Sopenharmony_ci                     const CFunctionInfo* c_signature, int c_arg_count,
2151cb0ef41Sopenharmony_ci                     Node* stack_slot);
2161cb0ef41Sopenharmony_ci  Node* GenerateSlowApiCall(Node* node);
2171cb0ef41Sopenharmony_ci  Node* LowerFastApiCall(Node* node);
2181cb0ef41Sopenharmony_ci  Node* LowerLoadTypedElement(Node* node);
2191cb0ef41Sopenharmony_ci  Node* LowerLoadDataViewElement(Node* node);
2201cb0ef41Sopenharmony_ci  Node* LowerLoadStackArgument(Node* node);
2211cb0ef41Sopenharmony_ci  void LowerStoreMessage(Node* node);
2221cb0ef41Sopenharmony_ci  void LowerStoreTypedElement(Node* node);
2231cb0ef41Sopenharmony_ci  void LowerStoreDataViewElement(Node* node);
2241cb0ef41Sopenharmony_ci  void LowerStoreSignedSmallElement(Node* node);
2251cb0ef41Sopenharmony_ci  Node* LowerFindOrderedHashMapEntry(Node* node);
2261cb0ef41Sopenharmony_ci  Node* LowerFindOrderedHashMapEntryForInt32Key(Node* node);
2271cb0ef41Sopenharmony_ci  void LowerTransitionAndStoreElement(Node* node);
2281cb0ef41Sopenharmony_ci  void LowerTransitionAndStoreNumberElement(Node* node);
2291cb0ef41Sopenharmony_ci  void LowerTransitionAndStoreNonNumberElement(Node* node);
2301cb0ef41Sopenharmony_ci  void LowerRuntimeAbort(Node* node);
2311cb0ef41Sopenharmony_ci  Node* LowerAssertType(Node* node);
2321cb0ef41Sopenharmony_ci  Node* LowerFoldConstant(Node* node);
2331cb0ef41Sopenharmony_ci  Node* LowerConvertReceiver(Node* node);
2341cb0ef41Sopenharmony_ci  Node* LowerDateNow(Node* node);
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci  // Lowering of optional operators.
2371cb0ef41Sopenharmony_ci  Maybe<Node*> LowerFloat64RoundUp(Node* node);
2381cb0ef41Sopenharmony_ci  Maybe<Node*> LowerFloat64RoundDown(Node* node);
2391cb0ef41Sopenharmony_ci  Maybe<Node*> LowerFloat64RoundTiesEven(Node* node);
2401cb0ef41Sopenharmony_ci  Maybe<Node*> LowerFloat64RoundTruncate(Node* node);
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_ci  Node* AllocateHeapNumberWithValue(Node* node);
2431cb0ef41Sopenharmony_ci  Node* BuildCheckedFloat64ToInt32(CheckForMinusZeroMode mode,
2441cb0ef41Sopenharmony_ci                                   const FeedbackSource& feedback, Node* value,
2451cb0ef41Sopenharmony_ci                                   Node* frame_state);
2461cb0ef41Sopenharmony_ci  Node* BuildCheckedFloat64ToInt64(CheckForMinusZeroMode mode,
2471cb0ef41Sopenharmony_ci                                   const FeedbackSource& feedback, Node* value,
2481cb0ef41Sopenharmony_ci                                   Node* frame_state);
2491cb0ef41Sopenharmony_ci  Node* BuildCheckedFloat64ToIndex(const FeedbackSource& feedback, Node* value,
2501cb0ef41Sopenharmony_ci                                   Node* frame_state);
2511cb0ef41Sopenharmony_ci  Node* BuildCheckedHeapNumberOrOddballToFloat64(CheckTaggedInputMode mode,
2521cb0ef41Sopenharmony_ci                                                 const FeedbackSource& feedback,
2531cb0ef41Sopenharmony_ci                                                 Node* value,
2541cb0ef41Sopenharmony_ci                                                 Node* frame_state);
2551cb0ef41Sopenharmony_ci  Node* BuildReverseBytes(ExternalArrayType type, Node* value);
2561cb0ef41Sopenharmony_ci  Node* BuildFloat64RoundDown(Node* value);
2571cb0ef41Sopenharmony_ci  Node* BuildFloat64RoundTruncate(Node* input);
2581cb0ef41Sopenharmony_ci  template <size_t VarCount, size_t VarCount2>
2591cb0ef41Sopenharmony_ci  void SmiTagOrOverflow(Node* value, GraphAssemblerLabel<VarCount>* if_overflow,
2601cb0ef41Sopenharmony_ci                        GraphAssemblerLabel<VarCount2>* done);
2611cb0ef41Sopenharmony_ci  Node* SmiTagOrDeopt(Node* value, const CheckParameters& params,
2621cb0ef41Sopenharmony_ci                      Node* frame_state);
2631cb0ef41Sopenharmony_ci  Node* BuildUint32Mod(Node* lhs, Node* rhs);
2641cb0ef41Sopenharmony_ci  Node* ComputeUnseededHash(Node* value);
2651cb0ef41Sopenharmony_ci  Node* LowerStringComparison(Callable const& callable, Node* node);
2661cb0ef41Sopenharmony_ci  Node* IsElementsKindGreaterThan(Node* kind, ElementsKind reference_kind);
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci  Node* BuildTypedArrayDataPointer(Node* base, Node* external);
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci  template <typename... Args>
2711cb0ef41Sopenharmony_ci  Node* CallBuiltin(Builtin builtin, Operator::Properties properties, Args...);
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_ci  Node* ChangeBitToTagged(Node* value);
2741cb0ef41Sopenharmony_ci  Node* ChangeFloat64ToTagged(Node* value, CheckForMinusZeroMode mode);
2751cb0ef41Sopenharmony_ci  Node* ChangeInt32ToSmi(Node* value);
2761cb0ef41Sopenharmony_ci  // In pointer compression, we smi-corrupt. This means the upper bits of a Smi
2771cb0ef41Sopenharmony_ci  // are not important. ChangeTaggedInt32ToSmi has a known tagged int32 as input
2781cb0ef41Sopenharmony_ci  // and takes advantage of the smi corruption by emitting a Bitcast node
2791cb0ef41Sopenharmony_ci  // instead of a Change node in order to save instructions.
2801cb0ef41Sopenharmony_ci  // In non pointer compression, it behaves like ChangeInt32ToSmi.
2811cb0ef41Sopenharmony_ci  Node* ChangeTaggedInt32ToSmi(Node* value);
2821cb0ef41Sopenharmony_ci  Node* ChangeInt32ToIntPtr(Node* value);
2831cb0ef41Sopenharmony_ci  Node* ChangeInt32ToTagged(Node* value);
2841cb0ef41Sopenharmony_ci  Node* ChangeInt64ToSmi(Node* value);
2851cb0ef41Sopenharmony_ci  Node* ChangeIntPtrToInt32(Node* value);
2861cb0ef41Sopenharmony_ci  Node* ChangeIntPtrToSmi(Node* value);
2871cb0ef41Sopenharmony_ci  Node* ChangeUint32ToUintPtr(Node* value);
2881cb0ef41Sopenharmony_ci  Node* ChangeUint32ToSmi(Node* value);
2891cb0ef41Sopenharmony_ci  Node* ChangeUint32ToTagged(Node* value);
2901cb0ef41Sopenharmony_ci  Node* ChangeSmiToIntPtr(Node* value);
2911cb0ef41Sopenharmony_ci  Node* ChangeSmiToInt32(Node* value);
2921cb0ef41Sopenharmony_ci  Node* ChangeSmiToInt64(Node* value);
2931cb0ef41Sopenharmony_ci  Node* ObjectIsSmi(Node* value);
2941cb0ef41Sopenharmony_ci  Node* LoadFromSeqString(Node* receiver, Node* position, Node* is_one_byte);
2951cb0ef41Sopenharmony_ci  Node* TruncateWordToInt32(Node* value);
2961cb0ef41Sopenharmony_ci  Node* MakeWeakForComparison(Node* heap_object);
2971cb0ef41Sopenharmony_ci  Node* BuildIsWeakReferenceTo(Node* maybe_object, Node* value);
2981cb0ef41Sopenharmony_ci  Node* BuildIsClearedWeakReference(Node* maybe_object);
2991cb0ef41Sopenharmony_ci  Node* BuildIsStrongReference(Node* value);
3001cb0ef41Sopenharmony_ci  Node* BuildStrongReferenceFromWeakReference(Node* value);
3011cb0ef41Sopenharmony_ci  Node* SmiMaxValueConstant();
3021cb0ef41Sopenharmony_ci  Node* SmiShiftBitsConstant();
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci  // Pass {bitfield} = {digit} = nullptr to construct the canoncial 0n BigInt.
3051cb0ef41Sopenharmony_ci  Node* BuildAllocateBigInt(Node* bitfield, Node* digit);
3061cb0ef41Sopenharmony_ci
3071cb0ef41Sopenharmony_ci  void TransitionElementsTo(Node* node, Node* array, ElementsKind from,
3081cb0ef41Sopenharmony_ci                            ElementsKind to);
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci  // This function tries to migrate |value| if its map |value_map| is
3111cb0ef41Sopenharmony_ci  // deprecated. It deopts, if either |value_map| isn't deprecated or migration
3121cb0ef41Sopenharmony_ci  // fails.
3131cb0ef41Sopenharmony_ci  void MigrateInstanceOrDeopt(Node* value, Node* value_map, Node* frame_state,
3141cb0ef41Sopenharmony_ci                              FeedbackSource const& feedback_source,
3151cb0ef41Sopenharmony_ci                              DeoptimizeReason reason);
3161cb0ef41Sopenharmony_ci  // Tries to migrate |value| if its map |value_map| is deprecated, but doesn't
3171cb0ef41Sopenharmony_ci  // deopt on failure.
3181cb0ef41Sopenharmony_ci  void TryMigrateInstance(Node* value, Node* value_map);
3191cb0ef41Sopenharmony_ci
3201cb0ef41Sopenharmony_ci  bool should_maintain_schedule() const {
3211cb0ef41Sopenharmony_ci    return maintain_schedule_ == MaintainSchedule::kMaintain;
3221cb0ef41Sopenharmony_ci  }
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ci  Factory* factory() const { return isolate()->factory(); }
3251cb0ef41Sopenharmony_ci  Isolate* isolate() const { return jsgraph()->isolate(); }
3261cb0ef41Sopenharmony_ci  JSGraph* jsgraph() const { return js_graph_; }
3271cb0ef41Sopenharmony_ci  Graph* graph() const { return js_graph_->graph(); }
3281cb0ef41Sopenharmony_ci  Schedule* schedule() const { return schedule_; }
3291cb0ef41Sopenharmony_ci  Zone* temp_zone() const { return temp_zone_; }
3301cb0ef41Sopenharmony_ci  CommonOperatorBuilder* common() const { return js_graph_->common(); }
3311cb0ef41Sopenharmony_ci  SimplifiedOperatorBuilder* simplified() const {
3321cb0ef41Sopenharmony_ci    return js_graph_->simplified();
3331cb0ef41Sopenharmony_ci  }
3341cb0ef41Sopenharmony_ci  MachineOperatorBuilder* machine() const { return js_graph_->machine(); }
3351cb0ef41Sopenharmony_ci  JSGraphAssembler* gasm() const { return graph_assembler_; }
3361cb0ef41Sopenharmony_ci  JSHeapBroker* broker() const { return broker_; }
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ci  JSGraph* js_graph_;
3391cb0ef41Sopenharmony_ci  Schedule* schedule_;
3401cb0ef41Sopenharmony_ci  Zone* temp_zone_;
3411cb0ef41Sopenharmony_ci  MaintainSchedule maintain_schedule_;
3421cb0ef41Sopenharmony_ci  RegionObservability region_observability_ = RegionObservability::kObservable;
3431cb0ef41Sopenharmony_ci  bool inside_region_ = false;
3441cb0ef41Sopenharmony_ci  SourcePositionTable* source_positions_;
3451cb0ef41Sopenharmony_ci  NodeOriginTable* node_origins_;
3461cb0ef41Sopenharmony_ci  JSHeapBroker* broker_;
3471cb0ef41Sopenharmony_ci  JSGraphAssembler* graph_assembler_;
3481cb0ef41Sopenharmony_ci  Node* frame_state_zapper_;  // For tracking down compiler::Node::New crashes.
3491cb0ef41Sopenharmony_ci};
3501cb0ef41Sopenharmony_ci
3511cb0ef41Sopenharmony_cinamespace {
3521cb0ef41Sopenharmony_ci
3531cb0ef41Sopenharmony_cistruct BlockEffectControlData {
3541cb0ef41Sopenharmony_ci  Node* current_effect = nullptr;       // New effect.
3551cb0ef41Sopenharmony_ci  Node* current_control = nullptr;      // New control.
3561cb0ef41Sopenharmony_ci  Node* current_frame_state = nullptr;  // New frame state.
3571cb0ef41Sopenharmony_ci};
3581cb0ef41Sopenharmony_ci
3591cb0ef41Sopenharmony_ciclass BlockEffectControlMap {
3601cb0ef41Sopenharmony_ci public:
3611cb0ef41Sopenharmony_ci  explicit BlockEffectControlMap(Zone* temp_zone) : map_(temp_zone) {}
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_ci  BlockEffectControlData& For(BasicBlock* from, BasicBlock* to) {
3641cb0ef41Sopenharmony_ci    return map_[std::make_pair(from->id().ToInt(), to->id().ToInt())];
3651cb0ef41Sopenharmony_ci  }
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_ci  const BlockEffectControlData& For(BasicBlock* from, BasicBlock* to) const {
3681cb0ef41Sopenharmony_ci    return map_.at(std::make_pair(from->id().ToInt(), to->id().ToInt()));
3691cb0ef41Sopenharmony_ci  }
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci private:
3721cb0ef41Sopenharmony_ci  using Key = std::pair<int32_t, int32_t>;
3731cb0ef41Sopenharmony_ci  using Map = ZoneMap<Key, BlockEffectControlData>;
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_ci  Map map_;
3761cb0ef41Sopenharmony_ci};
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_ci// Effect phis that need to be updated after the first pass.
3791cb0ef41Sopenharmony_cistruct PendingEffectPhi {
3801cb0ef41Sopenharmony_ci  Node* effect_phi;
3811cb0ef41Sopenharmony_ci  BasicBlock* block;
3821cb0ef41Sopenharmony_ci
3831cb0ef41Sopenharmony_ci  PendingEffectPhi(Node* effect_phi, BasicBlock* block)
3841cb0ef41Sopenharmony_ci      : effect_phi(effect_phi), block(block) {}
3851cb0ef41Sopenharmony_ci};
3861cb0ef41Sopenharmony_ci
3871cb0ef41Sopenharmony_civoid UpdateEffectPhi(Node* node, BasicBlock* block,
3881cb0ef41Sopenharmony_ci                     BlockEffectControlMap* block_effects) {
3891cb0ef41Sopenharmony_ci  // Update all inputs to an effect phi with the effects from the given
3901cb0ef41Sopenharmony_ci  // block->effect map.
3911cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
3921cb0ef41Sopenharmony_ci  DCHECK_EQ(static_cast<size_t>(node->op()->EffectInputCount()),
3931cb0ef41Sopenharmony_ci            block->PredecessorCount());
3941cb0ef41Sopenharmony_ci  for (int i = 0; i < node->op()->EffectInputCount(); i++) {
3951cb0ef41Sopenharmony_ci    Node* input = node->InputAt(i);
3961cb0ef41Sopenharmony_ci    BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
3971cb0ef41Sopenharmony_ci    const BlockEffectControlData& block_effect =
3981cb0ef41Sopenharmony_ci        block_effects->For(predecessor, block);
3991cb0ef41Sopenharmony_ci    Node* effect = block_effect.current_effect;
4001cb0ef41Sopenharmony_ci    if (input != effect) {
4011cb0ef41Sopenharmony_ci      node->ReplaceInput(i, effect);
4021cb0ef41Sopenharmony_ci    }
4031cb0ef41Sopenharmony_ci  }
4041cb0ef41Sopenharmony_ci}
4051cb0ef41Sopenharmony_ci
4061cb0ef41Sopenharmony_civoid UpdateBlockControl(BasicBlock* block,
4071cb0ef41Sopenharmony_ci                        BlockEffectControlMap* block_effects) {
4081cb0ef41Sopenharmony_ci  Node* control = block->NodeAt(0);
4091cb0ef41Sopenharmony_ci  DCHECK(NodeProperties::IsControl(control));
4101cb0ef41Sopenharmony_ci
4111cb0ef41Sopenharmony_ci  // Do not rewire the end node.
4121cb0ef41Sopenharmony_ci  if (control->opcode() == IrOpcode::kEnd) return;
4131cb0ef41Sopenharmony_ci
4141cb0ef41Sopenharmony_ci  // Update all inputs to the given control node with the correct control.
4151cb0ef41Sopenharmony_ci  DCHECK(control->opcode() == IrOpcode::kMerge ||
4161cb0ef41Sopenharmony_ci         static_cast<size_t>(control->op()->ControlInputCount()) ==
4171cb0ef41Sopenharmony_ci             block->PredecessorCount());
4181cb0ef41Sopenharmony_ci  if (static_cast<size_t>(control->op()->ControlInputCount()) !=
4191cb0ef41Sopenharmony_ci      block->PredecessorCount()) {
4201cb0ef41Sopenharmony_ci    return;  // We already re-wired the control inputs of this node.
4211cb0ef41Sopenharmony_ci  }
4221cb0ef41Sopenharmony_ci  for (int i = 0; i < control->op()->ControlInputCount(); i++) {
4231cb0ef41Sopenharmony_ci    Node* input = NodeProperties::GetControlInput(control, i);
4241cb0ef41Sopenharmony_ci    BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
4251cb0ef41Sopenharmony_ci    const BlockEffectControlData& block_effect =
4261cb0ef41Sopenharmony_ci        block_effects->For(predecessor, block);
4271cb0ef41Sopenharmony_ci    if (input != block_effect.current_control) {
4281cb0ef41Sopenharmony_ci      NodeProperties::ReplaceControlInput(control, block_effect.current_control,
4291cb0ef41Sopenharmony_ci                                          i);
4301cb0ef41Sopenharmony_ci    }
4311cb0ef41Sopenharmony_ci  }
4321cb0ef41Sopenharmony_ci}
4331cb0ef41Sopenharmony_ci
4341cb0ef41Sopenharmony_civoid RemoveRenameNode(Node* node) {
4351cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::kFinishRegion == node->opcode() ||
4361cb0ef41Sopenharmony_ci         IrOpcode::kBeginRegion == node->opcode() ||
4371cb0ef41Sopenharmony_ci         IrOpcode::kTypeGuard == node->opcode());
4381cb0ef41Sopenharmony_ci  // Update the value/context uses to the value input of the finish node and
4391cb0ef41Sopenharmony_ci  // the effect uses to the effect input.
4401cb0ef41Sopenharmony_ci  for (Edge edge : node->use_edges()) {
4411cb0ef41Sopenharmony_ci    DCHECK(!edge.from()->IsDead());
4421cb0ef41Sopenharmony_ci    if (NodeProperties::IsEffectEdge(edge)) {
4431cb0ef41Sopenharmony_ci      edge.UpdateTo(NodeProperties::GetEffectInput(node));
4441cb0ef41Sopenharmony_ci    } else {
4451cb0ef41Sopenharmony_ci      DCHECK(!NodeProperties::IsControlEdge(edge));
4461cb0ef41Sopenharmony_ci      DCHECK(!NodeProperties::IsFrameStateEdge(edge));
4471cb0ef41Sopenharmony_ci      edge.UpdateTo(node->InputAt(0));
4481cb0ef41Sopenharmony_ci    }
4491cb0ef41Sopenharmony_ci  }
4501cb0ef41Sopenharmony_ci  node->Kill();
4511cb0ef41Sopenharmony_ci}
4521cb0ef41Sopenharmony_ci
4531cb0ef41Sopenharmony_civoid TryCloneBranch(Node* node, BasicBlock* block, Zone* temp_zone,
4541cb0ef41Sopenharmony_ci                    Graph* graph, CommonOperatorBuilder* common,
4551cb0ef41Sopenharmony_ci                    BlockEffectControlMap* block_effects,
4561cb0ef41Sopenharmony_ci                    SourcePositionTable* source_positions,
4571cb0ef41Sopenharmony_ci                    NodeOriginTable* node_origins) {
4581cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kBranch, node->opcode());
4591cb0ef41Sopenharmony_ci
4601cb0ef41Sopenharmony_ci  // This optimization is a special case of (super)block cloning. It takes an
4611cb0ef41Sopenharmony_ci  // input graph as shown below and clones the Branch node for every predecessor
4621cb0ef41Sopenharmony_ci  // to the Merge, essentially removing the Merge completely. This avoids
4631cb0ef41Sopenharmony_ci  // materializing the bit for the Phi and may offer potential for further
4641cb0ef41Sopenharmony_ci  // branch folding optimizations (i.e. because one or more inputs to the Phi is
4651cb0ef41Sopenharmony_ci  // a constant). Note that there may be more Phi nodes hanging off the Merge,
4661cb0ef41Sopenharmony_ci  // but we can only a certain subset of them currently (actually only Phi and
4671cb0ef41Sopenharmony_ci  // EffectPhi nodes whose uses have either the IfTrue or IfFalse as control
4681cb0ef41Sopenharmony_ci  // input).
4691cb0ef41Sopenharmony_ci
4701cb0ef41Sopenharmony_ci  //   Control1 ... ControlN
4711cb0ef41Sopenharmony_ci  //      ^            ^
4721cb0ef41Sopenharmony_ci  //      |            |   Cond1 ... CondN
4731cb0ef41Sopenharmony_ci  //      +----+  +----+     ^         ^
4741cb0ef41Sopenharmony_ci  //           |  |          |         |
4751cb0ef41Sopenharmony_ci  //           |  |     +----+         |
4761cb0ef41Sopenharmony_ci  //          Merge<--+ | +------------+
4771cb0ef41Sopenharmony_ci  //            ^      \|/
4781cb0ef41Sopenharmony_ci  //            |      Phi
4791cb0ef41Sopenharmony_ci  //            |       |
4801cb0ef41Sopenharmony_ci  //          Branch----+
4811cb0ef41Sopenharmony_ci  //            ^
4821cb0ef41Sopenharmony_ci  //            |
4831cb0ef41Sopenharmony_ci  //      +-----+-----+
4841cb0ef41Sopenharmony_ci  //      |           |
4851cb0ef41Sopenharmony_ci  //    IfTrue     IfFalse
4861cb0ef41Sopenharmony_ci  //      ^           ^
4871cb0ef41Sopenharmony_ci  //      |           |
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ci  // The resulting graph (modulo the Phi and EffectPhi nodes) looks like this:
4901cb0ef41Sopenharmony_ci
4911cb0ef41Sopenharmony_ci  // Control1 Cond1 ... ControlN CondN
4921cb0ef41Sopenharmony_ci  //    ^      ^           ^      ^
4931cb0ef41Sopenharmony_ci  //    \      /           \      /
4941cb0ef41Sopenharmony_ci  //     Branch     ...     Branch
4951cb0ef41Sopenharmony_ci  //       ^                  ^
4961cb0ef41Sopenharmony_ci  //       |                  |
4971cb0ef41Sopenharmony_ci  //   +---+---+          +---+----+
4981cb0ef41Sopenharmony_ci  //   |       |          |        |
4991cb0ef41Sopenharmony_ci  // IfTrue IfFalse ... IfTrue  IfFalse
5001cb0ef41Sopenharmony_ci  //   ^       ^          ^        ^
5011cb0ef41Sopenharmony_ci  //   |       |          |        |
5021cb0ef41Sopenharmony_ci  //   +--+ +-------------+        |
5031cb0ef41Sopenharmony_ci  //      | |  +--------------+ +--+
5041cb0ef41Sopenharmony_ci  //      | |                 | |
5051cb0ef41Sopenharmony_ci  //     Merge               Merge
5061cb0ef41Sopenharmony_ci  //       ^                   ^
5071cb0ef41Sopenharmony_ci  //       |                   |
5081cb0ef41Sopenharmony_ci
5091cb0ef41Sopenharmony_ci  SourcePositionTable::Scope scope(source_positions,
5101cb0ef41Sopenharmony_ci                                   source_positions->GetSourcePosition(node));
5111cb0ef41Sopenharmony_ci  NodeOriginTable::Scope origin_scope(node_origins, "clone branch", node);
5121cb0ef41Sopenharmony_ci  Node* branch = node;
5131cb0ef41Sopenharmony_ci  Node* cond = NodeProperties::GetValueInput(branch, 0);
5141cb0ef41Sopenharmony_ci  if (!cond->OwnedBy(branch) || cond->opcode() != IrOpcode::kPhi) return;
5151cb0ef41Sopenharmony_ci  Node* merge = NodeProperties::GetControlInput(branch);
5161cb0ef41Sopenharmony_ci  if (merge->opcode() != IrOpcode::kMerge ||
5171cb0ef41Sopenharmony_ci      NodeProperties::GetControlInput(cond) != merge) {
5181cb0ef41Sopenharmony_ci    return;
5191cb0ef41Sopenharmony_ci  }
5201cb0ef41Sopenharmony_ci  // Grab the IfTrue/IfFalse projections of the Branch.
5211cb0ef41Sopenharmony_ci  BranchMatcher matcher(branch);
5221cb0ef41Sopenharmony_ci  // Check/collect other Phi/EffectPhi nodes hanging off the Merge.
5231cb0ef41Sopenharmony_ci  NodeVector phis(temp_zone);
5241cb0ef41Sopenharmony_ci  for (Node* const use : merge->uses()) {
5251cb0ef41Sopenharmony_ci    if (use == branch || use == cond) continue;
5261cb0ef41Sopenharmony_ci    // We cannot currently deal with non-Phi/EffectPhi nodes hanging off the
5271cb0ef41Sopenharmony_ci    // Merge. Ideally, we would just clone the nodes (and everything that
5281cb0ef41Sopenharmony_ci    // depends on it to some distant join point), but that requires knowledge
5291cb0ef41Sopenharmony_ci    // about dominance/post-dominance.
5301cb0ef41Sopenharmony_ci    if (!NodeProperties::IsPhi(use)) return;
5311cb0ef41Sopenharmony_ci    for (Edge edge : use->use_edges()) {
5321cb0ef41Sopenharmony_ci      // Right now we can only handle Phi/EffectPhi nodes whose uses are
5331cb0ef41Sopenharmony_ci      // directly control-dependend on either the IfTrue or the IfFalse
5341cb0ef41Sopenharmony_ci      // successor, because we know exactly how to update those uses.
5351cb0ef41Sopenharmony_ci      if (edge.from()->op()->ControlInputCount() != 1) return;
5361cb0ef41Sopenharmony_ci      Node* control = NodeProperties::GetControlInput(edge.from());
5371cb0ef41Sopenharmony_ci      if (NodeProperties::IsPhi(edge.from())) {
5381cb0ef41Sopenharmony_ci        control = NodeProperties::GetControlInput(control, edge.index());
5391cb0ef41Sopenharmony_ci      }
5401cb0ef41Sopenharmony_ci      if (control != matcher.IfTrue() && control != matcher.IfFalse()) return;
5411cb0ef41Sopenharmony_ci    }
5421cb0ef41Sopenharmony_ci    phis.push_back(use);
5431cb0ef41Sopenharmony_ci  }
5441cb0ef41Sopenharmony_ci  BranchHint const hint = BranchHintOf(branch->op());
5451cb0ef41Sopenharmony_ci  int const input_count = merge->op()->ControlInputCount();
5461cb0ef41Sopenharmony_ci  DCHECK_LE(1, input_count);
5471cb0ef41Sopenharmony_ci  Node** const inputs = graph->zone()->NewArray<Node*>(2 * input_count);
5481cb0ef41Sopenharmony_ci  Node** const merge_true_inputs = &inputs[0];
5491cb0ef41Sopenharmony_ci  Node** const merge_false_inputs = &inputs[input_count];
5501cb0ef41Sopenharmony_ci  for (int index = 0; index < input_count; ++index) {
5511cb0ef41Sopenharmony_ci    Node* cond1 = NodeProperties::GetValueInput(cond, index);
5521cb0ef41Sopenharmony_ci    Node* control1 = NodeProperties::GetControlInput(merge, index);
5531cb0ef41Sopenharmony_ci    Node* branch1 = graph->NewNode(common->Branch(hint), cond1, control1);
5541cb0ef41Sopenharmony_ci    merge_true_inputs[index] = graph->NewNode(common->IfTrue(), branch1);
5551cb0ef41Sopenharmony_ci    merge_false_inputs[index] = graph->NewNode(common->IfFalse(), branch1);
5561cb0ef41Sopenharmony_ci  }
5571cb0ef41Sopenharmony_ci  Node* const merge_true = matcher.IfTrue();
5581cb0ef41Sopenharmony_ci  Node* const merge_false = matcher.IfFalse();
5591cb0ef41Sopenharmony_ci  merge_true->TrimInputCount(0);
5601cb0ef41Sopenharmony_ci  merge_false->TrimInputCount(0);
5611cb0ef41Sopenharmony_ci  for (int i = 0; i < input_count; ++i) {
5621cb0ef41Sopenharmony_ci    merge_true->AppendInput(graph->zone(), merge_true_inputs[i]);
5631cb0ef41Sopenharmony_ci    merge_false->AppendInput(graph->zone(), merge_false_inputs[i]);
5641cb0ef41Sopenharmony_ci  }
5651cb0ef41Sopenharmony_ci  DCHECK_EQ(2u, block->SuccessorCount());
5661cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(matcher.IfTrue(), common->Merge(input_count));
5671cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(matcher.IfFalse(), common->Merge(input_count));
5681cb0ef41Sopenharmony_ci  int const true_index =
5691cb0ef41Sopenharmony_ci      block->SuccessorAt(0)->NodeAt(0) == matcher.IfTrue() ? 0 : 1;
5701cb0ef41Sopenharmony_ci  BlockEffectControlData* true_block_data =
5711cb0ef41Sopenharmony_ci      &block_effects->For(block, block->SuccessorAt(true_index));
5721cb0ef41Sopenharmony_ci  BlockEffectControlData* false_block_data =
5731cb0ef41Sopenharmony_ci      &block_effects->For(block, block->SuccessorAt(true_index ^ 1));
5741cb0ef41Sopenharmony_ci  for (Node* const phi : phis) {
5751cb0ef41Sopenharmony_ci    for (int index = 0; index < input_count; ++index) {
5761cb0ef41Sopenharmony_ci      inputs[index] = phi->InputAt(index);
5771cb0ef41Sopenharmony_ci    }
5781cb0ef41Sopenharmony_ci    inputs[input_count] = merge_true;
5791cb0ef41Sopenharmony_ci    Node* phi_true = graph->NewNode(phi->op(), input_count + 1, inputs);
5801cb0ef41Sopenharmony_ci    inputs[input_count] = merge_false;
5811cb0ef41Sopenharmony_ci    Node* phi_false = graph->NewNode(phi->op(), input_count + 1, inputs);
5821cb0ef41Sopenharmony_ci    if (phi->UseCount() == 0) {
5831cb0ef41Sopenharmony_ci      DCHECK_EQ(phi->opcode(), IrOpcode::kEffectPhi);
5841cb0ef41Sopenharmony_ci    } else {
5851cb0ef41Sopenharmony_ci      for (Edge edge : phi->use_edges()) {
5861cb0ef41Sopenharmony_ci        Node* control = NodeProperties::GetControlInput(edge.from());
5871cb0ef41Sopenharmony_ci        if (NodeProperties::IsPhi(edge.from())) {
5881cb0ef41Sopenharmony_ci          control = NodeProperties::GetControlInput(control, edge.index());
5891cb0ef41Sopenharmony_ci        }
5901cb0ef41Sopenharmony_ci        DCHECK(control == matcher.IfTrue() || control == matcher.IfFalse());
5911cb0ef41Sopenharmony_ci        edge.UpdateTo((control == matcher.IfTrue()) ? phi_true : phi_false);
5921cb0ef41Sopenharmony_ci      }
5931cb0ef41Sopenharmony_ci    }
5941cb0ef41Sopenharmony_ci    if (phi->opcode() == IrOpcode::kEffectPhi) {
5951cb0ef41Sopenharmony_ci      true_block_data->current_effect = phi_true;
5961cb0ef41Sopenharmony_ci      false_block_data->current_effect = phi_false;
5971cb0ef41Sopenharmony_ci    }
5981cb0ef41Sopenharmony_ci    phi->Kill();
5991cb0ef41Sopenharmony_ci  }
6001cb0ef41Sopenharmony_ci  // Fix up IfTrue and IfFalse and kill all dead nodes.
6011cb0ef41Sopenharmony_ci  if (branch == block->control_input()) {
6021cb0ef41Sopenharmony_ci    true_block_data->current_control = merge_true;
6031cb0ef41Sopenharmony_ci    false_block_data->current_control = merge_false;
6041cb0ef41Sopenharmony_ci  }
6051cb0ef41Sopenharmony_ci  branch->Kill();
6061cb0ef41Sopenharmony_ci  cond->Kill();
6071cb0ef41Sopenharmony_ci  merge->Kill();
6081cb0ef41Sopenharmony_ci}
6091cb0ef41Sopenharmony_ci
6101cb0ef41Sopenharmony_ci}  // namespace
6111cb0ef41Sopenharmony_ci
6121cb0ef41Sopenharmony_civoid EffectControlLinearizer::Run() {
6131cb0ef41Sopenharmony_ci  BlockEffectControlMap block_effects(temp_zone());
6141cb0ef41Sopenharmony_ci  ZoneVector<PendingEffectPhi> pending_effect_phis(temp_zone());
6151cb0ef41Sopenharmony_ci  ZoneVector<BasicBlock*> pending_block_controls(temp_zone());
6161cb0ef41Sopenharmony_ci  NodeVector inputs_buffer(temp_zone());
6171cb0ef41Sopenharmony_ci
6181cb0ef41Sopenharmony_ci  // TODO(rmcilroy) We should not depend on having rpo_order on schedule, and
6191cb0ef41Sopenharmony_ci  // instead just do our own RPO walk here.
6201cb0ef41Sopenharmony_ci  for (BasicBlock* block : *(schedule()->rpo_order())) {
6211cb0ef41Sopenharmony_ci    if (block != schedule()->start() && block->PredecessorCount() == 0) {
6221cb0ef41Sopenharmony_ci      // Block has been removed from the schedule by a preceeding unreachable
6231cb0ef41Sopenharmony_ci      // node, just skip it.
6241cb0ef41Sopenharmony_ci      continue;
6251cb0ef41Sopenharmony_ci    }
6261cb0ef41Sopenharmony_ci
6271cb0ef41Sopenharmony_ci    gasm()->Reset();
6281cb0ef41Sopenharmony_ci
6291cb0ef41Sopenharmony_ci    BasicBlock::iterator instr = block->begin();
6301cb0ef41Sopenharmony_ci    BasicBlock::iterator end_instr = block->end();
6311cb0ef41Sopenharmony_ci
6321cb0ef41Sopenharmony_ci    // The control node should be the first.
6331cb0ef41Sopenharmony_ci    Node* control = *instr;
6341cb0ef41Sopenharmony_ci    gasm()->AddNode(control);
6351cb0ef41Sopenharmony_ci
6361cb0ef41Sopenharmony_ci    DCHECK(NodeProperties::IsControl(control));
6371cb0ef41Sopenharmony_ci    bool has_incoming_backedge = IrOpcode::kLoop == control->opcode();
6381cb0ef41Sopenharmony_ci    // Update the control inputs.
6391cb0ef41Sopenharmony_ci    if (has_incoming_backedge) {
6401cb0ef41Sopenharmony_ci      // If there are back edges, we need to update later because we have not
6411cb0ef41Sopenharmony_ci      // computed the control yet.
6421cb0ef41Sopenharmony_ci      pending_block_controls.push_back(block);
6431cb0ef41Sopenharmony_ci    } else {
6441cb0ef41Sopenharmony_ci      // If there are no back edges, we can update now.
6451cb0ef41Sopenharmony_ci      UpdateBlockControl(block, &block_effects);
6461cb0ef41Sopenharmony_ci    }
6471cb0ef41Sopenharmony_ci    instr++;
6481cb0ef41Sopenharmony_ci
6491cb0ef41Sopenharmony_ci    // Iterate over the phis and update the effect phis.
6501cb0ef41Sopenharmony_ci    Node* effect_phi = nullptr;
6511cb0ef41Sopenharmony_ci    Node* terminate = nullptr;
6521cb0ef41Sopenharmony_ci    for (; instr != end_instr; instr++) {
6531cb0ef41Sopenharmony_ci      Node* node = *instr;
6541cb0ef41Sopenharmony_ci      // Only go through the phis and effect phis.
6551cb0ef41Sopenharmony_ci      if (node->opcode() == IrOpcode::kEffectPhi) {
6561cb0ef41Sopenharmony_ci        // There should be at most one effect phi in a block.
6571cb0ef41Sopenharmony_ci        DCHECK_NULL(effect_phi);
6581cb0ef41Sopenharmony_ci        // IfException blocks should not have effect phis.
6591cb0ef41Sopenharmony_ci        DCHECK_NE(IrOpcode::kIfException, control->opcode());
6601cb0ef41Sopenharmony_ci        effect_phi = node;
6611cb0ef41Sopenharmony_ci      } else if (node->opcode() == IrOpcode::kPhi) {
6621cb0ef41Sopenharmony_ci        // Just skip phis.
6631cb0ef41Sopenharmony_ci      } else if (node->opcode() == IrOpcode::kTerminate) {
6641cb0ef41Sopenharmony_ci        DCHECK_NULL(terminate);
6651cb0ef41Sopenharmony_ci        terminate = node;
6661cb0ef41Sopenharmony_ci      } else {
6671cb0ef41Sopenharmony_ci        break;
6681cb0ef41Sopenharmony_ci      }
6691cb0ef41Sopenharmony_ci      gasm()->AddNode(node);
6701cb0ef41Sopenharmony_ci    }
6711cb0ef41Sopenharmony_ci
6721cb0ef41Sopenharmony_ci    if (effect_phi) {
6731cb0ef41Sopenharmony_ci      // Make sure we update the inputs to the incoming blocks' effects.
6741cb0ef41Sopenharmony_ci      if (has_incoming_backedge) {
6751cb0ef41Sopenharmony_ci        // In case of loops, we do not update the effect phi immediately
6761cb0ef41Sopenharmony_ci        // because the back predecessor has not been handled yet. We just
6771cb0ef41Sopenharmony_ci        // record the effect phi for later processing.
6781cb0ef41Sopenharmony_ci        pending_effect_phis.push_back(PendingEffectPhi(effect_phi, block));
6791cb0ef41Sopenharmony_ci      } else {
6801cb0ef41Sopenharmony_ci        UpdateEffectPhi(effect_phi, block, &block_effects);
6811cb0ef41Sopenharmony_ci      }
6821cb0ef41Sopenharmony_ci    }
6831cb0ef41Sopenharmony_ci
6841cb0ef41Sopenharmony_ci    Node* effect = effect_phi;
6851cb0ef41Sopenharmony_ci    if (effect == nullptr) {
6861cb0ef41Sopenharmony_ci      // There was no effect phi.
6871cb0ef41Sopenharmony_ci      if (block == schedule()->start()) {
6881cb0ef41Sopenharmony_ci        // Start block => effect is start.
6891cb0ef41Sopenharmony_ci        DCHECK_EQ(graph()->start(), control);
6901cb0ef41Sopenharmony_ci        effect = graph()->start();
6911cb0ef41Sopenharmony_ci      } else if (control->opcode() == IrOpcode::kEnd) {
6921cb0ef41Sopenharmony_ci        // End block is just a dummy, no effect needed.
6931cb0ef41Sopenharmony_ci        DCHECK_EQ(BasicBlock::kNone, block->control());
6941cb0ef41Sopenharmony_ci        DCHECK_EQ(1u, block->size());
6951cb0ef41Sopenharmony_ci        effect = nullptr;
6961cb0ef41Sopenharmony_ci      } else {
6971cb0ef41Sopenharmony_ci        // If all the predecessors have the same effect, we can use it as our
6981cb0ef41Sopenharmony_ci        // current effect.
6991cb0ef41Sopenharmony_ci        for (size_t i = 0; i < block->PredecessorCount(); ++i) {
7001cb0ef41Sopenharmony_ci          const BlockEffectControlData& data =
7011cb0ef41Sopenharmony_ci              block_effects.For(block->PredecessorAt(i), block);
7021cb0ef41Sopenharmony_ci          if (!effect) effect = data.current_effect;
7031cb0ef41Sopenharmony_ci          if (data.current_effect != effect) {
7041cb0ef41Sopenharmony_ci            effect = nullptr;
7051cb0ef41Sopenharmony_ci            break;
7061cb0ef41Sopenharmony_ci          }
7071cb0ef41Sopenharmony_ci        }
7081cb0ef41Sopenharmony_ci        if (effect == nullptr) {
7091cb0ef41Sopenharmony_ci          DCHECK_NE(IrOpcode::kIfException, control->opcode());
7101cb0ef41Sopenharmony_ci          // The input blocks do not have the same effect. We have
7111cb0ef41Sopenharmony_ci          // to create an effect phi node.
7121cb0ef41Sopenharmony_ci          inputs_buffer.clear();
7131cb0ef41Sopenharmony_ci          inputs_buffer.resize(block->PredecessorCount(), jsgraph()->Dead());
7141cb0ef41Sopenharmony_ci          inputs_buffer.push_back(control);
7151cb0ef41Sopenharmony_ci          effect = graph()->NewNode(
7161cb0ef41Sopenharmony_ci              common()->EffectPhi(static_cast<int>(block->PredecessorCount())),
7171cb0ef41Sopenharmony_ci              static_cast<int>(inputs_buffer.size()), &(inputs_buffer.front()));
7181cb0ef41Sopenharmony_ci          gasm()->AddNode(effect);
7191cb0ef41Sopenharmony_ci          // For loops, we update the effect phi node later to break cycles.
7201cb0ef41Sopenharmony_ci          if (control->opcode() == IrOpcode::kLoop) {
7211cb0ef41Sopenharmony_ci            pending_effect_phis.push_back(PendingEffectPhi(effect, block));
7221cb0ef41Sopenharmony_ci          } else {
7231cb0ef41Sopenharmony_ci            UpdateEffectPhi(effect, block, &block_effects);
7241cb0ef41Sopenharmony_ci          }
7251cb0ef41Sopenharmony_ci        } else if (control->opcode() == IrOpcode::kIfException) {
7261cb0ef41Sopenharmony_ci          // The IfException is connected into the effect chain, so we need
7271cb0ef41Sopenharmony_ci          // to update the effect here.
7281cb0ef41Sopenharmony_ci          NodeProperties::ReplaceEffectInput(control, effect);
7291cb0ef41Sopenharmony_ci          effect = control;
7301cb0ef41Sopenharmony_ci        }
7311cb0ef41Sopenharmony_ci      }
7321cb0ef41Sopenharmony_ci    }
7331cb0ef41Sopenharmony_ci
7341cb0ef41Sopenharmony_ci    // Fixup the Terminate node.
7351cb0ef41Sopenharmony_ci    if (terminate != nullptr) {
7361cb0ef41Sopenharmony_ci      NodeProperties::ReplaceEffectInput(terminate, effect);
7371cb0ef41Sopenharmony_ci    }
7381cb0ef41Sopenharmony_ci
7391cb0ef41Sopenharmony_ci    // The frame state at block entry is determined by the frame states leaving
7401cb0ef41Sopenharmony_ci    // all predecessors. In case there is no frame state dominating this block,
7411cb0ef41Sopenharmony_ci    // we can rely on a checkpoint being present before the next deoptimization.
7421cb0ef41Sopenharmony_ci    Node* frame_state = nullptr;
7431cb0ef41Sopenharmony_ci    if (block != schedule()->start()) {
7441cb0ef41Sopenharmony_ci      // If all the predecessors have the same effect, we can use it
7451cb0ef41Sopenharmony_ci      // as our current effect.
7461cb0ef41Sopenharmony_ci      frame_state =
7471cb0ef41Sopenharmony_ci          block_effects.For(block->PredecessorAt(0), block).current_frame_state;
7481cb0ef41Sopenharmony_ci      for (size_t i = 1; i < block->PredecessorCount(); i++) {
7491cb0ef41Sopenharmony_ci        if (block_effects.For(block->PredecessorAt(i), block)
7501cb0ef41Sopenharmony_ci                .current_frame_state != frame_state) {
7511cb0ef41Sopenharmony_ci          frame_state = nullptr;
7521cb0ef41Sopenharmony_ci          frame_state_zapper_ = graph()->end();
7531cb0ef41Sopenharmony_ci          break;
7541cb0ef41Sopenharmony_ci        }
7551cb0ef41Sopenharmony_ci      }
7561cb0ef41Sopenharmony_ci    }
7571cb0ef41Sopenharmony_ci
7581cb0ef41Sopenharmony_ci    gasm()->InitializeEffectControl(effect, control);
7591cb0ef41Sopenharmony_ci
7601cb0ef41Sopenharmony_ci    // Process the ordinary instructions.
7611cb0ef41Sopenharmony_ci    for (; instr != end_instr; instr++) {
7621cb0ef41Sopenharmony_ci      Node* node = *instr;
7631cb0ef41Sopenharmony_ci      ProcessNode(node, &frame_state);
7641cb0ef41Sopenharmony_ci    }
7651cb0ef41Sopenharmony_ci
7661cb0ef41Sopenharmony_ci    switch (block->control()) {
7671cb0ef41Sopenharmony_ci      case BasicBlock::kGoto:
7681cb0ef41Sopenharmony_ci      case BasicBlock::kNone:
7691cb0ef41Sopenharmony_ci        break;
7701cb0ef41Sopenharmony_ci      case BasicBlock::kCall:
7711cb0ef41Sopenharmony_ci      case BasicBlock::kTailCall:
7721cb0ef41Sopenharmony_ci      case BasicBlock::kSwitch:
7731cb0ef41Sopenharmony_ci      case BasicBlock::kReturn:
7741cb0ef41Sopenharmony_ci      case BasicBlock::kDeoptimize:
7751cb0ef41Sopenharmony_ci      case BasicBlock::kThrow:
7761cb0ef41Sopenharmony_ci      case BasicBlock::kBranch:
7771cb0ef41Sopenharmony_ci        UpdateEffectControlForNode(block->control_input());
7781cb0ef41Sopenharmony_ci        gasm()->UpdateEffectControlWith(block->control_input());
7791cb0ef41Sopenharmony_ci        break;
7801cb0ef41Sopenharmony_ci    }
7811cb0ef41Sopenharmony_ci
7821cb0ef41Sopenharmony_ci    if (!should_maintain_schedule() &&
7831cb0ef41Sopenharmony_ci        block->control() == BasicBlock::kBranch) {
7841cb0ef41Sopenharmony_ci      TryCloneBranch(block->control_input(), block, temp_zone(), graph(),
7851cb0ef41Sopenharmony_ci                     common(), &block_effects, source_positions_,
7861cb0ef41Sopenharmony_ci                     node_origins_);
7871cb0ef41Sopenharmony_ci    }
7881cb0ef41Sopenharmony_ci
7891cb0ef41Sopenharmony_ci    // Store the effect, control and frame state for later use.
7901cb0ef41Sopenharmony_ci    for (BasicBlock* successor : block->successors()) {
7911cb0ef41Sopenharmony_ci      BlockEffectControlData* data = &block_effects.For(block, successor);
7921cb0ef41Sopenharmony_ci      if (data->current_effect == nullptr) {
7931cb0ef41Sopenharmony_ci        data->current_effect = gasm()->effect();
7941cb0ef41Sopenharmony_ci      }
7951cb0ef41Sopenharmony_ci      if (data->current_control == nullptr) {
7961cb0ef41Sopenharmony_ci        data->current_control = gasm()->control();
7971cb0ef41Sopenharmony_ci      }
7981cb0ef41Sopenharmony_ci      data->current_frame_state = frame_state;
7991cb0ef41Sopenharmony_ci    }
8001cb0ef41Sopenharmony_ci  }
8011cb0ef41Sopenharmony_ci
8021cb0ef41Sopenharmony_ci  for (BasicBlock* pending_block_control : pending_block_controls) {
8031cb0ef41Sopenharmony_ci    UpdateBlockControl(pending_block_control, &block_effects);
8041cb0ef41Sopenharmony_ci  }
8051cb0ef41Sopenharmony_ci  // Update the incoming edges of the effect phis that could not be processed
8061cb0ef41Sopenharmony_ci  // during the first pass (because they could have incoming back edges).
8071cb0ef41Sopenharmony_ci  for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) {
8081cb0ef41Sopenharmony_ci    UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block,
8091cb0ef41Sopenharmony_ci                    &block_effects);
8101cb0ef41Sopenharmony_ci  }
8111cb0ef41Sopenharmony_ci
8121cb0ef41Sopenharmony_ci  schedule_->rpo_order()->clear();
8131cb0ef41Sopenharmony_ci}
8141cb0ef41Sopenharmony_ci
8151cb0ef41Sopenharmony_civoid EffectControlLinearizer::UpdateEffectControlForNode(Node* node) {
8161cb0ef41Sopenharmony_ci  // If the node takes an effect, replace with the current one.
8171cb0ef41Sopenharmony_ci  if (node->op()->EffectInputCount() > 0) {
8181cb0ef41Sopenharmony_ci    DCHECK_EQ(1, node->op()->EffectInputCount());
8191cb0ef41Sopenharmony_ci    NodeProperties::ReplaceEffectInput(node, gasm()->effect());
8201cb0ef41Sopenharmony_ci  } else {
8211cb0ef41Sopenharmony_ci    // New effect chain is only started with a Start or ValueEffect node.
8221cb0ef41Sopenharmony_ci    DCHECK(node->op()->EffectOutputCount() == 0 ||
8231cb0ef41Sopenharmony_ci           node->opcode() == IrOpcode::kStart);
8241cb0ef41Sopenharmony_ci  }
8251cb0ef41Sopenharmony_ci
8261cb0ef41Sopenharmony_ci  // Rewire control inputs.
8271cb0ef41Sopenharmony_ci  for (int i = 0; i < node->op()->ControlInputCount(); i++) {
8281cb0ef41Sopenharmony_ci    NodeProperties::ReplaceControlInput(node, gasm()->control(), i);
8291cb0ef41Sopenharmony_ci  }
8301cb0ef41Sopenharmony_ci}
8311cb0ef41Sopenharmony_ci
8321cb0ef41Sopenharmony_civoid EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state) {
8331cb0ef41Sopenharmony_ci  SourcePositionTable::Scope scope(source_positions_,
8341cb0ef41Sopenharmony_ci                                   source_positions_->GetSourcePosition(node));
8351cb0ef41Sopenharmony_ci  NodeOriginTable::Scope origin_scope(node_origins_, "process node", node);
8361cb0ef41Sopenharmony_ci
8371cb0ef41Sopenharmony_ci  // If basic block is unreachable after this point, update the node's effect
8381cb0ef41Sopenharmony_ci  // and control inputs to mark it as dead, but don't process further.
8391cb0ef41Sopenharmony_ci  if (gasm()->effect() == jsgraph()->Dead()) {
8401cb0ef41Sopenharmony_ci    UpdateEffectControlForNode(node);
8411cb0ef41Sopenharmony_ci    return;
8421cb0ef41Sopenharmony_ci  }
8431cb0ef41Sopenharmony_ci
8441cb0ef41Sopenharmony_ci  // If the node needs to be wired into the effect/control chain, do this
8451cb0ef41Sopenharmony_ci  // here. Pass current frame state for lowering to eager deoptimization.
8461cb0ef41Sopenharmony_ci  if (TryWireInStateEffect(node, *frame_state)) {
8471cb0ef41Sopenharmony_ci    return;
8481cb0ef41Sopenharmony_ci  }
8491cb0ef41Sopenharmony_ci
8501cb0ef41Sopenharmony_ci  // If the node has a visible effect, then there must be a checkpoint in the
8511cb0ef41Sopenharmony_ci  // effect chain before we are allowed to place another eager deoptimization
8521cb0ef41Sopenharmony_ci  // point. We zap the frame state to ensure this invariant is maintained.
8531cb0ef41Sopenharmony_ci  if (region_observability_ == RegionObservability::kObservable &&
8541cb0ef41Sopenharmony_ci      !node->op()->HasProperty(Operator::kNoWrite)) {
8551cb0ef41Sopenharmony_ci    *frame_state = nullptr;
8561cb0ef41Sopenharmony_ci    frame_state_zapper_ = node;
8571cb0ef41Sopenharmony_ci  }
8581cb0ef41Sopenharmony_ci
8591cb0ef41Sopenharmony_ci  // Remove the end markers of 'atomic' allocation region because the
8601cb0ef41Sopenharmony_ci  // region should be wired-in now.
8611cb0ef41Sopenharmony_ci  if (node->opcode() == IrOpcode::kFinishRegion) {
8621cb0ef41Sopenharmony_ci    // Reset the current region observability.
8631cb0ef41Sopenharmony_ci    region_observability_ = RegionObservability::kObservable;
8641cb0ef41Sopenharmony_ci    inside_region_ = false;
8651cb0ef41Sopenharmony_ci    // Update the value uses to the value input of the finish node and
8661cb0ef41Sopenharmony_ci    // the effect uses to the effect input.
8671cb0ef41Sopenharmony_ci    return RemoveRenameNode(node);
8681cb0ef41Sopenharmony_ci  }
8691cb0ef41Sopenharmony_ci  if (node->opcode() == IrOpcode::kBeginRegion) {
8701cb0ef41Sopenharmony_ci    // Determine the observability for this region and use that for all
8711cb0ef41Sopenharmony_ci    // nodes inside the region (i.e. ignore the absence of kNoWrite on
8721cb0ef41Sopenharmony_ci    // StoreField and other operators).
8731cb0ef41Sopenharmony_ci    DCHECK_NE(RegionObservability::kNotObservable, region_observability_);
8741cb0ef41Sopenharmony_ci    region_observability_ = RegionObservabilityOf(node->op());
8751cb0ef41Sopenharmony_ci    inside_region_ = true;
8761cb0ef41Sopenharmony_ci    // Update the value uses to the value input of the finish node and
8771cb0ef41Sopenharmony_ci    // the effect uses to the effect input.
8781cb0ef41Sopenharmony_ci    return RemoveRenameNode(node);
8791cb0ef41Sopenharmony_ci  }
8801cb0ef41Sopenharmony_ci  if (node->opcode() == IrOpcode::kTypeGuard) {
8811cb0ef41Sopenharmony_ci    return RemoveRenameNode(node);
8821cb0ef41Sopenharmony_ci  }
8831cb0ef41Sopenharmony_ci
8841cb0ef41Sopenharmony_ci  // Special treatment for checkpoint nodes.
8851cb0ef41Sopenharmony_ci  if (node->opcode() == IrOpcode::kCheckpoint) {
8861cb0ef41Sopenharmony_ci    // Unlink the check point; effect uses will be updated to the incoming
8871cb0ef41Sopenharmony_ci    // effect that is passed. The frame state is preserved for lowering.
8881cb0ef41Sopenharmony_ci    DCHECK_EQ(RegionObservability::kObservable, region_observability_);
8891cb0ef41Sopenharmony_ci    *frame_state = NodeProperties::GetFrameStateInput(node);
8901cb0ef41Sopenharmony_ci    return;
8911cb0ef41Sopenharmony_ci  }
8921cb0ef41Sopenharmony_ci
8931cb0ef41Sopenharmony_ci  if (node->opcode() == IrOpcode::kStoreField) {
8941cb0ef41Sopenharmony_ci    // Mark stores outside a region as non-initializing and non-transitioning.
8951cb0ef41Sopenharmony_ci    if (!inside_region_) {
8961cb0ef41Sopenharmony_ci      const FieldAccess access = FieldAccessOf(node->op());
8971cb0ef41Sopenharmony_ci      NodeProperties::ChangeOp(node, simplified()->StoreField(access, false));
8981cb0ef41Sopenharmony_ci    }
8991cb0ef41Sopenharmony_ci  }
9001cb0ef41Sopenharmony_ci
9011cb0ef41Sopenharmony_ci  // The IfSuccess nodes should always start a basic block (and basic block
9021cb0ef41Sopenharmony_ci  // start nodes are not handled in the ProcessNode method).
9031cb0ef41Sopenharmony_ci  DCHECK_NE(IrOpcode::kIfSuccess, node->opcode());
9041cb0ef41Sopenharmony_ci
9051cb0ef41Sopenharmony_ci  UpdateEffectControlForNode(node);
9061cb0ef41Sopenharmony_ci
9071cb0ef41Sopenharmony_ci  gasm()->AddNode(node);
9081cb0ef41Sopenharmony_ci
9091cb0ef41Sopenharmony_ci  if (node->opcode() == IrOpcode::kUnreachable) {
9101cb0ef41Sopenharmony_ci    // Break the effect chain on {Unreachable} and reconnect to the graph end.
9111cb0ef41Sopenharmony_ci    // Mark the following code for deletion by connecting to the {Dead} node.
9121cb0ef41Sopenharmony_ci    gasm()->ConnectUnreachableToEnd();
9131cb0ef41Sopenharmony_ci  }
9141cb0ef41Sopenharmony_ci}
9151cb0ef41Sopenharmony_ci
9161cb0ef41Sopenharmony_cibool EffectControlLinearizer::TryWireInStateEffect(Node* node,
9171cb0ef41Sopenharmony_ci                                                   Node* frame_state) {
9181cb0ef41Sopenharmony_ci  Node* result = nullptr;
9191cb0ef41Sopenharmony_ci  switch (node->opcode()) {
9201cb0ef41Sopenharmony_ci    case IrOpcode::kChangeBitToTagged:
9211cb0ef41Sopenharmony_ci      result = LowerChangeBitToTagged(node);
9221cb0ef41Sopenharmony_ci      break;
9231cb0ef41Sopenharmony_ci    case IrOpcode::kChangeInt31ToTaggedSigned:
9241cb0ef41Sopenharmony_ci      result = LowerChangeInt31ToTaggedSigned(node);
9251cb0ef41Sopenharmony_ci      break;
9261cb0ef41Sopenharmony_ci    case IrOpcode::kChangeInt32ToTagged:
9271cb0ef41Sopenharmony_ci      result = LowerChangeInt32ToTagged(node);
9281cb0ef41Sopenharmony_ci      break;
9291cb0ef41Sopenharmony_ci    case IrOpcode::kChangeInt64ToTagged:
9301cb0ef41Sopenharmony_ci      result = LowerChangeInt64ToTagged(node);
9311cb0ef41Sopenharmony_ci      break;
9321cb0ef41Sopenharmony_ci    case IrOpcode::kChangeUint32ToTagged:
9331cb0ef41Sopenharmony_ci      result = LowerChangeUint32ToTagged(node);
9341cb0ef41Sopenharmony_ci      break;
9351cb0ef41Sopenharmony_ci    case IrOpcode::kChangeUint64ToTagged:
9361cb0ef41Sopenharmony_ci      result = LowerChangeUint64ToTagged(node);
9371cb0ef41Sopenharmony_ci      break;
9381cb0ef41Sopenharmony_ci    case IrOpcode::kChangeFloat64ToTagged:
9391cb0ef41Sopenharmony_ci      result = LowerChangeFloat64ToTagged(node);
9401cb0ef41Sopenharmony_ci      break;
9411cb0ef41Sopenharmony_ci    case IrOpcode::kChangeFloat64ToTaggedPointer:
9421cb0ef41Sopenharmony_ci      result = LowerChangeFloat64ToTaggedPointer(node);
9431cb0ef41Sopenharmony_ci      break;
9441cb0ef41Sopenharmony_ci    case IrOpcode::kChangeTaggedSignedToInt32:
9451cb0ef41Sopenharmony_ci      result = LowerChangeTaggedSignedToInt32(node);
9461cb0ef41Sopenharmony_ci      break;
9471cb0ef41Sopenharmony_ci    case IrOpcode::kChangeTaggedSignedToInt64:
9481cb0ef41Sopenharmony_ci      result = LowerChangeTaggedSignedToInt64(node);
9491cb0ef41Sopenharmony_ci      break;
9501cb0ef41Sopenharmony_ci    case IrOpcode::kChangeTaggedToBit:
9511cb0ef41Sopenharmony_ci      result = LowerChangeTaggedToBit(node);
9521cb0ef41Sopenharmony_ci      break;
9531cb0ef41Sopenharmony_ci    case IrOpcode::kChangeTaggedToInt32:
9541cb0ef41Sopenharmony_ci      result = LowerChangeTaggedToInt32(node);
9551cb0ef41Sopenharmony_ci      break;
9561cb0ef41Sopenharmony_ci    case IrOpcode::kChangeTaggedToUint32:
9571cb0ef41Sopenharmony_ci      result = LowerChangeTaggedToUint32(node);
9581cb0ef41Sopenharmony_ci      break;
9591cb0ef41Sopenharmony_ci    case IrOpcode::kChangeTaggedToInt64:
9601cb0ef41Sopenharmony_ci      result = LowerChangeTaggedToInt64(node);
9611cb0ef41Sopenharmony_ci      break;
9621cb0ef41Sopenharmony_ci    case IrOpcode::kChangeTaggedToFloat64:
9631cb0ef41Sopenharmony_ci      result = LowerChangeTaggedToFloat64(node);
9641cb0ef41Sopenharmony_ci      break;
9651cb0ef41Sopenharmony_ci    case IrOpcode::kChangeTaggedToTaggedSigned:
9661cb0ef41Sopenharmony_ci      result = LowerChangeTaggedToTaggedSigned(node);
9671cb0ef41Sopenharmony_ci      break;
9681cb0ef41Sopenharmony_ci    case IrOpcode::kTruncateTaggedToBit:
9691cb0ef41Sopenharmony_ci      result = LowerTruncateTaggedToBit(node);
9701cb0ef41Sopenharmony_ci      break;
9711cb0ef41Sopenharmony_ci    case IrOpcode::kTruncateTaggedPointerToBit:
9721cb0ef41Sopenharmony_ci      result = LowerTruncateTaggedPointerToBit(node);
9731cb0ef41Sopenharmony_ci      break;
9741cb0ef41Sopenharmony_ci    case IrOpcode::kTruncateTaggedToFloat64:
9751cb0ef41Sopenharmony_ci      result = LowerTruncateTaggedToFloat64(node);
9761cb0ef41Sopenharmony_ci      break;
9771cb0ef41Sopenharmony_ci    case IrOpcode::kCheckClosure:
9781cb0ef41Sopenharmony_ci      result = LowerCheckClosure(node, frame_state);
9791cb0ef41Sopenharmony_ci      break;
9801cb0ef41Sopenharmony_ci    case IrOpcode::kCheckMaps:
9811cb0ef41Sopenharmony_ci      LowerCheckMaps(node, frame_state);
9821cb0ef41Sopenharmony_ci      break;
9831cb0ef41Sopenharmony_ci    case IrOpcode::kCompareMaps:
9841cb0ef41Sopenharmony_ci      result = LowerCompareMaps(node);
9851cb0ef41Sopenharmony_ci      break;
9861cb0ef41Sopenharmony_ci    case IrOpcode::kCheckNumber:
9871cb0ef41Sopenharmony_ci      result = LowerCheckNumber(node, frame_state);
9881cb0ef41Sopenharmony_ci      break;
9891cb0ef41Sopenharmony_ci    case IrOpcode::kCheckReceiver:
9901cb0ef41Sopenharmony_ci      result = LowerCheckReceiver(node, frame_state);
9911cb0ef41Sopenharmony_ci      break;
9921cb0ef41Sopenharmony_ci    case IrOpcode::kCheckReceiverOrNullOrUndefined:
9931cb0ef41Sopenharmony_ci      result = LowerCheckReceiverOrNullOrUndefined(node, frame_state);
9941cb0ef41Sopenharmony_ci      break;
9951cb0ef41Sopenharmony_ci    case IrOpcode::kCheckSymbol:
9961cb0ef41Sopenharmony_ci      result = LowerCheckSymbol(node, frame_state);
9971cb0ef41Sopenharmony_ci      break;
9981cb0ef41Sopenharmony_ci    case IrOpcode::kCheckString:
9991cb0ef41Sopenharmony_ci      result = LowerCheckString(node, frame_state);
10001cb0ef41Sopenharmony_ci      break;
10011cb0ef41Sopenharmony_ci    case IrOpcode::kCheckBigInt:
10021cb0ef41Sopenharmony_ci      result = LowerCheckBigInt(node, frame_state);
10031cb0ef41Sopenharmony_ci      break;
10041cb0ef41Sopenharmony_ci    case IrOpcode::kCheckInternalizedString:
10051cb0ef41Sopenharmony_ci      result = LowerCheckInternalizedString(node, frame_state);
10061cb0ef41Sopenharmony_ci      break;
10071cb0ef41Sopenharmony_ci    case IrOpcode::kCheckIf:
10081cb0ef41Sopenharmony_ci      LowerCheckIf(node, frame_state);
10091cb0ef41Sopenharmony_ci      break;
10101cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedInt32Add:
10111cb0ef41Sopenharmony_ci      result = LowerCheckedInt32Add(node, frame_state);
10121cb0ef41Sopenharmony_ci      break;
10131cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedInt32Sub:
10141cb0ef41Sopenharmony_ci      result = LowerCheckedInt32Sub(node, frame_state);
10151cb0ef41Sopenharmony_ci      break;
10161cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedInt32Div:
10171cb0ef41Sopenharmony_ci      result = LowerCheckedInt32Div(node, frame_state);
10181cb0ef41Sopenharmony_ci      break;
10191cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedInt32Mod:
10201cb0ef41Sopenharmony_ci      result = LowerCheckedInt32Mod(node, frame_state);
10211cb0ef41Sopenharmony_ci      break;
10221cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedUint32Div:
10231cb0ef41Sopenharmony_ci      result = LowerCheckedUint32Div(node, frame_state);
10241cb0ef41Sopenharmony_ci      break;
10251cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedUint32Mod:
10261cb0ef41Sopenharmony_ci      result = LowerCheckedUint32Mod(node, frame_state);
10271cb0ef41Sopenharmony_ci      break;
10281cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedInt32Mul:
10291cb0ef41Sopenharmony_ci      result = LowerCheckedInt32Mul(node, frame_state);
10301cb0ef41Sopenharmony_ci      break;
10311cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedInt32ToTaggedSigned:
10321cb0ef41Sopenharmony_ci      result = LowerCheckedInt32ToTaggedSigned(node, frame_state);
10331cb0ef41Sopenharmony_ci      break;
10341cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedInt64ToInt32:
10351cb0ef41Sopenharmony_ci      result = LowerCheckedInt64ToInt32(node, frame_state);
10361cb0ef41Sopenharmony_ci      break;
10371cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedInt64ToTaggedSigned:
10381cb0ef41Sopenharmony_ci      result = LowerCheckedInt64ToTaggedSigned(node, frame_state);
10391cb0ef41Sopenharmony_ci      break;
10401cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedUint32Bounds:
10411cb0ef41Sopenharmony_ci      result = LowerCheckedUint32Bounds(node, frame_state);
10421cb0ef41Sopenharmony_ci      break;
10431cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedUint32ToInt32:
10441cb0ef41Sopenharmony_ci      result = LowerCheckedUint32ToInt32(node, frame_state);
10451cb0ef41Sopenharmony_ci      break;
10461cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedUint32ToTaggedSigned:
10471cb0ef41Sopenharmony_ci      result = LowerCheckedUint32ToTaggedSigned(node, frame_state);
10481cb0ef41Sopenharmony_ci      break;
10491cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedUint64Bounds:
10501cb0ef41Sopenharmony_ci      result = LowerCheckedUint64Bounds(node, frame_state);
10511cb0ef41Sopenharmony_ci      break;
10521cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedUint64ToInt32:
10531cb0ef41Sopenharmony_ci      result = LowerCheckedUint64ToInt32(node, frame_state);
10541cb0ef41Sopenharmony_ci      break;
10551cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedUint64ToTaggedSigned:
10561cb0ef41Sopenharmony_ci      result = LowerCheckedUint64ToTaggedSigned(node, frame_state);
10571cb0ef41Sopenharmony_ci      break;
10581cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedFloat64ToInt32:
10591cb0ef41Sopenharmony_ci      result = LowerCheckedFloat64ToInt32(node, frame_state);
10601cb0ef41Sopenharmony_ci      break;
10611cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedFloat64ToInt64:
10621cb0ef41Sopenharmony_ci      result = LowerCheckedFloat64ToInt64(node, frame_state);
10631cb0ef41Sopenharmony_ci      break;
10641cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedTaggedSignedToInt32:
10651cb0ef41Sopenharmony_ci      if (frame_state == nullptr) {
10661cb0ef41Sopenharmony_ci        FATAL("No frame state (zapped by #%d: %s)", frame_state_zapper_->id(),
10671cb0ef41Sopenharmony_ci              frame_state_zapper_->op()->mnemonic());
10681cb0ef41Sopenharmony_ci      }
10691cb0ef41Sopenharmony_ci      result = LowerCheckedTaggedSignedToInt32(node, frame_state);
10701cb0ef41Sopenharmony_ci      break;
10711cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedTaggedToArrayIndex:
10721cb0ef41Sopenharmony_ci      result = LowerCheckedTaggedToArrayIndex(node, frame_state);
10731cb0ef41Sopenharmony_ci      break;
10741cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedTaggedToInt32:
10751cb0ef41Sopenharmony_ci      result = LowerCheckedTaggedToInt32(node, frame_state);
10761cb0ef41Sopenharmony_ci      break;
10771cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedTaggedToInt64:
10781cb0ef41Sopenharmony_ci      result = LowerCheckedTaggedToInt64(node, frame_state);
10791cb0ef41Sopenharmony_ci      break;
10801cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedTaggedToFloat64:
10811cb0ef41Sopenharmony_ci      result = LowerCheckedTaggedToFloat64(node, frame_state);
10821cb0ef41Sopenharmony_ci      break;
10831cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedTaggedToTaggedSigned:
10841cb0ef41Sopenharmony_ci      result = LowerCheckedTaggedToTaggedSigned(node, frame_state);
10851cb0ef41Sopenharmony_ci      break;
10861cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedTaggedToTaggedPointer:
10871cb0ef41Sopenharmony_ci      result = LowerCheckedTaggedToTaggedPointer(node, frame_state);
10881cb0ef41Sopenharmony_ci      break;
10891cb0ef41Sopenharmony_ci    case IrOpcode::kChangeInt64ToBigInt:
10901cb0ef41Sopenharmony_ci      result = LowerChangeInt64ToBigInt(node);
10911cb0ef41Sopenharmony_ci      break;
10921cb0ef41Sopenharmony_ci    case IrOpcode::kChangeUint64ToBigInt:
10931cb0ef41Sopenharmony_ci      result = LowerChangeUint64ToBigInt(node);
10941cb0ef41Sopenharmony_ci      break;
10951cb0ef41Sopenharmony_ci    case IrOpcode::kTruncateBigIntToWord64:
10961cb0ef41Sopenharmony_ci      result = LowerTruncateBigIntToWord64(node);
10971cb0ef41Sopenharmony_ci      break;
10981cb0ef41Sopenharmony_ci    case IrOpcode::kTruncateTaggedToWord32:
10991cb0ef41Sopenharmony_ci      result = LowerTruncateTaggedToWord32(node);
11001cb0ef41Sopenharmony_ci      break;
11011cb0ef41Sopenharmony_ci    case IrOpcode::kCheckedTruncateTaggedToWord32:
11021cb0ef41Sopenharmony_ci      result = LowerCheckedTruncateTaggedToWord32(node, frame_state);
11031cb0ef41Sopenharmony_ci      break;
11041cb0ef41Sopenharmony_ci    case IrOpcode::kNumberToString:
11051cb0ef41Sopenharmony_ci      result = LowerNumberToString(node);
11061cb0ef41Sopenharmony_ci      break;
11071cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsArrayBufferView:
11081cb0ef41Sopenharmony_ci      result = LowerObjectIsArrayBufferView(node);
11091cb0ef41Sopenharmony_ci      break;
11101cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsBigInt:
11111cb0ef41Sopenharmony_ci      result = LowerObjectIsBigInt(node);
11121cb0ef41Sopenharmony_ci      break;
11131cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsCallable:
11141cb0ef41Sopenharmony_ci      result = LowerObjectIsCallable(node);
11151cb0ef41Sopenharmony_ci      break;
11161cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsConstructor:
11171cb0ef41Sopenharmony_ci      result = LowerObjectIsConstructor(node);
11181cb0ef41Sopenharmony_ci      break;
11191cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsDetectableCallable:
11201cb0ef41Sopenharmony_ci      result = LowerObjectIsDetectableCallable(node);
11211cb0ef41Sopenharmony_ci      break;
11221cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsMinusZero:
11231cb0ef41Sopenharmony_ci      result = LowerObjectIsMinusZero(node);
11241cb0ef41Sopenharmony_ci      break;
11251cb0ef41Sopenharmony_ci    case IrOpcode::kNumberIsMinusZero:
11261cb0ef41Sopenharmony_ci      result = LowerNumberIsMinusZero(node);
11271cb0ef41Sopenharmony_ci      break;
11281cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsNaN:
11291cb0ef41Sopenharmony_ci      result = LowerObjectIsNaN(node);
11301cb0ef41Sopenharmony_ci      break;
11311cb0ef41Sopenharmony_ci    case IrOpcode::kNumberIsNaN:
11321cb0ef41Sopenharmony_ci      result = LowerNumberIsNaN(node);
11331cb0ef41Sopenharmony_ci      break;
11341cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsNonCallable:
11351cb0ef41Sopenharmony_ci      result = LowerObjectIsNonCallable(node);
11361cb0ef41Sopenharmony_ci      break;
11371cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsNumber:
11381cb0ef41Sopenharmony_ci      result = LowerObjectIsNumber(node);
11391cb0ef41Sopenharmony_ci      break;
11401cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsReceiver:
11411cb0ef41Sopenharmony_ci      result = LowerObjectIsReceiver(node);
11421cb0ef41Sopenharmony_ci      break;
11431cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsSmi:
11441cb0ef41Sopenharmony_ci      result = LowerObjectIsSmi(node);
11451cb0ef41Sopenharmony_ci      break;
11461cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsString:
11471cb0ef41Sopenharmony_ci      result = LowerObjectIsString(node);
11481cb0ef41Sopenharmony_ci      break;
11491cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsSymbol:
11501cb0ef41Sopenharmony_ci      result = LowerObjectIsSymbol(node);
11511cb0ef41Sopenharmony_ci      break;
11521cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsUndetectable:
11531cb0ef41Sopenharmony_ci      result = LowerObjectIsUndetectable(node);
11541cb0ef41Sopenharmony_ci      break;
11551cb0ef41Sopenharmony_ci    case IrOpcode::kArgumentsLength:
11561cb0ef41Sopenharmony_ci      result = LowerArgumentsLength(node);
11571cb0ef41Sopenharmony_ci      break;
11581cb0ef41Sopenharmony_ci    case IrOpcode::kRestLength:
11591cb0ef41Sopenharmony_ci      result = LowerRestLength(node);
11601cb0ef41Sopenharmony_ci      break;
11611cb0ef41Sopenharmony_ci    case IrOpcode::kToBoolean:
11621cb0ef41Sopenharmony_ci      result = LowerToBoolean(node);
11631cb0ef41Sopenharmony_ci      break;
11641cb0ef41Sopenharmony_ci    case IrOpcode::kTypeOf:
11651cb0ef41Sopenharmony_ci      result = LowerTypeOf(node);
11661cb0ef41Sopenharmony_ci      break;
11671cb0ef41Sopenharmony_ci    case IrOpcode::kNewDoubleElements:
11681cb0ef41Sopenharmony_ci      result = LowerNewDoubleElements(node);
11691cb0ef41Sopenharmony_ci      break;
11701cb0ef41Sopenharmony_ci    case IrOpcode::kNewSmiOrObjectElements:
11711cb0ef41Sopenharmony_ci      result = LowerNewSmiOrObjectElements(node);
11721cb0ef41Sopenharmony_ci      break;
11731cb0ef41Sopenharmony_ci    case IrOpcode::kNewArgumentsElements:
11741cb0ef41Sopenharmony_ci      result = LowerNewArgumentsElements(node);
11751cb0ef41Sopenharmony_ci      break;
11761cb0ef41Sopenharmony_ci    case IrOpcode::kNewConsString:
11771cb0ef41Sopenharmony_ci      result = LowerNewConsString(node);
11781cb0ef41Sopenharmony_ci      break;
11791cb0ef41Sopenharmony_ci    case IrOpcode::kSameValue:
11801cb0ef41Sopenharmony_ci      result = LowerSameValue(node);
11811cb0ef41Sopenharmony_ci      break;
11821cb0ef41Sopenharmony_ci    case IrOpcode::kSameValueNumbersOnly:
11831cb0ef41Sopenharmony_ci      result = LowerSameValueNumbersOnly(node);
11841cb0ef41Sopenharmony_ci      break;
11851cb0ef41Sopenharmony_ci    case IrOpcode::kNumberSameValue:
11861cb0ef41Sopenharmony_ci      result = LowerNumberSameValue(node);
11871cb0ef41Sopenharmony_ci      break;
11881cb0ef41Sopenharmony_ci    case IrOpcode::kDeadValue:
11891cb0ef41Sopenharmony_ci      result = LowerDeadValue(node);
11901cb0ef41Sopenharmony_ci      break;
11911cb0ef41Sopenharmony_ci    case IrOpcode::kStringConcat:
11921cb0ef41Sopenharmony_ci      result = LowerStringConcat(node);
11931cb0ef41Sopenharmony_ci      break;
11941cb0ef41Sopenharmony_ci    case IrOpcode::kStringFromSingleCharCode:
11951cb0ef41Sopenharmony_ci      result = LowerStringFromSingleCharCode(node);
11961cb0ef41Sopenharmony_ci      break;
11971cb0ef41Sopenharmony_ci    case IrOpcode::kStringFromSingleCodePoint:
11981cb0ef41Sopenharmony_ci      result = LowerStringFromSingleCodePoint(node);
11991cb0ef41Sopenharmony_ci      break;
12001cb0ef41Sopenharmony_ci    case IrOpcode::kStringIndexOf:
12011cb0ef41Sopenharmony_ci      result = LowerStringIndexOf(node);
12021cb0ef41Sopenharmony_ci      break;
12031cb0ef41Sopenharmony_ci    case IrOpcode::kStringFromCodePointAt:
12041cb0ef41Sopenharmony_ci      result = LowerStringFromCodePointAt(node);
12051cb0ef41Sopenharmony_ci      break;
12061cb0ef41Sopenharmony_ci    case IrOpcode::kStringLength:
12071cb0ef41Sopenharmony_ci      result = LowerStringLength(node);
12081cb0ef41Sopenharmony_ci      break;
12091cb0ef41Sopenharmony_ci    case IrOpcode::kStringToNumber:
12101cb0ef41Sopenharmony_ci      result = LowerStringToNumber(node);
12111cb0ef41Sopenharmony_ci      break;
12121cb0ef41Sopenharmony_ci    case IrOpcode::kStringCharCodeAt:
12131cb0ef41Sopenharmony_ci      result = LowerStringCharCodeAt(node);
12141cb0ef41Sopenharmony_ci      break;
12151cb0ef41Sopenharmony_ci    case IrOpcode::kStringCodePointAt:
12161cb0ef41Sopenharmony_ci      result = LowerStringCodePointAt(node);
12171cb0ef41Sopenharmony_ci      break;
12181cb0ef41Sopenharmony_ci    case IrOpcode::kStringToLowerCaseIntl:
12191cb0ef41Sopenharmony_ci      result = LowerStringToLowerCaseIntl(node);
12201cb0ef41Sopenharmony_ci      break;
12211cb0ef41Sopenharmony_ci    case IrOpcode::kStringToUpperCaseIntl:
12221cb0ef41Sopenharmony_ci      result = LowerStringToUpperCaseIntl(node);
12231cb0ef41Sopenharmony_ci      break;
12241cb0ef41Sopenharmony_ci    case IrOpcode::kStringSubstring:
12251cb0ef41Sopenharmony_ci      result = LowerStringSubstring(node);
12261cb0ef41Sopenharmony_ci      break;
12271cb0ef41Sopenharmony_ci    case IrOpcode::kStringEqual:
12281cb0ef41Sopenharmony_ci      result = LowerStringEqual(node);
12291cb0ef41Sopenharmony_ci      break;
12301cb0ef41Sopenharmony_ci    case IrOpcode::kStringLessThan:
12311cb0ef41Sopenharmony_ci      result = LowerStringLessThan(node);
12321cb0ef41Sopenharmony_ci      break;
12331cb0ef41Sopenharmony_ci    case IrOpcode::kStringLessThanOrEqual:
12341cb0ef41Sopenharmony_ci      result = LowerStringLessThanOrEqual(node);
12351cb0ef41Sopenharmony_ci      break;
12361cb0ef41Sopenharmony_ci    case IrOpcode::kBigIntAdd:
12371cb0ef41Sopenharmony_ci      result = LowerBigIntAdd(node, frame_state);
12381cb0ef41Sopenharmony_ci      break;
12391cb0ef41Sopenharmony_ci    case IrOpcode::kBigIntSubtract:
12401cb0ef41Sopenharmony_ci      result = LowerBigIntSubtract(node, frame_state);
12411cb0ef41Sopenharmony_ci      break;
12421cb0ef41Sopenharmony_ci    case IrOpcode::kBigIntNegate:
12431cb0ef41Sopenharmony_ci      result = LowerBigIntNegate(node);
12441cb0ef41Sopenharmony_ci      break;
12451cb0ef41Sopenharmony_ci    case IrOpcode::kNumberIsFloat64Hole:
12461cb0ef41Sopenharmony_ci      result = LowerNumberIsFloat64Hole(node);
12471cb0ef41Sopenharmony_ci      break;
12481cb0ef41Sopenharmony_ci    case IrOpcode::kNumberIsFinite:
12491cb0ef41Sopenharmony_ci      result = LowerNumberIsFinite(node);
12501cb0ef41Sopenharmony_ci      break;
12511cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsFiniteNumber:
12521cb0ef41Sopenharmony_ci      result = LowerObjectIsFiniteNumber(node);
12531cb0ef41Sopenharmony_ci      break;
12541cb0ef41Sopenharmony_ci    case IrOpcode::kNumberIsInteger:
12551cb0ef41Sopenharmony_ci      result = LowerNumberIsInteger(node);
12561cb0ef41Sopenharmony_ci      break;
12571cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsInteger:
12581cb0ef41Sopenharmony_ci      result = LowerObjectIsInteger(node);
12591cb0ef41Sopenharmony_ci      break;
12601cb0ef41Sopenharmony_ci    case IrOpcode::kNumberIsSafeInteger:
12611cb0ef41Sopenharmony_ci      result = LowerNumberIsSafeInteger(node);
12621cb0ef41Sopenharmony_ci      break;
12631cb0ef41Sopenharmony_ci    case IrOpcode::kObjectIsSafeInteger:
12641cb0ef41Sopenharmony_ci      result = LowerObjectIsSafeInteger(node);
12651cb0ef41Sopenharmony_ci      break;
12661cb0ef41Sopenharmony_ci    case IrOpcode::kCheckFloat64Hole:
12671cb0ef41Sopenharmony_ci      result = LowerCheckFloat64Hole(node, frame_state);
12681cb0ef41Sopenharmony_ci      break;
12691cb0ef41Sopenharmony_ci    case IrOpcode::kCheckNotTaggedHole:
12701cb0ef41Sopenharmony_ci      result = LowerCheckNotTaggedHole(node, frame_state);
12711cb0ef41Sopenharmony_ci      break;
12721cb0ef41Sopenharmony_ci    case IrOpcode::kConvertTaggedHoleToUndefined:
12731cb0ef41Sopenharmony_ci      result = LowerConvertTaggedHoleToUndefined(node);
12741cb0ef41Sopenharmony_ci      break;
12751cb0ef41Sopenharmony_ci    case IrOpcode::kCheckEqualsInternalizedString:
12761cb0ef41Sopenharmony_ci      LowerCheckEqualsInternalizedString(node, frame_state);
12771cb0ef41Sopenharmony_ci      break;
12781cb0ef41Sopenharmony_ci    case IrOpcode::kAllocate:
12791cb0ef41Sopenharmony_ci      result = LowerAllocate(node);
12801cb0ef41Sopenharmony_ci      break;
12811cb0ef41Sopenharmony_ci    case IrOpcode::kCheckEqualsSymbol:
12821cb0ef41Sopenharmony_ci      LowerCheckEqualsSymbol(node, frame_state);
12831cb0ef41Sopenharmony_ci      break;
12841cb0ef41Sopenharmony_ci    case IrOpcode::kPlainPrimitiveToNumber:
12851cb0ef41Sopenharmony_ci      result = LowerPlainPrimitiveToNumber(node);
12861cb0ef41Sopenharmony_ci      break;
12871cb0ef41Sopenharmony_ci    case IrOpcode::kPlainPrimitiveToWord32:
12881cb0ef41Sopenharmony_ci      result = LowerPlainPrimitiveToWord32(node);
12891cb0ef41Sopenharmony_ci      break;
12901cb0ef41Sopenharmony_ci    case IrOpcode::kPlainPrimitiveToFloat64:
12911cb0ef41Sopenharmony_ci      result = LowerPlainPrimitiveToFloat64(node);
12921cb0ef41Sopenharmony_ci      break;
12931cb0ef41Sopenharmony_ci    case IrOpcode::kEnsureWritableFastElements:
12941cb0ef41Sopenharmony_ci      result = LowerEnsureWritableFastElements(node);
12951cb0ef41Sopenharmony_ci      break;
12961cb0ef41Sopenharmony_ci    case IrOpcode::kMaybeGrowFastElements:
12971cb0ef41Sopenharmony_ci      result = LowerMaybeGrowFastElements(node, frame_state);
12981cb0ef41Sopenharmony_ci      break;
12991cb0ef41Sopenharmony_ci    case IrOpcode::kTransitionElementsKind:
13001cb0ef41Sopenharmony_ci      LowerTransitionElementsKind(node);
13011cb0ef41Sopenharmony_ci      break;
13021cb0ef41Sopenharmony_ci    case IrOpcode::kLoadMessage:
13031cb0ef41Sopenharmony_ci      result = LowerLoadMessage(node);
13041cb0ef41Sopenharmony_ci      break;
13051cb0ef41Sopenharmony_ci    case IrOpcode::kStoreMessage:
13061cb0ef41Sopenharmony_ci      LowerStoreMessage(node);
13071cb0ef41Sopenharmony_ci      break;
13081cb0ef41Sopenharmony_ci    case IrOpcode::kFastApiCall:
13091cb0ef41Sopenharmony_ci      result = LowerFastApiCall(node);
13101cb0ef41Sopenharmony_ci      break;
13111cb0ef41Sopenharmony_ci    case IrOpcode::kLoadFieldByIndex:
13121cb0ef41Sopenharmony_ci      result = LowerLoadFieldByIndex(node);
13131cb0ef41Sopenharmony_ci      break;
13141cb0ef41Sopenharmony_ci    case IrOpcode::kLoadTypedElement:
13151cb0ef41Sopenharmony_ci      result = LowerLoadTypedElement(node);
13161cb0ef41Sopenharmony_ci      break;
13171cb0ef41Sopenharmony_ci    case IrOpcode::kLoadDataViewElement:
13181cb0ef41Sopenharmony_ci      result = LowerLoadDataViewElement(node);
13191cb0ef41Sopenharmony_ci      break;
13201cb0ef41Sopenharmony_ci    case IrOpcode::kLoadStackArgument:
13211cb0ef41Sopenharmony_ci      result = LowerLoadStackArgument(node);
13221cb0ef41Sopenharmony_ci      break;
13231cb0ef41Sopenharmony_ci    case IrOpcode::kStoreTypedElement:
13241cb0ef41Sopenharmony_ci      LowerStoreTypedElement(node);
13251cb0ef41Sopenharmony_ci      break;
13261cb0ef41Sopenharmony_ci    case IrOpcode::kStoreDataViewElement:
13271cb0ef41Sopenharmony_ci      LowerStoreDataViewElement(node);
13281cb0ef41Sopenharmony_ci      break;
13291cb0ef41Sopenharmony_ci    case IrOpcode::kStoreSignedSmallElement:
13301cb0ef41Sopenharmony_ci      LowerStoreSignedSmallElement(node);
13311cb0ef41Sopenharmony_ci      break;
13321cb0ef41Sopenharmony_ci    case IrOpcode::kFindOrderedHashMapEntry:
13331cb0ef41Sopenharmony_ci      result = LowerFindOrderedHashMapEntry(node);
13341cb0ef41Sopenharmony_ci      break;
13351cb0ef41Sopenharmony_ci    case IrOpcode::kFindOrderedHashMapEntryForInt32Key:
13361cb0ef41Sopenharmony_ci      result = LowerFindOrderedHashMapEntryForInt32Key(node);
13371cb0ef41Sopenharmony_ci      break;
13381cb0ef41Sopenharmony_ci    case IrOpcode::kTransitionAndStoreNumberElement:
13391cb0ef41Sopenharmony_ci      LowerTransitionAndStoreNumberElement(node);
13401cb0ef41Sopenharmony_ci      break;
13411cb0ef41Sopenharmony_ci    case IrOpcode::kTransitionAndStoreNonNumberElement:
13421cb0ef41Sopenharmony_ci      LowerTransitionAndStoreNonNumberElement(node);
13431cb0ef41Sopenharmony_ci      break;
13441cb0ef41Sopenharmony_ci    case IrOpcode::kTransitionAndStoreElement:
13451cb0ef41Sopenharmony_ci      LowerTransitionAndStoreElement(node);
13461cb0ef41Sopenharmony_ci      break;
13471cb0ef41Sopenharmony_ci    case IrOpcode::kRuntimeAbort:
13481cb0ef41Sopenharmony_ci      LowerRuntimeAbort(node);
13491cb0ef41Sopenharmony_ci      break;
13501cb0ef41Sopenharmony_ci    case IrOpcode::kAssertType:
13511cb0ef41Sopenharmony_ci      result = LowerAssertType(node);
13521cb0ef41Sopenharmony_ci      break;
13531cb0ef41Sopenharmony_ci    case IrOpcode::kConvertReceiver:
13541cb0ef41Sopenharmony_ci      result = LowerConvertReceiver(node);
13551cb0ef41Sopenharmony_ci      break;
13561cb0ef41Sopenharmony_ci    case IrOpcode::kFloat64RoundUp:
13571cb0ef41Sopenharmony_ci      if (!LowerFloat64RoundUp(node).To(&result)) {
13581cb0ef41Sopenharmony_ci        return false;
13591cb0ef41Sopenharmony_ci      }
13601cb0ef41Sopenharmony_ci      break;
13611cb0ef41Sopenharmony_ci    case IrOpcode::kFloat64RoundDown:
13621cb0ef41Sopenharmony_ci      if (!LowerFloat64RoundDown(node).To(&result)) {
13631cb0ef41Sopenharmony_ci        return false;
13641cb0ef41Sopenharmony_ci      }
13651cb0ef41Sopenharmony_ci      break;
13661cb0ef41Sopenharmony_ci    case IrOpcode::kFloat64RoundTruncate:
13671cb0ef41Sopenharmony_ci      if (!LowerFloat64RoundTruncate(node).To(&result)) {
13681cb0ef41Sopenharmony_ci        return false;
13691cb0ef41Sopenharmony_ci      }
13701cb0ef41Sopenharmony_ci      break;
13711cb0ef41Sopenharmony_ci    case IrOpcode::kFloat64RoundTiesEven:
13721cb0ef41Sopenharmony_ci      if (!LowerFloat64RoundTiesEven(node).To(&result)) {
13731cb0ef41Sopenharmony_ci        return false;
13741cb0ef41Sopenharmony_ci      }
13751cb0ef41Sopenharmony_ci      break;
13761cb0ef41Sopenharmony_ci    case IrOpcode::kDateNow:
13771cb0ef41Sopenharmony_ci      result = LowerDateNow(node);
13781cb0ef41Sopenharmony_ci      break;
13791cb0ef41Sopenharmony_ci    case IrOpcode::kFoldConstant:
13801cb0ef41Sopenharmony_ci      result = LowerFoldConstant(node);
13811cb0ef41Sopenharmony_ci      break;
13821cb0ef41Sopenharmony_ci    default:
13831cb0ef41Sopenharmony_ci      return false;
13841cb0ef41Sopenharmony_ci  }
13851cb0ef41Sopenharmony_ci
13861cb0ef41Sopenharmony_ci  if ((result ? 1 : 0) != node->op()->ValueOutputCount()) {
13871cb0ef41Sopenharmony_ci    FATAL(
13881cb0ef41Sopenharmony_ci        "Effect control linearizer lowering of '%s':"
13891cb0ef41Sopenharmony_ci        " value output count does not agree.",
13901cb0ef41Sopenharmony_ci        node->op()->mnemonic());
13911cb0ef41Sopenharmony_ci  }
13921cb0ef41Sopenharmony_ci
13931cb0ef41Sopenharmony_ci  NodeProperties::ReplaceUses(node, result, gasm()->effect(),
13941cb0ef41Sopenharmony_ci                              gasm()->control());
13951cb0ef41Sopenharmony_ci  return true;
13961cb0ef41Sopenharmony_ci}
13971cb0ef41Sopenharmony_ci
13981cb0ef41Sopenharmony_ci#define __ gasm()->
13991cb0ef41Sopenharmony_ci
14001cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node) {
14011cb0ef41Sopenharmony_ci  CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
14021cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
14031cb0ef41Sopenharmony_ci  return ChangeFloat64ToTagged(value, mode);
14041cb0ef41Sopenharmony_ci}
14051cb0ef41Sopenharmony_ci
14061cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeFloat64ToTagged(
14071cb0ef41Sopenharmony_ci    Node* value, CheckForMinusZeroMode mode) {
14081cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
14091cb0ef41Sopenharmony_ci  auto if_heapnumber = __ MakeDeferredLabel();
14101cb0ef41Sopenharmony_ci  auto if_int32 = __ MakeLabel();
14111cb0ef41Sopenharmony_ci
14121cb0ef41Sopenharmony_ci  Node* value32 = __ RoundFloat64ToInt32(value);
14131cb0ef41Sopenharmony_ci  __ GotoIf(__ Float64Equal(value, __ ChangeInt32ToFloat64(value32)),
14141cb0ef41Sopenharmony_ci            &if_int32);
14151cb0ef41Sopenharmony_ci  __ Goto(&if_heapnumber);
14161cb0ef41Sopenharmony_ci
14171cb0ef41Sopenharmony_ci  __ Bind(&if_int32);
14181cb0ef41Sopenharmony_ci  {
14191cb0ef41Sopenharmony_ci    if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
14201cb0ef41Sopenharmony_ci      Node* zero = __ Int32Constant(0);
14211cb0ef41Sopenharmony_ci      auto if_zero = __ MakeDeferredLabel();
14221cb0ef41Sopenharmony_ci      auto if_smi = __ MakeLabel();
14231cb0ef41Sopenharmony_ci
14241cb0ef41Sopenharmony_ci      __ GotoIf(__ Word32Equal(value32, zero), &if_zero);
14251cb0ef41Sopenharmony_ci      __ Goto(&if_smi);
14261cb0ef41Sopenharmony_ci
14271cb0ef41Sopenharmony_ci      __ Bind(&if_zero);
14281cb0ef41Sopenharmony_ci      {
14291cb0ef41Sopenharmony_ci        // In case of 0, we need to check the high bits for the IEEE -0 pattern.
14301cb0ef41Sopenharmony_ci        __ GotoIf(__ Int32LessThan(__ Float64ExtractHighWord32(value), zero),
14311cb0ef41Sopenharmony_ci                  &if_heapnumber);
14321cb0ef41Sopenharmony_ci        __ Goto(&if_smi);
14331cb0ef41Sopenharmony_ci      }
14341cb0ef41Sopenharmony_ci
14351cb0ef41Sopenharmony_ci      __ Bind(&if_smi);
14361cb0ef41Sopenharmony_ci    }
14371cb0ef41Sopenharmony_ci
14381cb0ef41Sopenharmony_ci    if (SmiValuesAre32Bits()) {
14391cb0ef41Sopenharmony_ci      Node* value_smi = ChangeInt32ToSmi(value32);
14401cb0ef41Sopenharmony_ci      __ Goto(&done, value_smi);
14411cb0ef41Sopenharmony_ci    } else {
14421cb0ef41Sopenharmony_ci      SmiTagOrOverflow(value32, &if_heapnumber, &done);
14431cb0ef41Sopenharmony_ci    }
14441cb0ef41Sopenharmony_ci  }
14451cb0ef41Sopenharmony_ci
14461cb0ef41Sopenharmony_ci  __ Bind(&if_heapnumber);
14471cb0ef41Sopenharmony_ci  {
14481cb0ef41Sopenharmony_ci    Node* value_number = AllocateHeapNumberWithValue(value);
14491cb0ef41Sopenharmony_ci    __ Goto(&done, value_number);
14501cb0ef41Sopenharmony_ci  }
14511cb0ef41Sopenharmony_ci
14521cb0ef41Sopenharmony_ci  __ Bind(&done);
14531cb0ef41Sopenharmony_ci  return done.PhiAt(0);
14541cb0ef41Sopenharmony_ci}
14551cb0ef41Sopenharmony_ci
14561cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeFloat64ToTaggedPointer(Node* node) {
14571cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
14581cb0ef41Sopenharmony_ci  return AllocateHeapNumberWithValue(value);
14591cb0ef41Sopenharmony_ci}
14601cb0ef41Sopenharmony_ci
14611cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeBitToTagged(Node* node) {
14621cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
14631cb0ef41Sopenharmony_ci  return ChangeBitToTagged(value);
14641cb0ef41Sopenharmony_ci}
14651cb0ef41Sopenharmony_ci
14661cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeBitToTagged(Node* value) {
14671cb0ef41Sopenharmony_ci  auto if_true = __ MakeLabel();
14681cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
14691cb0ef41Sopenharmony_ci
14701cb0ef41Sopenharmony_ci  __ GotoIf(value, &if_true);
14711cb0ef41Sopenharmony_ci  __ Goto(&done, __ FalseConstant());
14721cb0ef41Sopenharmony_ci
14731cb0ef41Sopenharmony_ci  __ Bind(&if_true);
14741cb0ef41Sopenharmony_ci  __ Goto(&done, __ TrueConstant());
14751cb0ef41Sopenharmony_ci
14761cb0ef41Sopenharmony_ci  __ Bind(&done);
14771cb0ef41Sopenharmony_ci  return done.PhiAt(0);
14781cb0ef41Sopenharmony_ci}
14791cb0ef41Sopenharmony_ci
14801cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeInt31ToTaggedSigned(Node* node) {
14811cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
14821cb0ef41Sopenharmony_ci  return ChangeInt32ToSmi(value);
14831cb0ef41Sopenharmony_ci}
14841cb0ef41Sopenharmony_ci
14851cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node) {
14861cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
14871cb0ef41Sopenharmony_ci  return ChangeInt32ToTagged(value);
14881cb0ef41Sopenharmony_ci}
14891cb0ef41Sopenharmony_ci
14901cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeInt32ToTagged(Node* value) {
14911cb0ef41Sopenharmony_ci  if (SmiValuesAre32Bits()) {
14921cb0ef41Sopenharmony_ci    return ChangeInt32ToSmi(value);
14931cb0ef41Sopenharmony_ci  }
14941cb0ef41Sopenharmony_ci  DCHECK(SmiValuesAre31Bits());
14951cb0ef41Sopenharmony_ci
14961cb0ef41Sopenharmony_ci  auto if_overflow = __ MakeDeferredLabel();
14971cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
14981cb0ef41Sopenharmony_ci
14991cb0ef41Sopenharmony_ci  SmiTagOrOverflow(value, &if_overflow, &done);
15001cb0ef41Sopenharmony_ci
15011cb0ef41Sopenharmony_ci  __ Bind(&if_overflow);
15021cb0ef41Sopenharmony_ci  Node* number = AllocateHeapNumberWithValue(__ ChangeInt32ToFloat64(value));
15031cb0ef41Sopenharmony_ci  __ Goto(&done, number);
15041cb0ef41Sopenharmony_ci
15051cb0ef41Sopenharmony_ci  __ Bind(&done);
15061cb0ef41Sopenharmony_ci  return done.PhiAt(0);
15071cb0ef41Sopenharmony_ci}
15081cb0ef41Sopenharmony_ci
15091cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeInt64ToTagged(Node* node) {
15101cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
15111cb0ef41Sopenharmony_ci
15121cb0ef41Sopenharmony_ci  auto if_not_in_smi_range = __ MakeDeferredLabel();
15131cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
15141cb0ef41Sopenharmony_ci
15151cb0ef41Sopenharmony_ci  Node* value32 = __ TruncateInt64ToInt32(value);
15161cb0ef41Sopenharmony_ci  __ GotoIfNot(__ Word64Equal(__ ChangeInt32ToInt64(value32), value),
15171cb0ef41Sopenharmony_ci               &if_not_in_smi_range);
15181cb0ef41Sopenharmony_ci
15191cb0ef41Sopenharmony_ci  if (SmiValuesAre32Bits()) {
15201cb0ef41Sopenharmony_ci    Node* value_smi = ChangeInt64ToSmi(value);
15211cb0ef41Sopenharmony_ci    __ Goto(&done, value_smi);
15221cb0ef41Sopenharmony_ci  } else {
15231cb0ef41Sopenharmony_ci    SmiTagOrOverflow(value32, &if_not_in_smi_range, &done);
15241cb0ef41Sopenharmony_ci  }
15251cb0ef41Sopenharmony_ci
15261cb0ef41Sopenharmony_ci  __ Bind(&if_not_in_smi_range);
15271cb0ef41Sopenharmony_ci  Node* number = AllocateHeapNumberWithValue(__ ChangeInt64ToFloat64(value));
15281cb0ef41Sopenharmony_ci  __ Goto(&done, number);
15291cb0ef41Sopenharmony_ci
15301cb0ef41Sopenharmony_ci  __ Bind(&done);
15311cb0ef41Sopenharmony_ci  return done.PhiAt(0);
15321cb0ef41Sopenharmony_ci}
15331cb0ef41Sopenharmony_ci
15341cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node) {
15351cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
15361cb0ef41Sopenharmony_ci  return ChangeUint32ToTagged(value);
15371cb0ef41Sopenharmony_ci}
15381cb0ef41Sopenharmony_ci
15391cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeUint32ToTagged(Node* value) {
15401cb0ef41Sopenharmony_ci  auto if_not_in_smi_range = __ MakeDeferredLabel();
15411cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
15421cb0ef41Sopenharmony_ci
15431cb0ef41Sopenharmony_ci  Node* check = __ Uint32LessThanOrEqual(value, SmiMaxValueConstant());
15441cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &if_not_in_smi_range);
15451cb0ef41Sopenharmony_ci  __ Goto(&done, ChangeUint32ToSmi(value));
15461cb0ef41Sopenharmony_ci
15471cb0ef41Sopenharmony_ci  __ Bind(&if_not_in_smi_range);
15481cb0ef41Sopenharmony_ci  Node* number = AllocateHeapNumberWithValue(__ ChangeUint32ToFloat64(value));
15491cb0ef41Sopenharmony_ci
15501cb0ef41Sopenharmony_ci  __ Goto(&done, number);
15511cb0ef41Sopenharmony_ci  __ Bind(&done);
15521cb0ef41Sopenharmony_ci
15531cb0ef41Sopenharmony_ci  return done.PhiAt(0);
15541cb0ef41Sopenharmony_ci}
15551cb0ef41Sopenharmony_ci
15561cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeUint64ToTagged(Node* node) {
15571cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
15581cb0ef41Sopenharmony_ci
15591cb0ef41Sopenharmony_ci  auto if_not_in_smi_range = __ MakeDeferredLabel();
15601cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
15611cb0ef41Sopenharmony_ci
15621cb0ef41Sopenharmony_ci  Node* check =
15631cb0ef41Sopenharmony_ci      __ Uint64LessThanOrEqual(value, __ Int64Constant(Smi::kMaxValue));
15641cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &if_not_in_smi_range);
15651cb0ef41Sopenharmony_ci  __ Goto(&done, ChangeInt64ToSmi(value));
15661cb0ef41Sopenharmony_ci
15671cb0ef41Sopenharmony_ci  __ Bind(&if_not_in_smi_range);
15681cb0ef41Sopenharmony_ci  Node* number = AllocateHeapNumberWithValue(__ ChangeInt64ToFloat64(value));
15691cb0ef41Sopenharmony_ci
15701cb0ef41Sopenharmony_ci  __ Goto(&done, number);
15711cb0ef41Sopenharmony_ci  __ Bind(&done);
15721cb0ef41Sopenharmony_ci
15731cb0ef41Sopenharmony_ci  return done.PhiAt(0);
15741cb0ef41Sopenharmony_ci}
15751cb0ef41Sopenharmony_ci
15761cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeTaggedSignedToInt32(Node* node) {
15771cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
15781cb0ef41Sopenharmony_ci  return ChangeSmiToInt32(value);
15791cb0ef41Sopenharmony_ci}
15801cb0ef41Sopenharmony_ci
15811cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeTaggedSignedToInt64(Node* node) {
15821cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
15831cb0ef41Sopenharmony_ci  return ChangeSmiToInt64(value);
15841cb0ef41Sopenharmony_ci}
15851cb0ef41Sopenharmony_ci
15861cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeTaggedToBit(Node* node) {
15871cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
15881cb0ef41Sopenharmony_ci  return __ TaggedEqual(value, __ TrueConstant());
15891cb0ef41Sopenharmony_ci}
15901cb0ef41Sopenharmony_ci
15911cb0ef41Sopenharmony_civoid EffectControlLinearizer::TruncateTaggedPointerToBit(
15921cb0ef41Sopenharmony_ci    Node* node, GraphAssemblerLabel<1>* done) {
15931cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
15941cb0ef41Sopenharmony_ci
15951cb0ef41Sopenharmony_ci  auto if_heapnumber = __ MakeDeferredLabel();
15961cb0ef41Sopenharmony_ci  auto if_bigint = __ MakeDeferredLabel();
15971cb0ef41Sopenharmony_ci
15981cb0ef41Sopenharmony_ci  Node* zero = __ Int32Constant(0);
15991cb0ef41Sopenharmony_ci  Node* fzero = __ Float64Constant(0.0);
16001cb0ef41Sopenharmony_ci
16011cb0ef41Sopenharmony_ci  // Check if {value} is false.
16021cb0ef41Sopenharmony_ci  __ GotoIf(__ TaggedEqual(value, __ FalseConstant()), done, zero);
16031cb0ef41Sopenharmony_ci
16041cb0ef41Sopenharmony_ci  // Check if {value} is the empty string.
16051cb0ef41Sopenharmony_ci  __ GotoIf(__ TaggedEqual(value, __ EmptyStringConstant()), done, zero);
16061cb0ef41Sopenharmony_ci
16071cb0ef41Sopenharmony_ci  // Load the map of {value}.
16081cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
16091cb0ef41Sopenharmony_ci
16101cb0ef41Sopenharmony_ci  // Check if the {value} is undetectable and immediately return false.
16111cb0ef41Sopenharmony_ci  // This includes undefined and null.
16121cb0ef41Sopenharmony_ci  Node* value_map_bitfield =
16131cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapBitField(), value_map);
16141cb0ef41Sopenharmony_ci  __ GotoIfNot(
16151cb0ef41Sopenharmony_ci      __ Word32Equal(
16161cb0ef41Sopenharmony_ci          __ Word32And(value_map_bitfield,
16171cb0ef41Sopenharmony_ci                       __ Int32Constant(Map::Bits1::IsUndetectableBit::kMask)),
16181cb0ef41Sopenharmony_ci          zero),
16191cb0ef41Sopenharmony_ci      done, zero);
16201cb0ef41Sopenharmony_ci
16211cb0ef41Sopenharmony_ci  // Check if {value} is a HeapNumber.
16221cb0ef41Sopenharmony_ci  __ GotoIf(__ TaggedEqual(value_map, __ HeapNumberMapConstant()),
16231cb0ef41Sopenharmony_ci            &if_heapnumber);
16241cb0ef41Sopenharmony_ci
16251cb0ef41Sopenharmony_ci  // Check if {value} is a BigInt.
16261cb0ef41Sopenharmony_ci  __ GotoIf(__ TaggedEqual(value_map, __ BigIntMapConstant()), &if_bigint);
16271cb0ef41Sopenharmony_ci
16281cb0ef41Sopenharmony_ci  // All other values that reach here are true.
16291cb0ef41Sopenharmony_ci  __ Goto(done, __ Int32Constant(1));
16301cb0ef41Sopenharmony_ci
16311cb0ef41Sopenharmony_ci  __ Bind(&if_heapnumber);
16321cb0ef41Sopenharmony_ci  {
16331cb0ef41Sopenharmony_ci    // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or
16341cb0ef41Sopenharmony_ci    // NaN.
16351cb0ef41Sopenharmony_ci    Node* value_value =
16361cb0ef41Sopenharmony_ci        __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
16371cb0ef41Sopenharmony_ci    __ Goto(done, __ Float64LessThan(fzero, __ Float64Abs(value_value)));
16381cb0ef41Sopenharmony_ci  }
16391cb0ef41Sopenharmony_ci
16401cb0ef41Sopenharmony_ci  __ Bind(&if_bigint);
16411cb0ef41Sopenharmony_ci  {
16421cb0ef41Sopenharmony_ci    Node* bitfield = __ LoadField(AccessBuilder::ForBigIntBitfield(), value);
16431cb0ef41Sopenharmony_ci    Node* length_is_zero = __ Word32Equal(
16441cb0ef41Sopenharmony_ci        __ Word32And(bitfield, __ Int32Constant(BigInt::LengthBits::kMask)),
16451cb0ef41Sopenharmony_ci        __ Int32Constant(0));
16461cb0ef41Sopenharmony_ci    __ Goto(done, __ Word32Equal(length_is_zero, zero));
16471cb0ef41Sopenharmony_ci  }
16481cb0ef41Sopenharmony_ci}
16491cb0ef41Sopenharmony_ci
16501cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) {
16511cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
16521cb0ef41Sopenharmony_ci  auto if_smi = __ MakeDeferredLabel();
16531cb0ef41Sopenharmony_ci
16541cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
16551cb0ef41Sopenharmony_ci  __ GotoIf(ObjectIsSmi(value), &if_smi);
16561cb0ef41Sopenharmony_ci
16571cb0ef41Sopenharmony_ci  TruncateTaggedPointerToBit(node, &done);
16581cb0ef41Sopenharmony_ci
16591cb0ef41Sopenharmony_ci  __ Bind(&if_smi);
16601cb0ef41Sopenharmony_ci  {
16611cb0ef41Sopenharmony_ci    // If {value} is a Smi, then we only need to check that it's not zero.
16621cb0ef41Sopenharmony_ci    __ Goto(&done, __ Word32Equal(__ TaggedEqual(value, __ SmiConstant(0)),
16631cb0ef41Sopenharmony_ci                                  __ Int32Constant(0)));
16641cb0ef41Sopenharmony_ci  }
16651cb0ef41Sopenharmony_ci
16661cb0ef41Sopenharmony_ci  __ Bind(&done);
16671cb0ef41Sopenharmony_ci  return done.PhiAt(0);
16681cb0ef41Sopenharmony_ci}
16691cb0ef41Sopenharmony_ci
16701cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerTruncateTaggedPointerToBit(Node* node) {
16711cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
16721cb0ef41Sopenharmony_ci
16731cb0ef41Sopenharmony_ci  TruncateTaggedPointerToBit(node, &done);
16741cb0ef41Sopenharmony_ci
16751cb0ef41Sopenharmony_ci  __ Bind(&done);
16761cb0ef41Sopenharmony_ci  return done.PhiAt(0);
16771cb0ef41Sopenharmony_ci}
16781cb0ef41Sopenharmony_ci
16791cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node) {
16801cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
16811cb0ef41Sopenharmony_ci
16821cb0ef41Sopenharmony_ci  auto if_not_smi = __ MakeDeferredLabel();
16831cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kWord32);
16841cb0ef41Sopenharmony_ci
16851cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
16861cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &if_not_smi);
16871cb0ef41Sopenharmony_ci  __ Goto(&done, ChangeSmiToInt32(value));
16881cb0ef41Sopenharmony_ci
16891cb0ef41Sopenharmony_ci  __ Bind(&if_not_smi);
16901cb0ef41Sopenharmony_ci  STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
16911cb0ef41Sopenharmony_ci                                    Oddball::kToNumberRawOffset);
16921cb0ef41Sopenharmony_ci  Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
16931cb0ef41Sopenharmony_ci  vfalse = __ ChangeFloat64ToInt32(vfalse);
16941cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
16951cb0ef41Sopenharmony_ci
16961cb0ef41Sopenharmony_ci  __ Bind(&done);
16971cb0ef41Sopenharmony_ci  return done.PhiAt(0);
16981cb0ef41Sopenharmony_ci}
16991cb0ef41Sopenharmony_ci
17001cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node) {
17011cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
17021cb0ef41Sopenharmony_ci
17031cb0ef41Sopenharmony_ci  auto if_not_smi = __ MakeDeferredLabel();
17041cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kWord32);
17051cb0ef41Sopenharmony_ci
17061cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
17071cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &if_not_smi);
17081cb0ef41Sopenharmony_ci  __ Goto(&done, ChangeSmiToInt32(value));
17091cb0ef41Sopenharmony_ci
17101cb0ef41Sopenharmony_ci  __ Bind(&if_not_smi);
17111cb0ef41Sopenharmony_ci  STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
17121cb0ef41Sopenharmony_ci                                    Oddball::kToNumberRawOffset);
17131cb0ef41Sopenharmony_ci  Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
17141cb0ef41Sopenharmony_ci  vfalse = __ ChangeFloat64ToUint32(vfalse);
17151cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
17161cb0ef41Sopenharmony_ci
17171cb0ef41Sopenharmony_ci  __ Bind(&done);
17181cb0ef41Sopenharmony_ci  return done.PhiAt(0);
17191cb0ef41Sopenharmony_ci}
17201cb0ef41Sopenharmony_ci
17211cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeTaggedToInt64(Node* node) {
17221cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
17231cb0ef41Sopenharmony_ci
17241cb0ef41Sopenharmony_ci  auto if_not_smi = __ MakeDeferredLabel();
17251cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kWord64);
17261cb0ef41Sopenharmony_ci
17271cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
17281cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &if_not_smi);
17291cb0ef41Sopenharmony_ci  __ Goto(&done, ChangeSmiToInt64(value));
17301cb0ef41Sopenharmony_ci
17311cb0ef41Sopenharmony_ci  __ Bind(&if_not_smi);
17321cb0ef41Sopenharmony_ci  STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
17331cb0ef41Sopenharmony_ci                                    Oddball::kToNumberRawOffset);
17341cb0ef41Sopenharmony_ci  Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
17351cb0ef41Sopenharmony_ci  vfalse = __ ChangeFloat64ToInt64(vfalse);
17361cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
17371cb0ef41Sopenharmony_ci
17381cb0ef41Sopenharmony_ci  __ Bind(&done);
17391cb0ef41Sopenharmony_ci  return done.PhiAt(0);
17401cb0ef41Sopenharmony_ci}
17411cb0ef41Sopenharmony_ci
17421cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node) {
17431cb0ef41Sopenharmony_ci  return LowerTruncateTaggedToFloat64(node);
17441cb0ef41Sopenharmony_ci}
17451cb0ef41Sopenharmony_ci
17461cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeTaggedToTaggedSigned(Node* node) {
17471cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
17481cb0ef41Sopenharmony_ci
17491cb0ef41Sopenharmony_ci  auto if_not_smi = __ MakeDeferredLabel();
17501cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kWord32);
17511cb0ef41Sopenharmony_ci
17521cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
17531cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &if_not_smi);
17541cb0ef41Sopenharmony_ci  __ Goto(&done, value);
17551cb0ef41Sopenharmony_ci
17561cb0ef41Sopenharmony_ci  __ Bind(&if_not_smi);
17571cb0ef41Sopenharmony_ci  STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
17581cb0ef41Sopenharmony_ci                                    Oddball::kToNumberRawOffset);
17591cb0ef41Sopenharmony_ci  Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
17601cb0ef41Sopenharmony_ci  vfalse = __ ChangeFloat64ToInt32(vfalse);
17611cb0ef41Sopenharmony_ci  vfalse = ChangeInt32ToSmi(vfalse);
17621cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
17631cb0ef41Sopenharmony_ci
17641cb0ef41Sopenharmony_ci  __ Bind(&done);
17651cb0ef41Sopenharmony_ci  return done.PhiAt(0);
17661cb0ef41Sopenharmony_ci}
17671cb0ef41Sopenharmony_ci
17681cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node) {
17691cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
17701cb0ef41Sopenharmony_ci
17711cb0ef41Sopenharmony_ci  auto if_not_smi = __ MakeDeferredLabel();
17721cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kFloat64);
17731cb0ef41Sopenharmony_ci
17741cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
17751cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &if_not_smi);
17761cb0ef41Sopenharmony_ci  Node* vtrue = ChangeSmiToInt32(value);
17771cb0ef41Sopenharmony_ci  vtrue = __ ChangeInt32ToFloat64(vtrue);
17781cb0ef41Sopenharmony_ci  __ Goto(&done, vtrue);
17791cb0ef41Sopenharmony_ci
17801cb0ef41Sopenharmony_ci  __ Bind(&if_not_smi);
17811cb0ef41Sopenharmony_ci  STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
17821cb0ef41Sopenharmony_ci                                    Oddball::kToNumberRawOffset);
17831cb0ef41Sopenharmony_ci  Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
17841cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
17851cb0ef41Sopenharmony_ci
17861cb0ef41Sopenharmony_ci  __ Bind(&done);
17871cb0ef41Sopenharmony_ci  return done.PhiAt(0);
17881cb0ef41Sopenharmony_ci}
17891cb0ef41Sopenharmony_ci
17901cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckClosure(Node* node,
17911cb0ef41Sopenharmony_ci                                                 Node* frame_state) {
17921cb0ef41Sopenharmony_ci  Handle<FeedbackCell> feedback_cell = FeedbackCellOf(node->op());
17931cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
17941cb0ef41Sopenharmony_ci
17951cb0ef41Sopenharmony_ci  // Check that {value} is actually a JSFunction.
17961cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
17971cb0ef41Sopenharmony_ci  Node* value_instance_type =
17981cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
17991cb0ef41Sopenharmony_ci  Node* check_instance_type = __ Uint32LessThanOrEqual(
18001cb0ef41Sopenharmony_ci      __ Int32Sub(value_instance_type,
18011cb0ef41Sopenharmony_ci                  __ Int32Constant(FIRST_JS_FUNCTION_TYPE)),
18021cb0ef41Sopenharmony_ci      __ Int32Constant(LAST_JS_FUNCTION_TYPE - FIRST_JS_FUNCTION_TYPE));
18031cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kWrongCallTarget, FeedbackSource(),
18041cb0ef41Sopenharmony_ci                     check_instance_type, frame_state);
18051cb0ef41Sopenharmony_ci
18061cb0ef41Sopenharmony_ci  // Check that the {value}s feedback vector cell matches the one
18071cb0ef41Sopenharmony_ci  // we recorded before.
18081cb0ef41Sopenharmony_ci  Node* value_cell =
18091cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForJSFunctionFeedbackCell(), value);
18101cb0ef41Sopenharmony_ci  Node* check_cell = __ WordEqual(value_cell, __ HeapConstant(feedback_cell));
18111cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kWrongFeedbackCell, FeedbackSource(),
18121cb0ef41Sopenharmony_ci                     check_cell, frame_state);
18131cb0ef41Sopenharmony_ci  return value;
18141cb0ef41Sopenharmony_ci}
18151cb0ef41Sopenharmony_ci
18161cb0ef41Sopenharmony_civoid EffectControlLinearizer::MigrateInstanceOrDeopt(
18171cb0ef41Sopenharmony_ci    Node* value, Node* value_map, Node* frame_state,
18181cb0ef41Sopenharmony_ci    FeedbackSource const& feedback_source, DeoptimizeReason reason) {
18191cb0ef41Sopenharmony_ci  // If map is not deprecated the migration attempt does not make sense.
18201cb0ef41Sopenharmony_ci  Node* bitfield3 = __ LoadField(AccessBuilder::ForMapBitField3(), value_map);
18211cb0ef41Sopenharmony_ci  Node* is_not_deprecated = __ Word32Equal(
18221cb0ef41Sopenharmony_ci      __ Word32And(bitfield3,
18231cb0ef41Sopenharmony_ci                   __ Int32Constant(Map::Bits3::IsDeprecatedBit::kMask)),
18241cb0ef41Sopenharmony_ci      __ Int32Constant(0));
18251cb0ef41Sopenharmony_ci  __ DeoptimizeIf(reason, feedback_source, is_not_deprecated, frame_state);
18261cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
18271cb0ef41Sopenharmony_ci  Runtime::FunctionId id = Runtime::kTryMigrateInstance;
18281cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
18291cb0ef41Sopenharmony_ci      graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
18301cb0ef41Sopenharmony_ci  Node* result = __ Call(call_descriptor, __ CEntryStubConstant(1), value,
18311cb0ef41Sopenharmony_ci                         __ ExternalConstant(ExternalReference::Create(id)),
18321cb0ef41Sopenharmony_ci                         __ Int32Constant(1), __ NoContextConstant());
18331cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(result);
18341cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kInstanceMigrationFailed, feedback_source,
18351cb0ef41Sopenharmony_ci                  check, frame_state);
18361cb0ef41Sopenharmony_ci}
18371cb0ef41Sopenharmony_ci
18381cb0ef41Sopenharmony_civoid EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
18391cb0ef41Sopenharmony_ci  CheckMapsParameters const& p = CheckMapsParametersOf(node->op());
18401cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
18411cb0ef41Sopenharmony_ci
18421cb0ef41Sopenharmony_ci  ZoneHandleSet<Map> const& maps = p.maps();
18431cb0ef41Sopenharmony_ci  size_t const map_count = maps.size();
18441cb0ef41Sopenharmony_ci
18451cb0ef41Sopenharmony_ci  if (p.flags() & CheckMapsFlag::kTryMigrateInstance) {
18461cb0ef41Sopenharmony_ci    auto done = __ MakeLabel();
18471cb0ef41Sopenharmony_ci    auto migrate = __ MakeDeferredLabel();
18481cb0ef41Sopenharmony_ci
18491cb0ef41Sopenharmony_ci    // Load the current map of the {value}.
18501cb0ef41Sopenharmony_ci    Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
18511cb0ef41Sopenharmony_ci
18521cb0ef41Sopenharmony_ci    // Perform the map checks.
18531cb0ef41Sopenharmony_ci    for (size_t i = 0; i < map_count; ++i) {
18541cb0ef41Sopenharmony_ci      Node* map = __ HeapConstant(maps[i]);
18551cb0ef41Sopenharmony_ci      Node* check = __ TaggedEqual(value_map, map);
18561cb0ef41Sopenharmony_ci      if (i == map_count - 1) {
18571cb0ef41Sopenharmony_ci        __ BranchWithCriticalSafetyCheck(check, &done, &migrate);
18581cb0ef41Sopenharmony_ci      } else {
18591cb0ef41Sopenharmony_ci        auto next_map = __ MakeLabel();
18601cb0ef41Sopenharmony_ci        __ BranchWithCriticalSafetyCheck(check, &done, &next_map);
18611cb0ef41Sopenharmony_ci        __ Bind(&next_map);
18621cb0ef41Sopenharmony_ci      }
18631cb0ef41Sopenharmony_ci    }
18641cb0ef41Sopenharmony_ci
18651cb0ef41Sopenharmony_ci    // Perform the (deferred) instance migration.
18661cb0ef41Sopenharmony_ci    __ Bind(&migrate);
18671cb0ef41Sopenharmony_ci    MigrateInstanceOrDeopt(value, value_map, frame_state, p.feedback(),
18681cb0ef41Sopenharmony_ci                           DeoptimizeReason::kWrongMap);
18691cb0ef41Sopenharmony_ci
18701cb0ef41Sopenharmony_ci    // Reload the current map of the {value}.
18711cb0ef41Sopenharmony_ci    value_map = __ LoadField(AccessBuilder::ForMap(), value);
18721cb0ef41Sopenharmony_ci
18731cb0ef41Sopenharmony_ci    // Perform the map checks again.
18741cb0ef41Sopenharmony_ci    for (size_t i = 0; i < map_count; ++i) {
18751cb0ef41Sopenharmony_ci      Node* map = __ HeapConstant(maps[i]);
18761cb0ef41Sopenharmony_ci      Node* check = __ TaggedEqual(value_map, map);
18771cb0ef41Sopenharmony_ci      if (i == map_count - 1) {
18781cb0ef41Sopenharmony_ci        __ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, p.feedback(), check,
18791cb0ef41Sopenharmony_ci                           frame_state);
18801cb0ef41Sopenharmony_ci      } else {
18811cb0ef41Sopenharmony_ci        auto next_map = __ MakeLabel();
18821cb0ef41Sopenharmony_ci        __ BranchWithCriticalSafetyCheck(check, &done, &next_map);
18831cb0ef41Sopenharmony_ci        __ Bind(&next_map);
18841cb0ef41Sopenharmony_ci      }
18851cb0ef41Sopenharmony_ci    }
18861cb0ef41Sopenharmony_ci
18871cb0ef41Sopenharmony_ci    __ Goto(&done);
18881cb0ef41Sopenharmony_ci    __ Bind(&done);
18891cb0ef41Sopenharmony_ci  } else {
18901cb0ef41Sopenharmony_ci    auto done = __ MakeLabel();
18911cb0ef41Sopenharmony_ci
18921cb0ef41Sopenharmony_ci    // Load the current map of the {value}.
18931cb0ef41Sopenharmony_ci    Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
18941cb0ef41Sopenharmony_ci
18951cb0ef41Sopenharmony_ci    for (size_t i = 0; i < map_count; ++i) {
18961cb0ef41Sopenharmony_ci      Node* map = __ HeapConstant(maps[i]);
18971cb0ef41Sopenharmony_ci      Node* check = __ TaggedEqual(value_map, map);
18981cb0ef41Sopenharmony_ci
18991cb0ef41Sopenharmony_ci      if (i == map_count - 1) {
19001cb0ef41Sopenharmony_ci        __ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, p.feedback(), check,
19011cb0ef41Sopenharmony_ci                           frame_state);
19021cb0ef41Sopenharmony_ci      } else {
19031cb0ef41Sopenharmony_ci        auto next_map = __ MakeLabel();
19041cb0ef41Sopenharmony_ci        __ BranchWithCriticalSafetyCheck(check, &done, &next_map);
19051cb0ef41Sopenharmony_ci        __ Bind(&next_map);
19061cb0ef41Sopenharmony_ci      }
19071cb0ef41Sopenharmony_ci    }
19081cb0ef41Sopenharmony_ci    __ Goto(&done);
19091cb0ef41Sopenharmony_ci    __ Bind(&done);
19101cb0ef41Sopenharmony_ci  }
19111cb0ef41Sopenharmony_ci}
19121cb0ef41Sopenharmony_ci
19131cb0ef41Sopenharmony_civoid EffectControlLinearizer::TryMigrateInstance(Node* value, Node* value_map) {
19141cb0ef41Sopenharmony_ci  auto done = __ MakeLabel();
19151cb0ef41Sopenharmony_ci  // If map is not deprecated the migration attempt does not make sense.
19161cb0ef41Sopenharmony_ci  Node* bitfield3 = __ LoadField(AccessBuilder::ForMapBitField3(), value_map);
19171cb0ef41Sopenharmony_ci  Node* is_not_deprecated = __ Word32Equal(
19181cb0ef41Sopenharmony_ci      __ Word32And(bitfield3,
19191cb0ef41Sopenharmony_ci                   __ Int32Constant(Map::Bits3::IsDeprecatedBit::kMask)),
19201cb0ef41Sopenharmony_ci      __ Int32Constant(0));
19211cb0ef41Sopenharmony_ci  __ GotoIf(is_not_deprecated, &done);
19221cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
19231cb0ef41Sopenharmony_ci  Runtime::FunctionId id = Runtime::kTryMigrateInstance;
19241cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
19251cb0ef41Sopenharmony_ci      graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
19261cb0ef41Sopenharmony_ci  __ Call(call_descriptor, __ CEntryStubConstant(1), value,
19271cb0ef41Sopenharmony_ci          __ ExternalConstant(ExternalReference::Create(id)),
19281cb0ef41Sopenharmony_ci          __ Int32Constant(1), __ NoContextConstant());
19291cb0ef41Sopenharmony_ci  __ Goto(&done);
19301cb0ef41Sopenharmony_ci  __ Bind(&done);
19311cb0ef41Sopenharmony_ci}
19321cb0ef41Sopenharmony_ci
19331cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCompareMaps(Node* node) {
19341cb0ef41Sopenharmony_ci  ZoneHandleSet<Map> const& maps = CompareMapsParametersOf(node->op());
19351cb0ef41Sopenharmony_ci  size_t const map_count = maps.size();
19361cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
19371cb0ef41Sopenharmony_ci
19381cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
19391cb0ef41Sopenharmony_ci
19401cb0ef41Sopenharmony_ci  // Load the current map of the {value}.
19411cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
19421cb0ef41Sopenharmony_ci
19431cb0ef41Sopenharmony_ci  for (size_t i = 0; i < map_count; ++i) {
19441cb0ef41Sopenharmony_ci    Node* map = __ HeapConstant(maps[i]);
19451cb0ef41Sopenharmony_ci    Node* check = __ TaggedEqual(value_map, map);
19461cb0ef41Sopenharmony_ci
19471cb0ef41Sopenharmony_ci    auto next_map = __ MakeLabel();
19481cb0ef41Sopenharmony_ci    auto passed = __ MakeLabel();
19491cb0ef41Sopenharmony_ci    __ BranchWithCriticalSafetyCheck(check, &passed, &next_map);
19501cb0ef41Sopenharmony_ci
19511cb0ef41Sopenharmony_ci    __ Bind(&passed);
19521cb0ef41Sopenharmony_ci    __ Goto(&done, __ Int32Constant(1));
19531cb0ef41Sopenharmony_ci
19541cb0ef41Sopenharmony_ci    __ Bind(&next_map);
19551cb0ef41Sopenharmony_ci  }
19561cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int32Constant(0));
19571cb0ef41Sopenharmony_ci
19581cb0ef41Sopenharmony_ci  __ Bind(&done);
19591cb0ef41Sopenharmony_ci  return done.PhiAt(0);
19601cb0ef41Sopenharmony_ci}
19611cb0ef41Sopenharmony_ci
19621cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckNumber(Node* node, Node* frame_state) {
19631cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
19641cb0ef41Sopenharmony_ci  const CheckParameters& params = CheckParametersOf(node->op());
19651cb0ef41Sopenharmony_ci
19661cb0ef41Sopenharmony_ci  auto if_not_smi = __ MakeDeferredLabel();
19671cb0ef41Sopenharmony_ci  auto done = __ MakeLabel();
19681cb0ef41Sopenharmony_ci
19691cb0ef41Sopenharmony_ci  Node* check0 = ObjectIsSmi(value);
19701cb0ef41Sopenharmony_ci  __ GotoIfNot(check0, &if_not_smi);
19711cb0ef41Sopenharmony_ci  __ Goto(&done);
19721cb0ef41Sopenharmony_ci
19731cb0ef41Sopenharmony_ci  __ Bind(&if_not_smi);
19741cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
19751cb0ef41Sopenharmony_ci  Node* check1 = __ TaggedEqual(value_map, __ HeapNumberMapConstant());
19761cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, params.feedback(),
19771cb0ef41Sopenharmony_ci                     check1, frame_state);
19781cb0ef41Sopenharmony_ci  __ Goto(&done);
19791cb0ef41Sopenharmony_ci
19801cb0ef41Sopenharmony_ci  __ Bind(&done);
19811cb0ef41Sopenharmony_ci  return value;
19821cb0ef41Sopenharmony_ci}
19831cb0ef41Sopenharmony_ci
19841cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckReceiver(Node* node,
19851cb0ef41Sopenharmony_ci                                                  Node* frame_state) {
19861cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
19871cb0ef41Sopenharmony_ci
19881cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
19891cb0ef41Sopenharmony_ci  Node* value_instance_type =
19901cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
19911cb0ef41Sopenharmony_ci
19921cb0ef41Sopenharmony_ci  STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
19931cb0ef41Sopenharmony_ci  Node* check = __ Uint32LessThanOrEqual(
19941cb0ef41Sopenharmony_ci      __ Uint32Constant(FIRST_JS_RECEIVER_TYPE), value_instance_type);
19951cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kNotAJavaScriptObject, FeedbackSource(),
19961cb0ef41Sopenharmony_ci                     check, frame_state);
19971cb0ef41Sopenharmony_ci  return value;
19981cb0ef41Sopenharmony_ci}
19991cb0ef41Sopenharmony_ci
20001cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckReceiverOrNullOrUndefined(
20011cb0ef41Sopenharmony_ci    Node* node, Node* frame_state) {
20021cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
20031cb0ef41Sopenharmony_ci
20041cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
20051cb0ef41Sopenharmony_ci  Node* value_instance_type =
20061cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
20071cb0ef41Sopenharmony_ci
20081cb0ef41Sopenharmony_ci  // Rule out all primitives except oddballs (true, false, undefined, null).
20091cb0ef41Sopenharmony_ci  STATIC_ASSERT(LAST_PRIMITIVE_HEAP_OBJECT_TYPE == ODDBALL_TYPE);
20101cb0ef41Sopenharmony_ci  STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
20111cb0ef41Sopenharmony_ci  Node* check0 = __ Uint32LessThanOrEqual(__ Uint32Constant(ODDBALL_TYPE),
20121cb0ef41Sopenharmony_ci                                          value_instance_type);
20131cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kNotAJavaScriptObjectOrNullOrUndefined,
20141cb0ef41Sopenharmony_ci                     FeedbackSource(), check0, frame_state);
20151cb0ef41Sopenharmony_ci
20161cb0ef41Sopenharmony_ci  // Rule out booleans.
20171cb0ef41Sopenharmony_ci  Node* check1 = __ TaggedEqual(value_map, __ BooleanMapConstant());
20181cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kNotAJavaScriptObjectOrNullOrUndefined,
20191cb0ef41Sopenharmony_ci                  FeedbackSource(), check1, frame_state);
20201cb0ef41Sopenharmony_ci  return value;
20211cb0ef41Sopenharmony_ci}
20221cb0ef41Sopenharmony_ci
20231cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckSymbol(Node* node, Node* frame_state) {
20241cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
20251cb0ef41Sopenharmony_ci
20261cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
20271cb0ef41Sopenharmony_ci
20281cb0ef41Sopenharmony_ci  Node* check =
20291cb0ef41Sopenharmony_ci      __ TaggedEqual(value_map, __ HeapConstant(factory()->symbol_map()));
20301cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kNotASymbol, FeedbackSource(), check,
20311cb0ef41Sopenharmony_ci                     frame_state);
20321cb0ef41Sopenharmony_ci  return value;
20331cb0ef41Sopenharmony_ci}
20341cb0ef41Sopenharmony_ci
20351cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckString(Node* node, Node* frame_state) {
20361cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
20371cb0ef41Sopenharmony_ci  const CheckParameters& params = CheckParametersOf(node->op());
20381cb0ef41Sopenharmony_ci
20391cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
20401cb0ef41Sopenharmony_ci  Node* value_instance_type =
20411cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
20421cb0ef41Sopenharmony_ci
20431cb0ef41Sopenharmony_ci  Node* check = __ Uint32LessThan(value_instance_type,
20441cb0ef41Sopenharmony_ci                                  __ Uint32Constant(FIRST_NONSTRING_TYPE));
20451cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kNotAString, params.feedback(), check,
20461cb0ef41Sopenharmony_ci                     frame_state);
20471cb0ef41Sopenharmony_ci  return value;
20481cb0ef41Sopenharmony_ci}
20491cb0ef41Sopenharmony_ci
20501cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckInternalizedString(Node* node,
20511cb0ef41Sopenharmony_ci                                                            Node* frame_state) {
20521cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
20531cb0ef41Sopenharmony_ci
20541cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
20551cb0ef41Sopenharmony_ci  Node* value_instance_type =
20561cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
20571cb0ef41Sopenharmony_ci
20581cb0ef41Sopenharmony_ci  Node* check = __ Word32Equal(
20591cb0ef41Sopenharmony_ci      __ Word32And(value_instance_type,
20601cb0ef41Sopenharmony_ci                   __ Int32Constant(kIsNotStringMask | kIsNotInternalizedMask)),
20611cb0ef41Sopenharmony_ci      __ Int32Constant(kInternalizedTag));
20621cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kWrongInstanceType, FeedbackSource(),
20631cb0ef41Sopenharmony_ci                     check, frame_state);
20641cb0ef41Sopenharmony_ci
20651cb0ef41Sopenharmony_ci  return value;
20661cb0ef41Sopenharmony_ci}
20671cb0ef41Sopenharmony_ci
20681cb0ef41Sopenharmony_civoid EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state) {
20691cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
20701cb0ef41Sopenharmony_ci  const CheckIfParameters& p = CheckIfParametersOf(node->op());
20711cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(p.reason(), p.feedback(), value, frame_state);
20721cb0ef41Sopenharmony_ci}
20731cb0ef41Sopenharmony_ci
20741cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringConcat(Node* node) {
20751cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(1);
20761cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(2);
20771cb0ef41Sopenharmony_ci
20781cb0ef41Sopenharmony_ci  Callable const callable =
20791cb0ef41Sopenharmony_ci      CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE);
20801cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
20811cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
20821cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags,
20831cb0ef41Sopenharmony_ci      Operator::kNoDeopt | Operator::kNoWrite | Operator::kNoThrow);
20841cb0ef41Sopenharmony_ci
20851cb0ef41Sopenharmony_ci  Node* value = __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs,
20861cb0ef41Sopenharmony_ci                        rhs, __ NoContextConstant());
20871cb0ef41Sopenharmony_ci
20881cb0ef41Sopenharmony_ci  return value;
20891cb0ef41Sopenharmony_ci}
20901cb0ef41Sopenharmony_ci
20911cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedInt32Add(Node* node,
20921cb0ef41Sopenharmony_ci                                                    Node* frame_state) {
20931cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(0);
20941cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(1);
20951cb0ef41Sopenharmony_ci
20961cb0ef41Sopenharmony_ci  Node* value = __ Int32AddWithOverflow(lhs, rhs);
20971cb0ef41Sopenharmony_ci  Node* check = __ Projection(1, value);
20981cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kOverflow, FeedbackSource(), check,
20991cb0ef41Sopenharmony_ci                  frame_state);
21001cb0ef41Sopenharmony_ci  return __ Projection(0, value);
21011cb0ef41Sopenharmony_ci}
21021cb0ef41Sopenharmony_ci
21031cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedInt32Sub(Node* node,
21041cb0ef41Sopenharmony_ci                                                    Node* frame_state) {
21051cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(0);
21061cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(1);
21071cb0ef41Sopenharmony_ci
21081cb0ef41Sopenharmony_ci  Node* value = __ Int32SubWithOverflow(lhs, rhs);
21091cb0ef41Sopenharmony_ci  Node* check = __ Projection(1, value);
21101cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kOverflow, FeedbackSource(), check,
21111cb0ef41Sopenharmony_ci                  frame_state);
21121cb0ef41Sopenharmony_ci  return __ Projection(0, value);
21131cb0ef41Sopenharmony_ci}
21141cb0ef41Sopenharmony_ci
21151cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedInt32Div(Node* node,
21161cb0ef41Sopenharmony_ci                                                    Node* frame_state) {
21171cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(0);
21181cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(1);
21191cb0ef41Sopenharmony_ci  Node* zero = __ Int32Constant(0);
21201cb0ef41Sopenharmony_ci
21211cb0ef41Sopenharmony_ci  // Check if the {rhs} is a known power of two.
21221cb0ef41Sopenharmony_ci  Int32Matcher m(rhs);
21231cb0ef41Sopenharmony_ci  if (m.IsPowerOf2()) {
21241cb0ef41Sopenharmony_ci    // Since we know that {rhs} is a power of two, we can perform a fast
21251cb0ef41Sopenharmony_ci    // check to see if the relevant least significant bits of the {lhs}
21261cb0ef41Sopenharmony_ci    // are all zero, and if so we know that we can perform a division
21271cb0ef41Sopenharmony_ci    // safely (and fast by doing an arithmetic - aka sign preserving -
21281cb0ef41Sopenharmony_ci    // right shift on {lhs}).
21291cb0ef41Sopenharmony_ci    int32_t divisor = m.ResolvedValue();
21301cb0ef41Sopenharmony_ci    Node* mask = __ Int32Constant(divisor - 1);
21311cb0ef41Sopenharmony_ci    Node* shift = __ Int32Constant(base::bits::WhichPowerOfTwo(divisor));
21321cb0ef41Sopenharmony_ci    Node* check = __ Word32Equal(__ Word32And(lhs, mask), zero);
21331cb0ef41Sopenharmony_ci    __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, FeedbackSource(),
21341cb0ef41Sopenharmony_ci                       check, frame_state);
21351cb0ef41Sopenharmony_ci    return __ Word32Sar(lhs, shift);
21361cb0ef41Sopenharmony_ci  } else {
21371cb0ef41Sopenharmony_ci    auto if_rhs_positive = __ MakeLabel();
21381cb0ef41Sopenharmony_ci    auto if_rhs_negative = __ MakeDeferredLabel();
21391cb0ef41Sopenharmony_ci    auto done = __ MakeLabel(MachineRepresentation::kWord32);
21401cb0ef41Sopenharmony_ci
21411cb0ef41Sopenharmony_ci    // Check if {rhs} is positive (and not zero).
21421cb0ef41Sopenharmony_ci    Node* check_rhs_positive = __ Int32LessThan(zero, rhs);
21431cb0ef41Sopenharmony_ci    __ Branch(check_rhs_positive, &if_rhs_positive, &if_rhs_negative);
21441cb0ef41Sopenharmony_ci
21451cb0ef41Sopenharmony_ci    __ Bind(&if_rhs_positive);
21461cb0ef41Sopenharmony_ci    {
21471cb0ef41Sopenharmony_ci      // Fast case, no additional checking required.
21481cb0ef41Sopenharmony_ci      __ Goto(&done, __ Int32Div(lhs, rhs));
21491cb0ef41Sopenharmony_ci    }
21501cb0ef41Sopenharmony_ci
21511cb0ef41Sopenharmony_ci    __ Bind(&if_rhs_negative);
21521cb0ef41Sopenharmony_ci    {
21531cb0ef41Sopenharmony_ci      auto if_lhs_minint = __ MakeDeferredLabel();
21541cb0ef41Sopenharmony_ci      auto if_lhs_notminint = __ MakeLabel();
21551cb0ef41Sopenharmony_ci
21561cb0ef41Sopenharmony_ci      // Check if {rhs} is zero.
21571cb0ef41Sopenharmony_ci      Node* check_rhs_zero = __ Word32Equal(rhs, zero);
21581cb0ef41Sopenharmony_ci      __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, FeedbackSource(),
21591cb0ef41Sopenharmony_ci                      check_rhs_zero, frame_state);
21601cb0ef41Sopenharmony_ci
21611cb0ef41Sopenharmony_ci      // Check if {lhs} is zero, as that would produce minus zero.
21621cb0ef41Sopenharmony_ci      Node* check_lhs_zero = __ Word32Equal(lhs, zero);
21631cb0ef41Sopenharmony_ci      __ DeoptimizeIf(DeoptimizeReason::kMinusZero, FeedbackSource(),
21641cb0ef41Sopenharmony_ci                      check_lhs_zero, frame_state);
21651cb0ef41Sopenharmony_ci
21661cb0ef41Sopenharmony_ci      // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have
21671cb0ef41Sopenharmony_ci      // to return -kMinInt, which is not representable as Word32.
21681cb0ef41Sopenharmony_ci      Node* check_lhs_minint = __ Word32Equal(lhs, __ Int32Constant(kMinInt));
21691cb0ef41Sopenharmony_ci      __ Branch(check_lhs_minint, &if_lhs_minint, &if_lhs_notminint);
21701cb0ef41Sopenharmony_ci
21711cb0ef41Sopenharmony_ci      __ Bind(&if_lhs_minint);
21721cb0ef41Sopenharmony_ci      {
21731cb0ef41Sopenharmony_ci        // Check that {rhs} is not -1, otherwise result would be -kMinInt.
21741cb0ef41Sopenharmony_ci        Node* check_rhs_minusone = __ Word32Equal(rhs, __ Int32Constant(-1));
21751cb0ef41Sopenharmony_ci        __ DeoptimizeIf(DeoptimizeReason::kOverflow, FeedbackSource(),
21761cb0ef41Sopenharmony_ci                        check_rhs_minusone, frame_state);
21771cb0ef41Sopenharmony_ci
21781cb0ef41Sopenharmony_ci        // Perform the actual integer division.
21791cb0ef41Sopenharmony_ci        __ Goto(&done, __ Int32Div(lhs, rhs));
21801cb0ef41Sopenharmony_ci      }
21811cb0ef41Sopenharmony_ci
21821cb0ef41Sopenharmony_ci      __ Bind(&if_lhs_notminint);
21831cb0ef41Sopenharmony_ci      {
21841cb0ef41Sopenharmony_ci        // Perform the actual integer division.
21851cb0ef41Sopenharmony_ci        __ Goto(&done, __ Int32Div(lhs, rhs));
21861cb0ef41Sopenharmony_ci      }
21871cb0ef41Sopenharmony_ci    }
21881cb0ef41Sopenharmony_ci
21891cb0ef41Sopenharmony_ci    __ Bind(&done);
21901cb0ef41Sopenharmony_ci    Node* value = done.PhiAt(0);
21911cb0ef41Sopenharmony_ci
21921cb0ef41Sopenharmony_ci    // Check if the remainder is non-zero.
21931cb0ef41Sopenharmony_ci    Node* check = __ Word32Equal(lhs, __ Int32Mul(value, rhs));
21941cb0ef41Sopenharmony_ci    __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, FeedbackSource(),
21951cb0ef41Sopenharmony_ci                       check, frame_state);
21961cb0ef41Sopenharmony_ci
21971cb0ef41Sopenharmony_ci    return value;
21981cb0ef41Sopenharmony_ci  }
21991cb0ef41Sopenharmony_ci}
22001cb0ef41Sopenharmony_ci
22011cb0ef41Sopenharmony_citemplate <size_t VarCount, size_t VarCount2>
22021cb0ef41Sopenharmony_civoid EffectControlLinearizer::SmiTagOrOverflow(
22031cb0ef41Sopenharmony_ci    Node* value, GraphAssemblerLabel<VarCount>* if_overflow,
22041cb0ef41Sopenharmony_ci    GraphAssemblerLabel<VarCount2>* done) {
22051cb0ef41Sopenharmony_ci  DCHECK(SmiValuesAre31Bits());
22061cb0ef41Sopenharmony_ci  // Check for overflow at the same time that we are smi tagging.
22071cb0ef41Sopenharmony_ci  // Since smi tagging shifts left by one, it's the same as adding value twice.
22081cb0ef41Sopenharmony_ci  Node* add = __ Int32AddWithOverflow(value, value);
22091cb0ef41Sopenharmony_ci  Node* ovf = __ Projection(1, add);
22101cb0ef41Sopenharmony_ci  __ GotoIf(ovf, if_overflow);
22111cb0ef41Sopenharmony_ci  Node* value_smi = __ Projection(0, add);
22121cb0ef41Sopenharmony_ci  value_smi = ChangeTaggedInt32ToSmi(value_smi);
22131cb0ef41Sopenharmony_ci  __ Goto(done, value_smi);
22141cb0ef41Sopenharmony_ci}
22151cb0ef41Sopenharmony_ci
22161cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::SmiTagOrDeopt(Node* value,
22171cb0ef41Sopenharmony_ci                                             const CheckParameters& params,
22181cb0ef41Sopenharmony_ci                                             Node* frame_state) {
22191cb0ef41Sopenharmony_ci  DCHECK(SmiValuesAre31Bits());
22201cb0ef41Sopenharmony_ci  // Check for the lost precision at the same time that we are smi tagging.
22211cb0ef41Sopenharmony_ci  // Since smi tagging shifts left by one, it's the same as adding value twice.
22221cb0ef41Sopenharmony_ci  Node* add = __ Int32AddWithOverflow(value, value);
22231cb0ef41Sopenharmony_ci  Node* check = __ Projection(1, add);
22241cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kLostPrecision, params.feedback(), check,
22251cb0ef41Sopenharmony_ci                  frame_state);
22261cb0ef41Sopenharmony_ci  Node* result = __ Projection(0, add);
22271cb0ef41Sopenharmony_ci  return ChangeTaggedInt32ToSmi(result);
22281cb0ef41Sopenharmony_ci}
22291cb0ef41Sopenharmony_ci
22301cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildUint32Mod(Node* lhs, Node* rhs) {
22311cb0ef41Sopenharmony_ci  auto if_rhs_power_of_two = __ MakeLabel();
22321cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kWord32);
22331cb0ef41Sopenharmony_ci
22341cb0ef41Sopenharmony_ci  // Compute the mask for the {rhs}.
22351cb0ef41Sopenharmony_ci  Node* one = __ Int32Constant(1);
22361cb0ef41Sopenharmony_ci  Node* msk = __ Int32Sub(rhs, one);
22371cb0ef41Sopenharmony_ci
22381cb0ef41Sopenharmony_ci  // Check if the {rhs} is a power of two.
22391cb0ef41Sopenharmony_ci  __ GotoIf(__ Word32Equal(__ Word32And(rhs, msk), __ Int32Constant(0)),
22401cb0ef41Sopenharmony_ci            &if_rhs_power_of_two);
22411cb0ef41Sopenharmony_ci  {
22421cb0ef41Sopenharmony_ci    // The {rhs} is not a power of two, do a generic Uint32Mod.
22431cb0ef41Sopenharmony_ci    __ Goto(&done, __ Uint32Mod(lhs, rhs));
22441cb0ef41Sopenharmony_ci  }
22451cb0ef41Sopenharmony_ci
22461cb0ef41Sopenharmony_ci  __ Bind(&if_rhs_power_of_two);
22471cb0ef41Sopenharmony_ci  {
22481cb0ef41Sopenharmony_ci    // The {rhs} is a power of two, just do a fast bit masking.
22491cb0ef41Sopenharmony_ci    __ Goto(&done, __ Word32And(lhs, msk));
22501cb0ef41Sopenharmony_ci  }
22511cb0ef41Sopenharmony_ci
22521cb0ef41Sopenharmony_ci  __ Bind(&done);
22531cb0ef41Sopenharmony_ci  return done.PhiAt(0);
22541cb0ef41Sopenharmony_ci}
22551cb0ef41Sopenharmony_ci
22561cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedInt32Mod(Node* node,
22571cb0ef41Sopenharmony_ci                                                    Node* frame_state) {
22581cb0ef41Sopenharmony_ci  // General case for signed integer modulus, with optimization for (unknown)
22591cb0ef41Sopenharmony_ci  // power of 2 right hand side.
22601cb0ef41Sopenharmony_ci  //
22611cb0ef41Sopenharmony_ci  //   if rhs <= 0 then
22621cb0ef41Sopenharmony_ci  //     rhs = -rhs
22631cb0ef41Sopenharmony_ci  //     deopt if rhs == 0
22641cb0ef41Sopenharmony_ci  //   let msk = rhs - 1 in
22651cb0ef41Sopenharmony_ci  //   if lhs < 0 then
22661cb0ef41Sopenharmony_ci  //     let lhs_abs = -lsh in
22671cb0ef41Sopenharmony_ci  //     let res = if rhs & msk == 0 then
22681cb0ef41Sopenharmony_ci  //                 lhs_abs & msk
22691cb0ef41Sopenharmony_ci  //               else
22701cb0ef41Sopenharmony_ci  //                 lhs_abs % rhs in
22711cb0ef41Sopenharmony_ci  //     if lhs < 0 then
22721cb0ef41Sopenharmony_ci  //       deopt if res == 0
22731cb0ef41Sopenharmony_ci  //       -res
22741cb0ef41Sopenharmony_ci  //     else
22751cb0ef41Sopenharmony_ci  //       res
22761cb0ef41Sopenharmony_ci  //   else
22771cb0ef41Sopenharmony_ci  //     if rhs & msk == 0 then
22781cb0ef41Sopenharmony_ci  //       lhs & msk
22791cb0ef41Sopenharmony_ci  //     else
22801cb0ef41Sopenharmony_ci  //       lhs % rhs
22811cb0ef41Sopenharmony_ci  //
22821cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(0);
22831cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(1);
22841cb0ef41Sopenharmony_ci
22851cb0ef41Sopenharmony_ci  auto if_rhs_not_positive = __ MakeDeferredLabel();
22861cb0ef41Sopenharmony_ci  auto if_lhs_negative = __ MakeDeferredLabel();
22871cb0ef41Sopenharmony_ci  auto if_rhs_power_of_two = __ MakeLabel();
22881cb0ef41Sopenharmony_ci  auto rhs_checked = __ MakeLabel(MachineRepresentation::kWord32);
22891cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kWord32);
22901cb0ef41Sopenharmony_ci
22911cb0ef41Sopenharmony_ci  Node* zero = __ Int32Constant(0);
22921cb0ef41Sopenharmony_ci
22931cb0ef41Sopenharmony_ci  // Check if {rhs} is not strictly positive.
22941cb0ef41Sopenharmony_ci  Node* check0 = __ Int32LessThanOrEqual(rhs, zero);
22951cb0ef41Sopenharmony_ci  __ GotoIf(check0, &if_rhs_not_positive);
22961cb0ef41Sopenharmony_ci  __ Goto(&rhs_checked, rhs);
22971cb0ef41Sopenharmony_ci
22981cb0ef41Sopenharmony_ci  __ Bind(&if_rhs_not_positive);
22991cb0ef41Sopenharmony_ci  {
23001cb0ef41Sopenharmony_ci    // Negate {rhs}, might still produce a negative result in case of
23011cb0ef41Sopenharmony_ci    // -2^31, but that is handled safely below.
23021cb0ef41Sopenharmony_ci    Node* vtrue0 = __ Int32Sub(zero, rhs);
23031cb0ef41Sopenharmony_ci
23041cb0ef41Sopenharmony_ci    // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
23051cb0ef41Sopenharmony_ci    __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, FeedbackSource(),
23061cb0ef41Sopenharmony_ci                    __ Word32Equal(vtrue0, zero), frame_state);
23071cb0ef41Sopenharmony_ci    __ Goto(&rhs_checked, vtrue0);
23081cb0ef41Sopenharmony_ci  }
23091cb0ef41Sopenharmony_ci
23101cb0ef41Sopenharmony_ci  __ Bind(&rhs_checked);
23111cb0ef41Sopenharmony_ci  rhs = rhs_checked.PhiAt(0);
23121cb0ef41Sopenharmony_ci
23131cb0ef41Sopenharmony_ci  __ GotoIf(__ Int32LessThan(lhs, zero), &if_lhs_negative);
23141cb0ef41Sopenharmony_ci  {
23151cb0ef41Sopenharmony_ci    // The {lhs} is a non-negative integer.
23161cb0ef41Sopenharmony_ci    __ Goto(&done, BuildUint32Mod(lhs, rhs));
23171cb0ef41Sopenharmony_ci  }
23181cb0ef41Sopenharmony_ci
23191cb0ef41Sopenharmony_ci  __ Bind(&if_lhs_negative);
23201cb0ef41Sopenharmony_ci  {
23211cb0ef41Sopenharmony_ci    // The {lhs} is a negative integer. This is very unlikely and
23221cb0ef41Sopenharmony_ci    // we intentionally don't use the BuildUint32Mod() here, which
23231cb0ef41Sopenharmony_ci    // would try to figure out whether {rhs} is a power of two,
23241cb0ef41Sopenharmony_ci    // since this is intended to be a slow-path.
23251cb0ef41Sopenharmony_ci    Node* res = __ Uint32Mod(__ Int32Sub(zero, lhs), rhs);
23261cb0ef41Sopenharmony_ci
23271cb0ef41Sopenharmony_ci    // Check if we would have to return -0.
23281cb0ef41Sopenharmony_ci    __ DeoptimizeIf(DeoptimizeReason::kMinusZero, FeedbackSource(),
23291cb0ef41Sopenharmony_ci                    __ Word32Equal(res, zero), frame_state);
23301cb0ef41Sopenharmony_ci    __ Goto(&done, __ Int32Sub(zero, res));
23311cb0ef41Sopenharmony_ci  }
23321cb0ef41Sopenharmony_ci
23331cb0ef41Sopenharmony_ci  __ Bind(&done);
23341cb0ef41Sopenharmony_ci  return done.PhiAt(0);
23351cb0ef41Sopenharmony_ci}
23361cb0ef41Sopenharmony_ci
23371cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedUint32Div(Node* node,
23381cb0ef41Sopenharmony_ci                                                     Node* frame_state) {
23391cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(0);
23401cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(1);
23411cb0ef41Sopenharmony_ci  Node* zero = __ Int32Constant(0);
23421cb0ef41Sopenharmony_ci
23431cb0ef41Sopenharmony_ci  // Check if the {rhs} is a known power of two.
23441cb0ef41Sopenharmony_ci  Uint32Matcher m(rhs);
23451cb0ef41Sopenharmony_ci  if (m.IsPowerOf2()) {
23461cb0ef41Sopenharmony_ci    // Since we know that {rhs} is a power of two, we can perform a fast
23471cb0ef41Sopenharmony_ci    // check to see if the relevant least significant bits of the {lhs}
23481cb0ef41Sopenharmony_ci    // are all zero, and if so we know that we can perform a division
23491cb0ef41Sopenharmony_ci    // safely (and fast by doing a logical - aka zero extending - right
23501cb0ef41Sopenharmony_ci    // shift on {lhs}).
23511cb0ef41Sopenharmony_ci    uint32_t divisor = m.ResolvedValue();
23521cb0ef41Sopenharmony_ci    Node* mask = __ Uint32Constant(divisor - 1);
23531cb0ef41Sopenharmony_ci    Node* shift = __ Uint32Constant(base::bits::WhichPowerOfTwo(divisor));
23541cb0ef41Sopenharmony_ci    Node* check = __ Word32Equal(__ Word32And(lhs, mask), zero);
23551cb0ef41Sopenharmony_ci    __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, FeedbackSource(),
23561cb0ef41Sopenharmony_ci                       check, frame_state);
23571cb0ef41Sopenharmony_ci    return __ Word32Shr(lhs, shift);
23581cb0ef41Sopenharmony_ci  } else {
23591cb0ef41Sopenharmony_ci    // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
23601cb0ef41Sopenharmony_ci    Node* check = __ Word32Equal(rhs, zero);
23611cb0ef41Sopenharmony_ci    __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, FeedbackSource(), check,
23621cb0ef41Sopenharmony_ci                    frame_state);
23631cb0ef41Sopenharmony_ci
23641cb0ef41Sopenharmony_ci    // Perform the actual unsigned integer division.
23651cb0ef41Sopenharmony_ci    Node* value = __ Uint32Div(lhs, rhs);
23661cb0ef41Sopenharmony_ci
23671cb0ef41Sopenharmony_ci    // Check if the remainder is non-zero.
23681cb0ef41Sopenharmony_ci    check = __ Word32Equal(lhs, __ Int32Mul(rhs, value));
23691cb0ef41Sopenharmony_ci    __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, FeedbackSource(),
23701cb0ef41Sopenharmony_ci                       check, frame_state);
23711cb0ef41Sopenharmony_ci    return value;
23721cb0ef41Sopenharmony_ci  }
23731cb0ef41Sopenharmony_ci}
23741cb0ef41Sopenharmony_ci
23751cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedUint32Mod(Node* node,
23761cb0ef41Sopenharmony_ci                                                     Node* frame_state) {
23771cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(0);
23781cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(1);
23791cb0ef41Sopenharmony_ci
23801cb0ef41Sopenharmony_ci  Node* zero = __ Int32Constant(0);
23811cb0ef41Sopenharmony_ci
23821cb0ef41Sopenharmony_ci  // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
23831cb0ef41Sopenharmony_ci  Node* check = __ Word32Equal(rhs, zero);
23841cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, FeedbackSource(), check,
23851cb0ef41Sopenharmony_ci                  frame_state);
23861cb0ef41Sopenharmony_ci
23871cb0ef41Sopenharmony_ci  // Perform the actual unsigned integer modulus.
23881cb0ef41Sopenharmony_ci  return BuildUint32Mod(lhs, rhs);
23891cb0ef41Sopenharmony_ci}
23901cb0ef41Sopenharmony_ci
23911cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedInt32Mul(Node* node,
23921cb0ef41Sopenharmony_ci                                                    Node* frame_state) {
23931cb0ef41Sopenharmony_ci  CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
23941cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(0);
23951cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(1);
23961cb0ef41Sopenharmony_ci
23971cb0ef41Sopenharmony_ci  Node* projection = __ Int32MulWithOverflow(lhs, rhs);
23981cb0ef41Sopenharmony_ci  Node* check = __ Projection(1, projection);
23991cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kOverflow, FeedbackSource(), check,
24001cb0ef41Sopenharmony_ci                  frame_state);
24011cb0ef41Sopenharmony_ci
24021cb0ef41Sopenharmony_ci  Node* value = __ Projection(0, projection);
24031cb0ef41Sopenharmony_ci
24041cb0ef41Sopenharmony_ci  if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
24051cb0ef41Sopenharmony_ci    auto if_zero = __ MakeDeferredLabel();
24061cb0ef41Sopenharmony_ci    auto check_done = __ MakeLabel();
24071cb0ef41Sopenharmony_ci    Node* zero = __ Int32Constant(0);
24081cb0ef41Sopenharmony_ci    Node* check_zero = __ Word32Equal(value, zero);
24091cb0ef41Sopenharmony_ci    __ GotoIf(check_zero, &if_zero);
24101cb0ef41Sopenharmony_ci    __ Goto(&check_done);
24111cb0ef41Sopenharmony_ci
24121cb0ef41Sopenharmony_ci    __ Bind(&if_zero);
24131cb0ef41Sopenharmony_ci    // We may need to return negative zero.
24141cb0ef41Sopenharmony_ci    Node* check_or = __ Int32LessThan(__ Word32Or(lhs, rhs), zero);
24151cb0ef41Sopenharmony_ci    __ DeoptimizeIf(DeoptimizeReason::kMinusZero, FeedbackSource(), check_or,
24161cb0ef41Sopenharmony_ci                    frame_state);
24171cb0ef41Sopenharmony_ci    __ Goto(&check_done);
24181cb0ef41Sopenharmony_ci
24191cb0ef41Sopenharmony_ci    __ Bind(&check_done);
24201cb0ef41Sopenharmony_ci  }
24211cb0ef41Sopenharmony_ci
24221cb0ef41Sopenharmony_ci  return value;
24231cb0ef41Sopenharmony_ci}
24241cb0ef41Sopenharmony_ci
24251cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedInt32ToTaggedSigned(
24261cb0ef41Sopenharmony_ci    Node* node, Node* frame_state) {
24271cb0ef41Sopenharmony_ci  DCHECK(SmiValuesAre31Bits());
24281cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
24291cb0ef41Sopenharmony_ci  const CheckParameters& params = CheckParametersOf(node->op());
24301cb0ef41Sopenharmony_ci  return SmiTagOrDeopt(value, params, frame_state);
24311cb0ef41Sopenharmony_ci}
24321cb0ef41Sopenharmony_ci
24331cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedInt64ToInt32(Node* node,
24341cb0ef41Sopenharmony_ci                                                        Node* frame_state) {
24351cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
24361cb0ef41Sopenharmony_ci  const CheckParameters& params = CheckParametersOf(node->op());
24371cb0ef41Sopenharmony_ci
24381cb0ef41Sopenharmony_ci  Node* value32 = __ TruncateInt64ToInt32(value);
24391cb0ef41Sopenharmony_ci  Node* check = __ Word64Equal(__ ChangeInt32ToInt64(value32), value);
24401cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
24411cb0ef41Sopenharmony_ci                     frame_state);
24421cb0ef41Sopenharmony_ci  return value32;
24431cb0ef41Sopenharmony_ci}
24441cb0ef41Sopenharmony_ci
24451cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedInt64ToTaggedSigned(
24461cb0ef41Sopenharmony_ci    Node* node, Node* frame_state) {
24471cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
24481cb0ef41Sopenharmony_ci  const CheckParameters& params = CheckParametersOf(node->op());
24491cb0ef41Sopenharmony_ci
24501cb0ef41Sopenharmony_ci  Node* value32 = __ TruncateInt64ToInt32(value);
24511cb0ef41Sopenharmony_ci  Node* check = __ Word64Equal(__ ChangeInt32ToInt64(value32), value);
24521cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
24531cb0ef41Sopenharmony_ci                     frame_state);
24541cb0ef41Sopenharmony_ci
24551cb0ef41Sopenharmony_ci  if (SmiValuesAre32Bits()) {
24561cb0ef41Sopenharmony_ci    return ChangeInt64ToSmi(value);
24571cb0ef41Sopenharmony_ci  } else {
24581cb0ef41Sopenharmony_ci    return SmiTagOrDeopt(value32, params, frame_state);
24591cb0ef41Sopenharmony_ci  }
24601cb0ef41Sopenharmony_ci}
24611cb0ef41Sopenharmony_ci
24621cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedUint32Bounds(Node* node,
24631cb0ef41Sopenharmony_ci                                                        Node* frame_state) {
24641cb0ef41Sopenharmony_ci  Node* index = node->InputAt(0);
24651cb0ef41Sopenharmony_ci  Node* limit = node->InputAt(1);
24661cb0ef41Sopenharmony_ci  const CheckBoundsParameters& params = CheckBoundsParametersOf(node->op());
24671cb0ef41Sopenharmony_ci
24681cb0ef41Sopenharmony_ci  Node* check = __ Uint32LessThan(index, limit);
24691cb0ef41Sopenharmony_ci  if (!(params.flags() & CheckBoundsFlag::kAbortOnOutOfBounds)) {
24701cb0ef41Sopenharmony_ci    __ DeoptimizeIfNot(DeoptimizeReason::kOutOfBounds,
24711cb0ef41Sopenharmony_ci                       params.check_parameters().feedback(), check,
24721cb0ef41Sopenharmony_ci                       frame_state);
24731cb0ef41Sopenharmony_ci  } else {
24741cb0ef41Sopenharmony_ci    auto if_abort = __ MakeDeferredLabel();
24751cb0ef41Sopenharmony_ci    auto done = __ MakeLabel();
24761cb0ef41Sopenharmony_ci
24771cb0ef41Sopenharmony_ci    __ Branch(check, &done, &if_abort);
24781cb0ef41Sopenharmony_ci
24791cb0ef41Sopenharmony_ci    __ Bind(&if_abort);
24801cb0ef41Sopenharmony_ci    __ Unreachable(&done);
24811cb0ef41Sopenharmony_ci
24821cb0ef41Sopenharmony_ci    __ Bind(&done);
24831cb0ef41Sopenharmony_ci  }
24841cb0ef41Sopenharmony_ci
24851cb0ef41Sopenharmony_ci  return index;
24861cb0ef41Sopenharmony_ci}
24871cb0ef41Sopenharmony_ci
24881cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node,
24891cb0ef41Sopenharmony_ci                                                         Node* frame_state) {
24901cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
24911cb0ef41Sopenharmony_ci  const CheckParameters& params = CheckParametersOf(node->op());
24921cb0ef41Sopenharmony_ci  Node* unsafe = __ Int32LessThan(value, __ Int32Constant(0));
24931cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kLostPrecision, params.feedback(), unsafe,
24941cb0ef41Sopenharmony_ci                  frame_state);
24951cb0ef41Sopenharmony_ci  return value;
24961cb0ef41Sopenharmony_ci}
24971cb0ef41Sopenharmony_ci
24981cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedUint32ToTaggedSigned(
24991cb0ef41Sopenharmony_ci    Node* node, Node* frame_state) {
25001cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
25011cb0ef41Sopenharmony_ci  const CheckParameters& params = CheckParametersOf(node->op());
25021cb0ef41Sopenharmony_ci  Node* check = __ Uint32LessThanOrEqual(value, SmiMaxValueConstant());
25031cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
25041cb0ef41Sopenharmony_ci                     frame_state);
25051cb0ef41Sopenharmony_ci  return ChangeUint32ToSmi(value);
25061cb0ef41Sopenharmony_ci}
25071cb0ef41Sopenharmony_ci
25081cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedUint64Bounds(Node* node,
25091cb0ef41Sopenharmony_ci                                                        Node* frame_state) {
25101cb0ef41Sopenharmony_ci  Node* const index = node->InputAt(0);
25111cb0ef41Sopenharmony_ci  Node* const limit = node->InputAt(1);
25121cb0ef41Sopenharmony_ci  const CheckBoundsParameters& params = CheckBoundsParametersOf(node->op());
25131cb0ef41Sopenharmony_ci
25141cb0ef41Sopenharmony_ci  Node* check = __ Uint64LessThan(index, limit);
25151cb0ef41Sopenharmony_ci  if (!(params.flags() & CheckBoundsFlag::kAbortOnOutOfBounds)) {
25161cb0ef41Sopenharmony_ci    __ DeoptimizeIfNot(DeoptimizeReason::kOutOfBounds,
25171cb0ef41Sopenharmony_ci                       params.check_parameters().feedback(), check,
25181cb0ef41Sopenharmony_ci                       frame_state);
25191cb0ef41Sopenharmony_ci  } else {
25201cb0ef41Sopenharmony_ci    auto if_abort = __ MakeDeferredLabel();
25211cb0ef41Sopenharmony_ci    auto done = __ MakeLabel();
25221cb0ef41Sopenharmony_ci
25231cb0ef41Sopenharmony_ci    __ Branch(check, &done, &if_abort);
25241cb0ef41Sopenharmony_ci
25251cb0ef41Sopenharmony_ci    __ Bind(&if_abort);
25261cb0ef41Sopenharmony_ci    __ Unreachable(&done);
25271cb0ef41Sopenharmony_ci
25281cb0ef41Sopenharmony_ci    __ Bind(&done);
25291cb0ef41Sopenharmony_ci  }
25301cb0ef41Sopenharmony_ci  return index;
25311cb0ef41Sopenharmony_ci}
25321cb0ef41Sopenharmony_ci
25331cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedUint64ToInt32(Node* node,
25341cb0ef41Sopenharmony_ci                                                         Node* frame_state) {
25351cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
25361cb0ef41Sopenharmony_ci  const CheckParameters& params = CheckParametersOf(node->op());
25371cb0ef41Sopenharmony_ci
25381cb0ef41Sopenharmony_ci  Node* check = __ Uint64LessThanOrEqual(value, __ Int64Constant(kMaxInt));
25391cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
25401cb0ef41Sopenharmony_ci                     frame_state);
25411cb0ef41Sopenharmony_ci  return __ TruncateInt64ToInt32(value);
25421cb0ef41Sopenharmony_ci}
25431cb0ef41Sopenharmony_ci
25441cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedUint64ToTaggedSigned(
25451cb0ef41Sopenharmony_ci    Node* node, Node* frame_state) {
25461cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
25471cb0ef41Sopenharmony_ci  const CheckParameters& params = CheckParametersOf(node->op());
25481cb0ef41Sopenharmony_ci
25491cb0ef41Sopenharmony_ci  Node* check =
25501cb0ef41Sopenharmony_ci      __ Uint64LessThanOrEqual(value, __ Int64Constant(Smi::kMaxValue));
25511cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
25521cb0ef41Sopenharmony_ci                     frame_state);
25531cb0ef41Sopenharmony_ci  return ChangeInt64ToSmi(value);
25541cb0ef41Sopenharmony_ci}
25551cb0ef41Sopenharmony_ci
25561cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildCheckedFloat64ToInt32(
25571cb0ef41Sopenharmony_ci    CheckForMinusZeroMode mode, const FeedbackSource& feedback, Node* value,
25581cb0ef41Sopenharmony_ci    Node* frame_state) {
25591cb0ef41Sopenharmony_ci  Node* value32 = __ RoundFloat64ToInt32(value);
25601cb0ef41Sopenharmony_ci  Node* check_same = __ Float64Equal(value, __ ChangeInt32ToFloat64(value32));
25611cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecisionOrNaN, feedback,
25621cb0ef41Sopenharmony_ci                     check_same, frame_state);
25631cb0ef41Sopenharmony_ci
25641cb0ef41Sopenharmony_ci  if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
25651cb0ef41Sopenharmony_ci    // Check if {value} is -0.
25661cb0ef41Sopenharmony_ci    auto if_zero = __ MakeDeferredLabel();
25671cb0ef41Sopenharmony_ci    auto check_done = __ MakeLabel();
25681cb0ef41Sopenharmony_ci
25691cb0ef41Sopenharmony_ci    Node* check_zero = __ Word32Equal(value32, __ Int32Constant(0));
25701cb0ef41Sopenharmony_ci    __ GotoIf(check_zero, &if_zero);
25711cb0ef41Sopenharmony_ci    __ Goto(&check_done);
25721cb0ef41Sopenharmony_ci
25731cb0ef41Sopenharmony_ci    __ Bind(&if_zero);
25741cb0ef41Sopenharmony_ci    // In case of 0, we need to check the high bits for the IEEE -0 pattern.
25751cb0ef41Sopenharmony_ci    Node* check_negative = __ Int32LessThan(__ Float64ExtractHighWord32(value),
25761cb0ef41Sopenharmony_ci                                            __ Int32Constant(0));
25771cb0ef41Sopenharmony_ci    __ DeoptimizeIf(DeoptimizeReason::kMinusZero, feedback, check_negative,
25781cb0ef41Sopenharmony_ci                    frame_state);
25791cb0ef41Sopenharmony_ci    __ Goto(&check_done);
25801cb0ef41Sopenharmony_ci
25811cb0ef41Sopenharmony_ci    __ Bind(&check_done);
25821cb0ef41Sopenharmony_ci  }
25831cb0ef41Sopenharmony_ci  return value32;
25841cb0ef41Sopenharmony_ci}
25851cb0ef41Sopenharmony_ci
25861cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildCheckedFloat64ToIndex(
25871cb0ef41Sopenharmony_ci    const FeedbackSource& feedback, Node* value, Node* frame_state) {
25881cb0ef41Sopenharmony_ci  if (machine()->Is64()) {
25891cb0ef41Sopenharmony_ci    Node* value64 =
25901cb0ef41Sopenharmony_ci        __ TruncateFloat64ToInt64(value, TruncateKind::kArchitectureDefault);
25911cb0ef41Sopenharmony_ci    // The TruncateKind above means there will be a precision loss in case
25921cb0ef41Sopenharmony_ci    // INT64_MAX input is passed, but that precision loss would not be
25931cb0ef41Sopenharmony_ci    // detected and would not lead to a deoptimization from the first check.
25941cb0ef41Sopenharmony_ci    // But in this case, we'll deopt anyway because of the following checks.
25951cb0ef41Sopenharmony_ci    Node* check_same = __ Float64Equal(value, __ ChangeInt64ToFloat64(value64));
25961cb0ef41Sopenharmony_ci    __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecisionOrNaN, feedback,
25971cb0ef41Sopenharmony_ci                       check_same, frame_state);
25981cb0ef41Sopenharmony_ci    Node* check_max =
25991cb0ef41Sopenharmony_ci        __ IntLessThan(value64, __ Int64Constant(kMaxSafeInteger));
26001cb0ef41Sopenharmony_ci    __ DeoptimizeIfNot(DeoptimizeReason::kNotAnArrayIndex, feedback, check_max,
26011cb0ef41Sopenharmony_ci                       frame_state);
26021cb0ef41Sopenharmony_ci    Node* check_min =
26031cb0ef41Sopenharmony_ci        __ IntLessThan(__ Int64Constant(-kMaxSafeInteger), value64);
26041cb0ef41Sopenharmony_ci    __ DeoptimizeIfNot(DeoptimizeReason::kNotAnArrayIndex, feedback, check_min,
26051cb0ef41Sopenharmony_ci                       frame_state);
26061cb0ef41Sopenharmony_ci    return value64;
26071cb0ef41Sopenharmony_ci  } else {
26081cb0ef41Sopenharmony_ci    Node* value32 = __ RoundFloat64ToInt32(value);
26091cb0ef41Sopenharmony_ci    Node* check_same = __ Float64Equal(value, __ ChangeInt32ToFloat64(value32));
26101cb0ef41Sopenharmony_ci    __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecisionOrNaN, feedback,
26111cb0ef41Sopenharmony_ci                       check_same, frame_state);
26121cb0ef41Sopenharmony_ci    return value32;
26131cb0ef41Sopenharmony_ci  }
26141cb0ef41Sopenharmony_ci}
26151cb0ef41Sopenharmony_ci
26161cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node,
26171cb0ef41Sopenharmony_ci                                                          Node* frame_state) {
26181cb0ef41Sopenharmony_ci  const CheckMinusZeroParameters& params =
26191cb0ef41Sopenharmony_ci      CheckMinusZeroParametersOf(node->op());
26201cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
26211cb0ef41Sopenharmony_ci  return BuildCheckedFloat64ToInt32(params.mode(), params.feedback(), value,
26221cb0ef41Sopenharmony_ci                                    frame_state);
26231cb0ef41Sopenharmony_ci}
26241cb0ef41Sopenharmony_ci
26251cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildCheckedFloat64ToInt64(
26261cb0ef41Sopenharmony_ci    CheckForMinusZeroMode mode, const FeedbackSource& feedback, Node* value,
26271cb0ef41Sopenharmony_ci    Node* frame_state) {
26281cb0ef41Sopenharmony_ci  Node* value64 =
26291cb0ef41Sopenharmony_ci      __ TruncateFloat64ToInt64(value, TruncateKind::kSetOverflowToMin);
26301cb0ef41Sopenharmony_ci  Node* check_same = __ Float64Equal(value, __ ChangeInt64ToFloat64(value64));
26311cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecisionOrNaN, feedback,
26321cb0ef41Sopenharmony_ci                     check_same, frame_state);
26331cb0ef41Sopenharmony_ci
26341cb0ef41Sopenharmony_ci  if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
26351cb0ef41Sopenharmony_ci    // Check if {value} is -0.
26361cb0ef41Sopenharmony_ci    auto if_zero = __ MakeDeferredLabel();
26371cb0ef41Sopenharmony_ci    auto check_done = __ MakeLabel();
26381cb0ef41Sopenharmony_ci
26391cb0ef41Sopenharmony_ci    Node* check_zero = __ Word64Equal(value64, __ Int64Constant(0));
26401cb0ef41Sopenharmony_ci    __ GotoIf(check_zero, &if_zero);
26411cb0ef41Sopenharmony_ci    __ Goto(&check_done);
26421cb0ef41Sopenharmony_ci
26431cb0ef41Sopenharmony_ci    __ Bind(&if_zero);
26441cb0ef41Sopenharmony_ci    // In case of 0, we need to check the high bits for the IEEE -0 pattern.
26451cb0ef41Sopenharmony_ci    Node* check_negative = __ Int32LessThan(__ Float64ExtractHighWord32(value),
26461cb0ef41Sopenharmony_ci                                            __ Int32Constant(0));
26471cb0ef41Sopenharmony_ci    __ DeoptimizeIf(DeoptimizeReason::kMinusZero, feedback, check_negative,
26481cb0ef41Sopenharmony_ci                    frame_state);
26491cb0ef41Sopenharmony_ci    __ Goto(&check_done);
26501cb0ef41Sopenharmony_ci
26511cb0ef41Sopenharmony_ci    __ Bind(&check_done);
26521cb0ef41Sopenharmony_ci  }
26531cb0ef41Sopenharmony_ci  return value64;
26541cb0ef41Sopenharmony_ci}
26551cb0ef41Sopenharmony_ci
26561cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedFloat64ToInt64(Node* node,
26571cb0ef41Sopenharmony_ci                                                          Node* frame_state) {
26581cb0ef41Sopenharmony_ci  const CheckMinusZeroParameters& params =
26591cb0ef41Sopenharmony_ci      CheckMinusZeroParametersOf(node->op());
26601cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
26611cb0ef41Sopenharmony_ci  return BuildCheckedFloat64ToInt64(params.mode(), params.feedback(), value,
26621cb0ef41Sopenharmony_ci                                    frame_state);
26631cb0ef41Sopenharmony_ci}
26641cb0ef41Sopenharmony_ci
26651cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedTaggedSignedToInt32(
26661cb0ef41Sopenharmony_ci    Node* node, Node* frame_state) {
26671cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
26681cb0ef41Sopenharmony_ci  const CheckParameters& params = CheckParametersOf(node->op());
26691cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
26701cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, params.feedback(), check,
26711cb0ef41Sopenharmony_ci                     frame_state);
26721cb0ef41Sopenharmony_ci  return ChangeSmiToInt32(value);
26731cb0ef41Sopenharmony_ci}
26741cb0ef41Sopenharmony_ci
26751cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedTaggedToArrayIndex(
26761cb0ef41Sopenharmony_ci    Node* node, Node* frame_state) {
26771cb0ef41Sopenharmony_ci  CheckParameters const& params = CheckParametersOf(node->op());
26781cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
26791cb0ef41Sopenharmony_ci
26801cb0ef41Sopenharmony_ci  auto if_not_smi = __ MakeDeferredLabel();
26811cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineType::PointerRepresentation());
26821cb0ef41Sopenharmony_ci
26831cb0ef41Sopenharmony_ci  __ GotoIfNot(ObjectIsSmi(value), &if_not_smi);
26841cb0ef41Sopenharmony_ci  // In the Smi case, just convert to intptr_t.
26851cb0ef41Sopenharmony_ci  __ Goto(&done, ChangeSmiToIntPtr(value));
26861cb0ef41Sopenharmony_ci
26871cb0ef41Sopenharmony_ci  // In the non-Smi case, check the heap numberness, load the number and convert
26881cb0ef41Sopenharmony_ci  // to integer.
26891cb0ef41Sopenharmony_ci  __ Bind(&if_not_smi);
26901cb0ef41Sopenharmony_ci  auto if_not_heap_number = __ MakeDeferredLabel();
26911cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
26921cb0ef41Sopenharmony_ci  Node* is_heap_number = __ TaggedEqual(value_map, __ HeapNumberMapConstant());
26931cb0ef41Sopenharmony_ci  __ GotoIfNot(is_heap_number, &if_not_heap_number);
26941cb0ef41Sopenharmony_ci
26951cb0ef41Sopenharmony_ci  Node* number = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
26961cb0ef41Sopenharmony_ci  number = BuildCheckedFloat64ToIndex(params.feedback(), number, frame_state);
26971cb0ef41Sopenharmony_ci  __ Goto(&done, number);
26981cb0ef41Sopenharmony_ci
26991cb0ef41Sopenharmony_ci  __ Bind(&if_not_heap_number);
27001cb0ef41Sopenharmony_ci  auto calculate_index = __ MakeDeferredLabel();
27011cb0ef41Sopenharmony_ci  Node* value_instance_type =
27021cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
27031cb0ef41Sopenharmony_ci  Node* is_string = __ Uint32LessThan(value_instance_type,
27041cb0ef41Sopenharmony_ci                                      __ Uint32Constant(FIRST_NONSTRING_TYPE));
27051cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kNotAString, params.feedback(),
27061cb0ef41Sopenharmony_ci                     is_string, frame_state);
27071cb0ef41Sopenharmony_ci
27081cb0ef41Sopenharmony_ci  MachineSignature::Builder builder(graph()->zone(), 1, 1);
27091cb0ef41Sopenharmony_ci  builder.AddReturn(MachineType::IntPtr());
27101cb0ef41Sopenharmony_ci  builder.AddParam(MachineType::TaggedPointer());
27111cb0ef41Sopenharmony_ci  Node* string_to_array_index_function =
27121cb0ef41Sopenharmony_ci      __ ExternalConstant(ExternalReference::string_to_array_index_function());
27131cb0ef41Sopenharmony_ci  auto call_descriptor =
27141cb0ef41Sopenharmony_ci      Linkage::GetSimplifiedCDescriptor(graph()->zone(), builder.Build());
27151cb0ef41Sopenharmony_ci  Node* index = __ Call(common()->Call(call_descriptor),
27161cb0ef41Sopenharmony_ci                        string_to_array_index_function, value);
27171cb0ef41Sopenharmony_ci
27181cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kNotAnArrayIndex, params.feedback(),
27191cb0ef41Sopenharmony_ci                  __ Word32Equal(index, __ Int32Constant(-1)), frame_state);
27201cb0ef41Sopenharmony_ci
27211cb0ef41Sopenharmony_ci  __ Goto(&done, index);
27221cb0ef41Sopenharmony_ci
27231cb0ef41Sopenharmony_ci  __ Bind(&done);
27241cb0ef41Sopenharmony_ci  return done.PhiAt(0);
27251cb0ef41Sopenharmony_ci}
27261cb0ef41Sopenharmony_ci
27271cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node,
27281cb0ef41Sopenharmony_ci                                                         Node* frame_state) {
27291cb0ef41Sopenharmony_ci  const CheckMinusZeroParameters& params =
27301cb0ef41Sopenharmony_ci      CheckMinusZeroParametersOf(node->op());
27311cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
27321cb0ef41Sopenharmony_ci
27331cb0ef41Sopenharmony_ci  auto if_not_smi = __ MakeDeferredLabel();
27341cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kWord32);
27351cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
27361cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &if_not_smi);
27371cb0ef41Sopenharmony_ci  // In the Smi case, just convert to int32.
27381cb0ef41Sopenharmony_ci  __ Goto(&done, ChangeSmiToInt32(value));
27391cb0ef41Sopenharmony_ci
27401cb0ef41Sopenharmony_ci  // In the non-Smi case, check the heap numberness, load the number and convert
27411cb0ef41Sopenharmony_ci  // to int32.
27421cb0ef41Sopenharmony_ci  __ Bind(&if_not_smi);
27431cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
27441cb0ef41Sopenharmony_ci  Node* check_map = __ TaggedEqual(value_map, __ HeapNumberMapConstant());
27451cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, params.feedback(),
27461cb0ef41Sopenharmony_ci                     check_map, frame_state);
27471cb0ef41Sopenharmony_ci  Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
27481cb0ef41Sopenharmony_ci  vfalse = BuildCheckedFloat64ToInt32(params.mode(), params.feedback(), vfalse,
27491cb0ef41Sopenharmony_ci                                      frame_state);
27501cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
27511cb0ef41Sopenharmony_ci
27521cb0ef41Sopenharmony_ci  __ Bind(&done);
27531cb0ef41Sopenharmony_ci  return done.PhiAt(0);
27541cb0ef41Sopenharmony_ci}
27551cb0ef41Sopenharmony_ci
27561cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedTaggedToInt64(Node* node,
27571cb0ef41Sopenharmony_ci                                                         Node* frame_state) {
27581cb0ef41Sopenharmony_ci  const CheckMinusZeroParameters& params =
27591cb0ef41Sopenharmony_ci      CheckMinusZeroParametersOf(node->op());
27601cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
27611cb0ef41Sopenharmony_ci
27621cb0ef41Sopenharmony_ci  auto if_not_smi = __ MakeDeferredLabel();
27631cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kWord64);
27641cb0ef41Sopenharmony_ci
27651cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
27661cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &if_not_smi);
27671cb0ef41Sopenharmony_ci  // In the Smi case, just convert to int64.
27681cb0ef41Sopenharmony_ci  __ Goto(&done, ChangeSmiToInt64(value));
27691cb0ef41Sopenharmony_ci
27701cb0ef41Sopenharmony_ci  // In the non-Smi case, check the heap numberness, load the number and convert
27711cb0ef41Sopenharmony_ci  // to int64.
27721cb0ef41Sopenharmony_ci  __ Bind(&if_not_smi);
27731cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
27741cb0ef41Sopenharmony_ci  Node* check_map = __ TaggedEqual(value_map, __ HeapNumberMapConstant());
27751cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, params.feedback(),
27761cb0ef41Sopenharmony_ci                     check_map, frame_state);
27771cb0ef41Sopenharmony_ci  Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
27781cb0ef41Sopenharmony_ci  vfalse = BuildCheckedFloat64ToInt64(params.mode(), params.feedback(), vfalse,
27791cb0ef41Sopenharmony_ci                                      frame_state);
27801cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
27811cb0ef41Sopenharmony_ci
27821cb0ef41Sopenharmony_ci  __ Bind(&done);
27831cb0ef41Sopenharmony_ci  return done.PhiAt(0);
27841cb0ef41Sopenharmony_ci}
27851cb0ef41Sopenharmony_ci
27861cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64(
27871cb0ef41Sopenharmony_ci    CheckTaggedInputMode mode, const FeedbackSource& feedback, Node* value,
27881cb0ef41Sopenharmony_ci    Node* frame_state) {
27891cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
27901cb0ef41Sopenharmony_ci  Node* check_number = __ TaggedEqual(value_map, __ HeapNumberMapConstant());
27911cb0ef41Sopenharmony_ci  switch (mode) {
27921cb0ef41Sopenharmony_ci    case CheckTaggedInputMode::kNumber: {
27931cb0ef41Sopenharmony_ci      __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, feedback,
27941cb0ef41Sopenharmony_ci                         check_number, frame_state);
27951cb0ef41Sopenharmony_ci      break;
27961cb0ef41Sopenharmony_ci    }
27971cb0ef41Sopenharmony_ci    case CheckTaggedInputMode::kNumberOrBoolean: {
27981cb0ef41Sopenharmony_ci      auto check_done = __ MakeLabel();
27991cb0ef41Sopenharmony_ci
28001cb0ef41Sopenharmony_ci      __ GotoIf(check_number, &check_done);
28011cb0ef41Sopenharmony_ci      __ DeoptimizeIfNot(DeoptimizeReason::kNotANumberOrBoolean, feedback,
28021cb0ef41Sopenharmony_ci                         __ TaggedEqual(value_map, __ BooleanMapConstant()),
28031cb0ef41Sopenharmony_ci                         frame_state);
28041cb0ef41Sopenharmony_ci      STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
28051cb0ef41Sopenharmony_ci                                        Oddball::kToNumberRawOffset);
28061cb0ef41Sopenharmony_ci      __ Goto(&check_done);
28071cb0ef41Sopenharmony_ci
28081cb0ef41Sopenharmony_ci      __ Bind(&check_done);
28091cb0ef41Sopenharmony_ci      break;
28101cb0ef41Sopenharmony_ci    }
28111cb0ef41Sopenharmony_ci    case CheckTaggedInputMode::kNumberOrOddball: {
28121cb0ef41Sopenharmony_ci      auto check_done = __ MakeLabel();
28131cb0ef41Sopenharmony_ci
28141cb0ef41Sopenharmony_ci      __ GotoIf(check_number, &check_done);
28151cb0ef41Sopenharmony_ci      // For oddballs also contain the numeric value, let us just check that
28161cb0ef41Sopenharmony_ci      // we have an oddball here.
28171cb0ef41Sopenharmony_ci      Node* instance_type =
28181cb0ef41Sopenharmony_ci          __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
28191cb0ef41Sopenharmony_ci      Node* check_oddball =
28201cb0ef41Sopenharmony_ci          __ Word32Equal(instance_type, __ Int32Constant(ODDBALL_TYPE));
28211cb0ef41Sopenharmony_ci      __ DeoptimizeIfNot(DeoptimizeReason::kNotANumberOrOddball, feedback,
28221cb0ef41Sopenharmony_ci                         check_oddball, frame_state);
28231cb0ef41Sopenharmony_ci      STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
28241cb0ef41Sopenharmony_ci                                        Oddball::kToNumberRawOffset);
28251cb0ef41Sopenharmony_ci      __ Goto(&check_done);
28261cb0ef41Sopenharmony_ci
28271cb0ef41Sopenharmony_ci      __ Bind(&check_done);
28281cb0ef41Sopenharmony_ci      break;
28291cb0ef41Sopenharmony_ci    }
28301cb0ef41Sopenharmony_ci  }
28311cb0ef41Sopenharmony_ci  return __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
28321cb0ef41Sopenharmony_ci}
28331cb0ef41Sopenharmony_ci
28341cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node,
28351cb0ef41Sopenharmony_ci                                                           Node* frame_state) {
28361cb0ef41Sopenharmony_ci  CheckTaggedInputParameters const& p =
28371cb0ef41Sopenharmony_ci      CheckTaggedInputParametersOf(node->op());
28381cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
28391cb0ef41Sopenharmony_ci
28401cb0ef41Sopenharmony_ci  auto if_smi = __ MakeLabel();
28411cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kFloat64);
28421cb0ef41Sopenharmony_ci
28431cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
28441cb0ef41Sopenharmony_ci  __ GotoIf(check, &if_smi);
28451cb0ef41Sopenharmony_ci
28461cb0ef41Sopenharmony_ci  // In the Smi case, just convert to int32 and then float64.
28471cb0ef41Sopenharmony_ci  // Otherwise, check heap numberness and load the number.
28481cb0ef41Sopenharmony_ci  Node* number = BuildCheckedHeapNumberOrOddballToFloat64(
28491cb0ef41Sopenharmony_ci      p.mode(), p.feedback(), value, frame_state);
28501cb0ef41Sopenharmony_ci  __ Goto(&done, number);
28511cb0ef41Sopenharmony_ci
28521cb0ef41Sopenharmony_ci  __ Bind(&if_smi);
28531cb0ef41Sopenharmony_ci  Node* from_smi = ChangeSmiToInt32(value);
28541cb0ef41Sopenharmony_ci  from_smi = __ ChangeInt32ToFloat64(from_smi);
28551cb0ef41Sopenharmony_ci  __ Goto(&done, from_smi);
28561cb0ef41Sopenharmony_ci
28571cb0ef41Sopenharmony_ci  __ Bind(&done);
28581cb0ef41Sopenharmony_ci  return done.PhiAt(0);
28591cb0ef41Sopenharmony_ci}
28601cb0ef41Sopenharmony_ci
28611cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned(
28621cb0ef41Sopenharmony_ci    Node* node, Node* frame_state) {
28631cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
28641cb0ef41Sopenharmony_ci  const CheckParameters& params = CheckParametersOf(node->op());
28651cb0ef41Sopenharmony_ci
28661cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
28671cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, params.feedback(), check,
28681cb0ef41Sopenharmony_ci                     frame_state);
28691cb0ef41Sopenharmony_ci
28701cb0ef41Sopenharmony_ci  return value;
28711cb0ef41Sopenharmony_ci}
28721cb0ef41Sopenharmony_ci
28731cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedTaggedToTaggedPointer(
28741cb0ef41Sopenharmony_ci    Node* node, Node* frame_state) {
28751cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
28761cb0ef41Sopenharmony_ci  const CheckParameters& params = CheckParametersOf(node->op());
28771cb0ef41Sopenharmony_ci
28781cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
28791cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kSmi, params.feedback(), check,
28801cb0ef41Sopenharmony_ci                  frame_state);
28811cb0ef41Sopenharmony_ci  return value;
28821cb0ef41Sopenharmony_ci}
28831cb0ef41Sopenharmony_ci
28841cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckBigInt(Node* node, Node* frame_state) {
28851cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
28861cb0ef41Sopenharmony_ci  const CheckParameters& params = CheckParametersOf(node->op());
28871cb0ef41Sopenharmony_ci
28881cb0ef41Sopenharmony_ci  // Check for Smi.
28891cb0ef41Sopenharmony_ci  Node* smi_check = ObjectIsSmi(value);
28901cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kSmi, params.feedback(), smi_check,
28911cb0ef41Sopenharmony_ci                  frame_state);
28921cb0ef41Sopenharmony_ci
28931cb0ef41Sopenharmony_ci  // Check for BigInt.
28941cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
28951cb0ef41Sopenharmony_ci  Node* bi_check = __ TaggedEqual(value_map, __ BigIntMapConstant());
28961cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kWrongInstanceType, params.feedback(),
28971cb0ef41Sopenharmony_ci                     bi_check, frame_state);
28981cb0ef41Sopenharmony_ci
28991cb0ef41Sopenharmony_ci  return value;
29001cb0ef41Sopenharmony_ci}
29011cb0ef41Sopenharmony_ci
29021cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeInt64ToBigInt(Node* node) {
29031cb0ef41Sopenharmony_ci  DCHECK(machine()->Is64());
29041cb0ef41Sopenharmony_ci
29051cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
29061cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
29071cb0ef41Sopenharmony_ci
29081cb0ef41Sopenharmony_ci  // BigInts with value 0 must be of size 0 (canonical form).
29091cb0ef41Sopenharmony_ci  __ GotoIf(__ Word64Equal(value, __ IntPtrConstant(0)), &done,
29101cb0ef41Sopenharmony_ci            BuildAllocateBigInt(nullptr, nullptr));
29111cb0ef41Sopenharmony_ci
29121cb0ef41Sopenharmony_ci  // Shift sign bit into BigInt's sign bit position.
29131cb0ef41Sopenharmony_ci  Node* sign =
29141cb0ef41Sopenharmony_ci      __ Word64Shr(value, __ IntPtrConstant(63 - BigInt::SignBits::kShift));
29151cb0ef41Sopenharmony_ci  Node* bitfield =
29161cb0ef41Sopenharmony_ci      __ Word32Or(__ Int32Constant(BigInt::LengthBits::encode(1)), sign);
29171cb0ef41Sopenharmony_ci
29181cb0ef41Sopenharmony_ci  // We use (value XOR (value >>> 63)) - (value >>> 63) to compute the
29191cb0ef41Sopenharmony_ci  // absolute value, in a branchless fashion.
29201cb0ef41Sopenharmony_ci  Node* sign_mask = __ Word64Sar(value, __ Int64Constant(63));
29211cb0ef41Sopenharmony_ci  Node* absolute_value = __ Int64Sub(__ Word64Xor(value, sign_mask), sign_mask);
29221cb0ef41Sopenharmony_ci  __ Goto(&done, BuildAllocateBigInt(bitfield, absolute_value));
29231cb0ef41Sopenharmony_ci
29241cb0ef41Sopenharmony_ci  __ Bind(&done);
29251cb0ef41Sopenharmony_ci  return done.PhiAt(0);
29261cb0ef41Sopenharmony_ci}
29271cb0ef41Sopenharmony_ci
29281cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerChangeUint64ToBigInt(Node* node) {
29291cb0ef41Sopenharmony_ci  DCHECK(machine()->Is64());
29301cb0ef41Sopenharmony_ci
29311cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
29321cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
29331cb0ef41Sopenharmony_ci
29341cb0ef41Sopenharmony_ci  // BigInts with value 0 must be of size 0 (canonical form).
29351cb0ef41Sopenharmony_ci  __ GotoIf(__ Word64Equal(value, __ IntPtrConstant(0)), &done,
29361cb0ef41Sopenharmony_ci            BuildAllocateBigInt(nullptr, nullptr));
29371cb0ef41Sopenharmony_ci
29381cb0ef41Sopenharmony_ci  const auto bitfield = BigInt::LengthBits::encode(1);
29391cb0ef41Sopenharmony_ci  __ Goto(&done, BuildAllocateBigInt(__ Int32Constant(bitfield), value));
29401cb0ef41Sopenharmony_ci
29411cb0ef41Sopenharmony_ci  __ Bind(&done);
29421cb0ef41Sopenharmony_ci  return done.PhiAt(0);
29431cb0ef41Sopenharmony_ci}
29441cb0ef41Sopenharmony_ci
29451cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerTruncateBigIntToWord64(Node* node) {
29461cb0ef41Sopenharmony_ci  DCHECK(machine()->Is64());
29471cb0ef41Sopenharmony_ci
29481cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kWord64);
29491cb0ef41Sopenharmony_ci  auto if_neg = __ MakeLabel();
29501cb0ef41Sopenharmony_ci  auto if_not_zero = __ MakeLabel();
29511cb0ef41Sopenharmony_ci
29521cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
29531cb0ef41Sopenharmony_ci
29541cb0ef41Sopenharmony_ci  Node* bitfield = __ LoadField(AccessBuilder::ForBigIntBitfield(), value);
29551cb0ef41Sopenharmony_ci  __ GotoIfNot(__ Word32Equal(bitfield, __ Int32Constant(0)), &if_not_zero);
29561cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int64Constant(0));
29571cb0ef41Sopenharmony_ci
29581cb0ef41Sopenharmony_ci  __ Bind(&if_not_zero);
29591cb0ef41Sopenharmony_ci  {
29601cb0ef41Sopenharmony_ci    Node* lsd =
29611cb0ef41Sopenharmony_ci        __ LoadField(AccessBuilder::ForBigIntLeastSignificantDigit64(), value);
29621cb0ef41Sopenharmony_ci    Node* sign =
29631cb0ef41Sopenharmony_ci        __ Word32And(bitfield, __ Int32Constant(BigInt::SignBits::kMask));
29641cb0ef41Sopenharmony_ci    __ GotoIf(__ Word32Equal(sign, __ Int32Constant(1)), &if_neg);
29651cb0ef41Sopenharmony_ci    __ Goto(&done, lsd);
29661cb0ef41Sopenharmony_ci
29671cb0ef41Sopenharmony_ci    __ Bind(&if_neg);
29681cb0ef41Sopenharmony_ci    __ Goto(&done, __ Int64Sub(__ Int64Constant(0), lsd));
29691cb0ef41Sopenharmony_ci  }
29701cb0ef41Sopenharmony_ci
29711cb0ef41Sopenharmony_ci  __ Bind(&done);
29721cb0ef41Sopenharmony_ci  return done.PhiAt(0);
29731cb0ef41Sopenharmony_ci}
29741cb0ef41Sopenharmony_ci
29751cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node) {
29761cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
29771cb0ef41Sopenharmony_ci
29781cb0ef41Sopenharmony_ci  auto if_not_smi = __ MakeDeferredLabel();
29791cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kWord32);
29801cb0ef41Sopenharmony_ci
29811cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
29821cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &if_not_smi);
29831cb0ef41Sopenharmony_ci  __ Goto(&done, ChangeSmiToInt32(value));
29841cb0ef41Sopenharmony_ci
29851cb0ef41Sopenharmony_ci  __ Bind(&if_not_smi);
29861cb0ef41Sopenharmony_ci  STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
29871cb0ef41Sopenharmony_ci                                    Oddball::kToNumberRawOffset);
29881cb0ef41Sopenharmony_ci  Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
29891cb0ef41Sopenharmony_ci  vfalse = __ TruncateFloat64ToWord32(vfalse);
29901cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
29911cb0ef41Sopenharmony_ci
29921cb0ef41Sopenharmony_ci  __ Bind(&done);
29931cb0ef41Sopenharmony_ci  return done.PhiAt(0);
29941cb0ef41Sopenharmony_ci}
29951cb0ef41Sopenharmony_ci
29961cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckedTruncateTaggedToWord32(
29971cb0ef41Sopenharmony_ci    Node* node, Node* frame_state) {
29981cb0ef41Sopenharmony_ci  const CheckTaggedInputParameters& params =
29991cb0ef41Sopenharmony_ci      CheckTaggedInputParametersOf(node->op());
30001cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
30011cb0ef41Sopenharmony_ci
30021cb0ef41Sopenharmony_ci  auto if_not_smi = __ MakeLabel();
30031cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kWord32);
30041cb0ef41Sopenharmony_ci
30051cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
30061cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &if_not_smi);
30071cb0ef41Sopenharmony_ci  // In the Smi case, just convert to int32.
30081cb0ef41Sopenharmony_ci  __ Goto(&done, ChangeSmiToInt32(value));
30091cb0ef41Sopenharmony_ci
30101cb0ef41Sopenharmony_ci  // Otherwise, check that it's a heap number or oddball and truncate the value
30111cb0ef41Sopenharmony_ci  // to int32.
30121cb0ef41Sopenharmony_ci  __ Bind(&if_not_smi);
30131cb0ef41Sopenharmony_ci  Node* number = BuildCheckedHeapNumberOrOddballToFloat64(
30141cb0ef41Sopenharmony_ci      params.mode(), params.feedback(), value, frame_state);
30151cb0ef41Sopenharmony_ci  number = __ TruncateFloat64ToWord32(number);
30161cb0ef41Sopenharmony_ci  __ Goto(&done, number);
30171cb0ef41Sopenharmony_ci
30181cb0ef41Sopenharmony_ci  __ Bind(&done);
30191cb0ef41Sopenharmony_ci  return done.PhiAt(0);
30201cb0ef41Sopenharmony_ci}
30211cb0ef41Sopenharmony_ci
30221cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerAllocate(Node* node) {
30231cb0ef41Sopenharmony_ci  Node* size = node->InputAt(0);
30241cb0ef41Sopenharmony_ci  AllocationType allocation = AllocationTypeOf(node->op());
30251cb0ef41Sopenharmony_ci  Node* new_node = __ Allocate(allocation, size);
30261cb0ef41Sopenharmony_ci  return new_node;
30271cb0ef41Sopenharmony_ci}
30281cb0ef41Sopenharmony_ci
30291cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerNumberToString(Node* node) {
30301cb0ef41Sopenharmony_ci  Node* argument = node->InputAt(0);
30311cb0ef41Sopenharmony_ci
30321cb0ef41Sopenharmony_ci  Callable const callable =
30331cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kNumberToString);
30341cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kEliminatable;
30351cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
30361cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
30371cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
30381cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), flags, properties);
30391cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ HeapConstant(callable.code()), argument,
30401cb0ef41Sopenharmony_ci                 __ NoContextConstant());
30411cb0ef41Sopenharmony_ci}
30421cb0ef41Sopenharmony_ci
30431cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsArrayBufferView(Node* node) {
30441cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
30451cb0ef41Sopenharmony_ci
30461cb0ef41Sopenharmony_ci  auto if_smi = __ MakeDeferredLabel();
30471cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
30481cb0ef41Sopenharmony_ci
30491cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
30501cb0ef41Sopenharmony_ci  __ GotoIf(check, &if_smi);
30511cb0ef41Sopenharmony_ci
30521cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
30531cb0ef41Sopenharmony_ci  Node* value_instance_type =
30541cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
30551cb0ef41Sopenharmony_ci  Node* vfalse = __ Uint32LessThan(
30561cb0ef41Sopenharmony_ci      __ Int32Sub(value_instance_type,
30571cb0ef41Sopenharmony_ci                  __ Int32Constant(FIRST_JS_ARRAY_BUFFER_VIEW_TYPE)),
30581cb0ef41Sopenharmony_ci      __ Int32Constant(LAST_JS_ARRAY_BUFFER_VIEW_TYPE -
30591cb0ef41Sopenharmony_ci                       FIRST_JS_ARRAY_BUFFER_VIEW_TYPE + 1));
30601cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
30611cb0ef41Sopenharmony_ci
30621cb0ef41Sopenharmony_ci  __ Bind(&if_smi);
30631cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int32Constant(0));
30641cb0ef41Sopenharmony_ci
30651cb0ef41Sopenharmony_ci  __ Bind(&done);
30661cb0ef41Sopenharmony_ci  return done.PhiAt(0);
30671cb0ef41Sopenharmony_ci}
30681cb0ef41Sopenharmony_ci
30691cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsBigInt(Node* node) {
30701cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
30711cb0ef41Sopenharmony_ci
30721cb0ef41Sopenharmony_ci  auto if_smi = __ MakeDeferredLabel();
30731cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
30741cb0ef41Sopenharmony_ci
30751cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
30761cb0ef41Sopenharmony_ci  __ GotoIf(check, &if_smi);
30771cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
30781cb0ef41Sopenharmony_ci  Node* vfalse = __ TaggedEqual(value_map, __ BigIntMapConstant());
30791cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
30801cb0ef41Sopenharmony_ci
30811cb0ef41Sopenharmony_ci  __ Bind(&if_smi);
30821cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int32Constant(0));
30831cb0ef41Sopenharmony_ci
30841cb0ef41Sopenharmony_ci  __ Bind(&done);
30851cb0ef41Sopenharmony_ci  return done.PhiAt(0);
30861cb0ef41Sopenharmony_ci}
30871cb0ef41Sopenharmony_ci
30881cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsCallable(Node* node) {
30891cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
30901cb0ef41Sopenharmony_ci
30911cb0ef41Sopenharmony_ci  auto if_smi = __ MakeDeferredLabel();
30921cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
30931cb0ef41Sopenharmony_ci
30941cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
30951cb0ef41Sopenharmony_ci  __ GotoIf(check, &if_smi);
30961cb0ef41Sopenharmony_ci
30971cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
30981cb0ef41Sopenharmony_ci  Node* value_bit_field =
30991cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapBitField(), value_map);
31001cb0ef41Sopenharmony_ci  Node* vfalse = __ Word32Equal(
31011cb0ef41Sopenharmony_ci      __ Int32Constant(Map::Bits1::IsCallableBit::kMask),
31021cb0ef41Sopenharmony_ci      __ Word32And(value_bit_field,
31031cb0ef41Sopenharmony_ci                   __ Int32Constant(Map::Bits1::IsCallableBit::kMask)));
31041cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
31051cb0ef41Sopenharmony_ci
31061cb0ef41Sopenharmony_ci  __ Bind(&if_smi);
31071cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int32Constant(0));
31081cb0ef41Sopenharmony_ci
31091cb0ef41Sopenharmony_ci  __ Bind(&done);
31101cb0ef41Sopenharmony_ci  return done.PhiAt(0);
31111cb0ef41Sopenharmony_ci}
31121cb0ef41Sopenharmony_ci
31131cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsConstructor(Node* node) {
31141cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
31151cb0ef41Sopenharmony_ci
31161cb0ef41Sopenharmony_ci  auto if_smi = __ MakeDeferredLabel();
31171cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
31181cb0ef41Sopenharmony_ci
31191cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
31201cb0ef41Sopenharmony_ci  __ GotoIf(check, &if_smi);
31211cb0ef41Sopenharmony_ci
31221cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
31231cb0ef41Sopenharmony_ci  Node* value_bit_field =
31241cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapBitField(), value_map);
31251cb0ef41Sopenharmony_ci  Node* vfalse = __ Word32Equal(
31261cb0ef41Sopenharmony_ci      __ Int32Constant(Map::Bits1::IsConstructorBit::kMask),
31271cb0ef41Sopenharmony_ci      __ Word32And(value_bit_field,
31281cb0ef41Sopenharmony_ci                   __ Int32Constant(Map::Bits1::IsConstructorBit::kMask)));
31291cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
31301cb0ef41Sopenharmony_ci
31311cb0ef41Sopenharmony_ci  __ Bind(&if_smi);
31321cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int32Constant(0));
31331cb0ef41Sopenharmony_ci
31341cb0ef41Sopenharmony_ci  __ Bind(&done);
31351cb0ef41Sopenharmony_ci  return done.PhiAt(0);
31361cb0ef41Sopenharmony_ci}
31371cb0ef41Sopenharmony_ci
31381cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsDetectableCallable(Node* node) {
31391cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
31401cb0ef41Sopenharmony_ci
31411cb0ef41Sopenharmony_ci  auto if_smi = __ MakeDeferredLabel();
31421cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
31431cb0ef41Sopenharmony_ci
31441cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
31451cb0ef41Sopenharmony_ci  __ GotoIf(check, &if_smi);
31461cb0ef41Sopenharmony_ci
31471cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
31481cb0ef41Sopenharmony_ci  Node* value_bit_field =
31491cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapBitField(), value_map);
31501cb0ef41Sopenharmony_ci  Node* vfalse = __ Word32Equal(
31511cb0ef41Sopenharmony_ci      __ Int32Constant(Map::Bits1::IsCallableBit::kMask),
31521cb0ef41Sopenharmony_ci      __ Word32And(value_bit_field,
31531cb0ef41Sopenharmony_ci                   __ Int32Constant((Map::Bits1::IsCallableBit::kMask) |
31541cb0ef41Sopenharmony_ci                                    (Map::Bits1::IsUndetectableBit::kMask))));
31551cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
31561cb0ef41Sopenharmony_ci
31571cb0ef41Sopenharmony_ci  __ Bind(&if_smi);
31581cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int32Constant(0));
31591cb0ef41Sopenharmony_ci
31601cb0ef41Sopenharmony_ci  __ Bind(&done);
31611cb0ef41Sopenharmony_ci  return done.PhiAt(0);
31621cb0ef41Sopenharmony_ci}
31631cb0ef41Sopenharmony_ci
31641cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerNumberIsFloat64Hole(Node* node) {
31651cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
31661cb0ef41Sopenharmony_ci  Node* check = __ Word32Equal(__ Float64ExtractHighWord32(value),
31671cb0ef41Sopenharmony_ci                               __ Int32Constant(kHoleNanUpper32));
31681cb0ef41Sopenharmony_ci  return check;
31691cb0ef41Sopenharmony_ci}
31701cb0ef41Sopenharmony_ci
31711cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerNumberIsFinite(Node* node) {
31721cb0ef41Sopenharmony_ci  Node* number = node->InputAt(0);
31731cb0ef41Sopenharmony_ci  Node* diff = __ Float64Sub(number, number);
31741cb0ef41Sopenharmony_ci  Node* check = __ Float64Equal(diff, diff);
31751cb0ef41Sopenharmony_ci  return check;
31761cb0ef41Sopenharmony_ci}
31771cb0ef41Sopenharmony_ci
31781cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsFiniteNumber(Node* node) {
31791cb0ef41Sopenharmony_ci  Node* object = node->InputAt(0);
31801cb0ef41Sopenharmony_ci  Node* zero = __ Int32Constant(0);
31811cb0ef41Sopenharmony_ci  Node* one = __ Int32Constant(1);
31821cb0ef41Sopenharmony_ci
31831cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
31841cb0ef41Sopenharmony_ci
31851cb0ef41Sopenharmony_ci  // Check if {object} is a Smi.
31861cb0ef41Sopenharmony_ci  __ GotoIf(ObjectIsSmi(object), &done, one);
31871cb0ef41Sopenharmony_ci
31881cb0ef41Sopenharmony_ci  // Check if {object} is a HeapNumber.
31891cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), object);
31901cb0ef41Sopenharmony_ci  __ GotoIfNot(__ TaggedEqual(value_map, __ HeapNumberMapConstant()), &done,
31911cb0ef41Sopenharmony_ci               zero);
31921cb0ef41Sopenharmony_ci
31931cb0ef41Sopenharmony_ci  // {object} is a HeapNumber.
31941cb0ef41Sopenharmony_ci  Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), object);
31951cb0ef41Sopenharmony_ci  Node* diff = __ Float64Sub(value, value);
31961cb0ef41Sopenharmony_ci  Node* check = __ Float64Equal(diff, diff);
31971cb0ef41Sopenharmony_ci  __ Goto(&done, check);
31981cb0ef41Sopenharmony_ci
31991cb0ef41Sopenharmony_ci  __ Bind(&done);
32001cb0ef41Sopenharmony_ci  return done.PhiAt(0);
32011cb0ef41Sopenharmony_ci}
32021cb0ef41Sopenharmony_ci
32031cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerNumberIsInteger(Node* node) {
32041cb0ef41Sopenharmony_ci  Node* number = node->InputAt(0);
32051cb0ef41Sopenharmony_ci  Node* trunc = BuildFloat64RoundTruncate(number);
32061cb0ef41Sopenharmony_ci  Node* diff = __ Float64Sub(number, trunc);
32071cb0ef41Sopenharmony_ci  Node* check = __ Float64Equal(diff, __ Float64Constant(0));
32081cb0ef41Sopenharmony_ci  return check;
32091cb0ef41Sopenharmony_ci}
32101cb0ef41Sopenharmony_ci
32111cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsInteger(Node* node) {
32121cb0ef41Sopenharmony_ci  Node* object = node->InputAt(0);
32131cb0ef41Sopenharmony_ci  Node* zero = __ Int32Constant(0);
32141cb0ef41Sopenharmony_ci  Node* one = __ Int32Constant(1);
32151cb0ef41Sopenharmony_ci
32161cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
32171cb0ef41Sopenharmony_ci
32181cb0ef41Sopenharmony_ci  // Check if {object} is a Smi.
32191cb0ef41Sopenharmony_ci  __ GotoIf(ObjectIsSmi(object), &done, one);
32201cb0ef41Sopenharmony_ci
32211cb0ef41Sopenharmony_ci  // Check if {object} is a HeapNumber.
32221cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), object);
32231cb0ef41Sopenharmony_ci  __ GotoIfNot(__ TaggedEqual(value_map, __ HeapNumberMapConstant()), &done,
32241cb0ef41Sopenharmony_ci               zero);
32251cb0ef41Sopenharmony_ci
32261cb0ef41Sopenharmony_ci  // {object} is a HeapNumber.
32271cb0ef41Sopenharmony_ci  Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), object);
32281cb0ef41Sopenharmony_ci  Node* trunc = BuildFloat64RoundTruncate(value);
32291cb0ef41Sopenharmony_ci  Node* diff = __ Float64Sub(value, trunc);
32301cb0ef41Sopenharmony_ci  Node* check = __ Float64Equal(diff, __ Float64Constant(0));
32311cb0ef41Sopenharmony_ci  __ Goto(&done, check);
32321cb0ef41Sopenharmony_ci
32331cb0ef41Sopenharmony_ci  __ Bind(&done);
32341cb0ef41Sopenharmony_ci  return done.PhiAt(0);
32351cb0ef41Sopenharmony_ci}
32361cb0ef41Sopenharmony_ci
32371cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerNumberIsSafeInteger(Node* node) {
32381cb0ef41Sopenharmony_ci  Node* number = node->InputAt(0);
32391cb0ef41Sopenharmony_ci  Node* zero = __ Int32Constant(0);
32401cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
32411cb0ef41Sopenharmony_ci
32421cb0ef41Sopenharmony_ci  Node* trunc = BuildFloat64RoundTruncate(number);
32431cb0ef41Sopenharmony_ci  Node* diff = __ Float64Sub(number, trunc);
32441cb0ef41Sopenharmony_ci  Node* check = __ Float64Equal(diff, __ Float64Constant(0));
32451cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &done, zero);
32461cb0ef41Sopenharmony_ci  Node* in_range = __ Float64LessThanOrEqual(
32471cb0ef41Sopenharmony_ci      __ Float64Abs(trunc), __ Float64Constant(kMaxSafeInteger));
32481cb0ef41Sopenharmony_ci  __ Goto(&done, in_range);
32491cb0ef41Sopenharmony_ci
32501cb0ef41Sopenharmony_ci  __ Bind(&done);
32511cb0ef41Sopenharmony_ci  return done.PhiAt(0);
32521cb0ef41Sopenharmony_ci}
32531cb0ef41Sopenharmony_ci
32541cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsSafeInteger(Node* node) {
32551cb0ef41Sopenharmony_ci  Node* object = node->InputAt(0);
32561cb0ef41Sopenharmony_ci  Node* zero = __ Int32Constant(0);
32571cb0ef41Sopenharmony_ci  Node* one = __ Int32Constant(1);
32581cb0ef41Sopenharmony_ci
32591cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
32601cb0ef41Sopenharmony_ci
32611cb0ef41Sopenharmony_ci  // Check if {object} is a Smi.
32621cb0ef41Sopenharmony_ci  __ GotoIf(ObjectIsSmi(object), &done, one);
32631cb0ef41Sopenharmony_ci
32641cb0ef41Sopenharmony_ci  // Check if {object} is a HeapNumber.
32651cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), object);
32661cb0ef41Sopenharmony_ci  __ GotoIfNot(__ TaggedEqual(value_map, __ HeapNumberMapConstant()), &done,
32671cb0ef41Sopenharmony_ci               zero);
32681cb0ef41Sopenharmony_ci
32691cb0ef41Sopenharmony_ci  // {object} is a HeapNumber.
32701cb0ef41Sopenharmony_ci  Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), object);
32711cb0ef41Sopenharmony_ci  Node* trunc = BuildFloat64RoundTruncate(value);
32721cb0ef41Sopenharmony_ci  Node* diff = __ Float64Sub(value, trunc);
32731cb0ef41Sopenharmony_ci  Node* check = __ Float64Equal(diff, __ Float64Constant(0));
32741cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &done, zero);
32751cb0ef41Sopenharmony_ci  Node* in_range = __ Float64LessThanOrEqual(
32761cb0ef41Sopenharmony_ci      __ Float64Abs(trunc), __ Float64Constant(kMaxSafeInteger));
32771cb0ef41Sopenharmony_ci  __ Goto(&done, in_range);
32781cb0ef41Sopenharmony_ci
32791cb0ef41Sopenharmony_ci  __ Bind(&done);
32801cb0ef41Sopenharmony_ci  return done.PhiAt(0);
32811cb0ef41Sopenharmony_ci}
32821cb0ef41Sopenharmony_ci
32831cb0ef41Sopenharmony_cinamespace {
32841cb0ef41Sopenharmony_ci
32851cb0ef41Sopenharmony_ci// There is no (currently) available constexpr version of bit_cast, so we have
32861cb0ef41Sopenharmony_ci// to make do with constructing the -0.0 bits manually (by setting the sign bit
32871cb0ef41Sopenharmony_ci// to 1 and everything else to 0).
32881cb0ef41Sopenharmony_ci// TODO(leszeks): Revisit when upgrading to C++20.
32891cb0ef41Sopenharmony_ciconstexpr int32_t kMinusZeroLoBits = static_cast<int32_t>(0);
32901cb0ef41Sopenharmony_ciconstexpr int32_t kMinusZeroHiBits = static_cast<int32_t>(1) << 31;
32911cb0ef41Sopenharmony_ciconstexpr int64_t kMinusZeroBits =
32921cb0ef41Sopenharmony_ci    (static_cast<uint64_t>(kMinusZeroHiBits) << 32) | kMinusZeroLoBits;
32931cb0ef41Sopenharmony_ci
32941cb0ef41Sopenharmony_ci}  // namespace
32951cb0ef41Sopenharmony_ci
32961cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsMinusZero(Node* node) {
32971cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
32981cb0ef41Sopenharmony_ci  Node* zero = __ Int32Constant(0);
32991cb0ef41Sopenharmony_ci
33001cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
33011cb0ef41Sopenharmony_ci
33021cb0ef41Sopenharmony_ci  // Check if {value} is a Smi.
33031cb0ef41Sopenharmony_ci  __ GotoIf(ObjectIsSmi(value), &done, zero);
33041cb0ef41Sopenharmony_ci
33051cb0ef41Sopenharmony_ci  // Check if {value} is a HeapNumber.
33061cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
33071cb0ef41Sopenharmony_ci  __ GotoIfNot(__ TaggedEqual(value_map, __ HeapNumberMapConstant()), &done,
33081cb0ef41Sopenharmony_ci               zero);
33091cb0ef41Sopenharmony_ci
33101cb0ef41Sopenharmony_ci  // Check if {value} contains -0.
33111cb0ef41Sopenharmony_ci  Node* value_value = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
33121cb0ef41Sopenharmony_ci  if (machine()->Is64()) {
33131cb0ef41Sopenharmony_ci    Node* value64 = __ BitcastFloat64ToInt64(value_value);
33141cb0ef41Sopenharmony_ci    __ Goto(&done, __ Word64Equal(value64, __ Int64Constant(kMinusZeroBits)));
33151cb0ef41Sopenharmony_ci  } else {
33161cb0ef41Sopenharmony_ci    Node* value_lo = __ Float64ExtractLowWord32(value_value);
33171cb0ef41Sopenharmony_ci    __ GotoIfNot(__ Word32Equal(value_lo, __ Int32Constant(kMinusZeroLoBits)),
33181cb0ef41Sopenharmony_ci                 &done, zero);
33191cb0ef41Sopenharmony_ci    Node* value_hi = __ Float64ExtractHighWord32(value_value);
33201cb0ef41Sopenharmony_ci    __ Goto(&done,
33211cb0ef41Sopenharmony_ci            __ Word32Equal(value_hi, __ Int32Constant(kMinusZeroHiBits)));
33221cb0ef41Sopenharmony_ci  }
33231cb0ef41Sopenharmony_ci
33241cb0ef41Sopenharmony_ci  __ Bind(&done);
33251cb0ef41Sopenharmony_ci  return done.PhiAt(0);
33261cb0ef41Sopenharmony_ci}
33271cb0ef41Sopenharmony_ci
33281cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerNumberIsMinusZero(Node* node) {
33291cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
33301cb0ef41Sopenharmony_ci
33311cb0ef41Sopenharmony_ci  if (machine()->Is64()) {
33321cb0ef41Sopenharmony_ci    Node* value64 = __ BitcastFloat64ToInt64(value);
33331cb0ef41Sopenharmony_ci    return __ Word64Equal(value64, __ Int64Constant(kMinusZeroBits));
33341cb0ef41Sopenharmony_ci  } else {
33351cb0ef41Sopenharmony_ci    auto done = __ MakeLabel(MachineRepresentation::kBit);
33361cb0ef41Sopenharmony_ci
33371cb0ef41Sopenharmony_ci    Node* value_lo = __ Float64ExtractLowWord32(value);
33381cb0ef41Sopenharmony_ci    __ GotoIfNot(__ Word32Equal(value_lo, __ Int32Constant(kMinusZeroLoBits)),
33391cb0ef41Sopenharmony_ci                 &done, __ Int32Constant(0));
33401cb0ef41Sopenharmony_ci    Node* value_hi = __ Float64ExtractHighWord32(value);
33411cb0ef41Sopenharmony_ci    __ Goto(&done,
33421cb0ef41Sopenharmony_ci            __ Word32Equal(value_hi, __ Int32Constant(kMinusZeroHiBits)));
33431cb0ef41Sopenharmony_ci
33441cb0ef41Sopenharmony_ci    __ Bind(&done);
33451cb0ef41Sopenharmony_ci    return done.PhiAt(0);
33461cb0ef41Sopenharmony_ci  }
33471cb0ef41Sopenharmony_ci}
33481cb0ef41Sopenharmony_ci
33491cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsNaN(Node* node) {
33501cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
33511cb0ef41Sopenharmony_ci  Node* zero = __ Int32Constant(0);
33521cb0ef41Sopenharmony_ci
33531cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
33541cb0ef41Sopenharmony_ci
33551cb0ef41Sopenharmony_ci  // Check if {value} is a Smi.
33561cb0ef41Sopenharmony_ci  __ GotoIf(ObjectIsSmi(value), &done, zero);
33571cb0ef41Sopenharmony_ci
33581cb0ef41Sopenharmony_ci  // Check if {value} is a HeapNumber.
33591cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
33601cb0ef41Sopenharmony_ci  __ GotoIfNot(__ TaggedEqual(value_map, __ HeapNumberMapConstant()), &done,
33611cb0ef41Sopenharmony_ci               zero);
33621cb0ef41Sopenharmony_ci
33631cb0ef41Sopenharmony_ci  // Check if {value} contains a NaN.
33641cb0ef41Sopenharmony_ci  Node* value_value = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
33651cb0ef41Sopenharmony_ci  __ Goto(&done,
33661cb0ef41Sopenharmony_ci          __ Word32Equal(__ Float64Equal(value_value, value_value), zero));
33671cb0ef41Sopenharmony_ci
33681cb0ef41Sopenharmony_ci  __ Bind(&done);
33691cb0ef41Sopenharmony_ci  return done.PhiAt(0);
33701cb0ef41Sopenharmony_ci}
33711cb0ef41Sopenharmony_ci
33721cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerNumberIsNaN(Node* node) {
33731cb0ef41Sopenharmony_ci  Node* number = node->InputAt(0);
33741cb0ef41Sopenharmony_ci  Node* diff = __ Float64Equal(number, number);
33751cb0ef41Sopenharmony_ci  Node* check = __ Word32Equal(diff, __ Int32Constant(0));
33761cb0ef41Sopenharmony_ci  return check;
33771cb0ef41Sopenharmony_ci}
33781cb0ef41Sopenharmony_ci
33791cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsNonCallable(Node* node) {
33801cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
33811cb0ef41Sopenharmony_ci
33821cb0ef41Sopenharmony_ci  auto if_primitive = __ MakeDeferredLabel();
33831cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
33841cb0ef41Sopenharmony_ci
33851cb0ef41Sopenharmony_ci  Node* check0 = ObjectIsSmi(value);
33861cb0ef41Sopenharmony_ci  __ GotoIf(check0, &if_primitive);
33871cb0ef41Sopenharmony_ci
33881cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
33891cb0ef41Sopenharmony_ci  Node* value_instance_type =
33901cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
33911cb0ef41Sopenharmony_ci  STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
33921cb0ef41Sopenharmony_ci  Node* check1 = __ Uint32LessThanOrEqual(
33931cb0ef41Sopenharmony_ci      __ Uint32Constant(FIRST_JS_RECEIVER_TYPE), value_instance_type);
33941cb0ef41Sopenharmony_ci  __ GotoIfNot(check1, &if_primitive);
33951cb0ef41Sopenharmony_ci
33961cb0ef41Sopenharmony_ci  Node* value_bit_field =
33971cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapBitField(), value_map);
33981cb0ef41Sopenharmony_ci  Node* check2 = __ Word32Equal(
33991cb0ef41Sopenharmony_ci      __ Int32Constant(0),
34001cb0ef41Sopenharmony_ci      __ Word32And(value_bit_field,
34011cb0ef41Sopenharmony_ci                   __ Int32Constant(Map::Bits1::IsCallableBit::kMask)));
34021cb0ef41Sopenharmony_ci  __ Goto(&done, check2);
34031cb0ef41Sopenharmony_ci
34041cb0ef41Sopenharmony_ci  __ Bind(&if_primitive);
34051cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int32Constant(0));
34061cb0ef41Sopenharmony_ci
34071cb0ef41Sopenharmony_ci  __ Bind(&done);
34081cb0ef41Sopenharmony_ci  return done.PhiAt(0);
34091cb0ef41Sopenharmony_ci}
34101cb0ef41Sopenharmony_ci
34111cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsNumber(Node* node) {
34121cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
34131cb0ef41Sopenharmony_ci
34141cb0ef41Sopenharmony_ci  auto if_smi = __ MakeLabel();
34151cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
34161cb0ef41Sopenharmony_ci
34171cb0ef41Sopenharmony_ci  __ GotoIf(ObjectIsSmi(value), &if_smi);
34181cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
34191cb0ef41Sopenharmony_ci  __ Goto(&done, __ TaggedEqual(value_map, __ HeapNumberMapConstant()));
34201cb0ef41Sopenharmony_ci
34211cb0ef41Sopenharmony_ci  __ Bind(&if_smi);
34221cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int32Constant(1));
34231cb0ef41Sopenharmony_ci
34241cb0ef41Sopenharmony_ci  __ Bind(&done);
34251cb0ef41Sopenharmony_ci  return done.PhiAt(0);
34261cb0ef41Sopenharmony_ci}
34271cb0ef41Sopenharmony_ci
34281cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsReceiver(Node* node) {
34291cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
34301cb0ef41Sopenharmony_ci
34311cb0ef41Sopenharmony_ci  auto if_smi = __ MakeDeferredLabel();
34321cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
34331cb0ef41Sopenharmony_ci
34341cb0ef41Sopenharmony_ci  __ GotoIf(ObjectIsSmi(value), &if_smi);
34351cb0ef41Sopenharmony_ci
34361cb0ef41Sopenharmony_ci  STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
34371cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
34381cb0ef41Sopenharmony_ci  Node* value_instance_type =
34391cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
34401cb0ef41Sopenharmony_ci  Node* result = __ Uint32LessThanOrEqual(
34411cb0ef41Sopenharmony_ci      __ Uint32Constant(FIRST_JS_RECEIVER_TYPE), value_instance_type);
34421cb0ef41Sopenharmony_ci  __ Goto(&done, result);
34431cb0ef41Sopenharmony_ci
34441cb0ef41Sopenharmony_ci  __ Bind(&if_smi);
34451cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int32Constant(0));
34461cb0ef41Sopenharmony_ci
34471cb0ef41Sopenharmony_ci  __ Bind(&done);
34481cb0ef41Sopenharmony_ci  return done.PhiAt(0);
34491cb0ef41Sopenharmony_ci}
34501cb0ef41Sopenharmony_ci
34511cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsSmi(Node* node) {
34521cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
34531cb0ef41Sopenharmony_ci  return ObjectIsSmi(value);
34541cb0ef41Sopenharmony_ci}
34551cb0ef41Sopenharmony_ci
34561cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsString(Node* node) {
34571cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
34581cb0ef41Sopenharmony_ci
34591cb0ef41Sopenharmony_ci  auto if_smi = __ MakeDeferredLabel();
34601cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
34611cb0ef41Sopenharmony_ci
34621cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
34631cb0ef41Sopenharmony_ci  __ GotoIf(check, &if_smi);
34641cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
34651cb0ef41Sopenharmony_ci  Node* value_instance_type =
34661cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
34671cb0ef41Sopenharmony_ci  Node* vfalse = __ Uint32LessThan(value_instance_type,
34681cb0ef41Sopenharmony_ci                                   __ Uint32Constant(FIRST_NONSTRING_TYPE));
34691cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
34701cb0ef41Sopenharmony_ci
34711cb0ef41Sopenharmony_ci  __ Bind(&if_smi);
34721cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int32Constant(0));
34731cb0ef41Sopenharmony_ci
34741cb0ef41Sopenharmony_ci  __ Bind(&done);
34751cb0ef41Sopenharmony_ci  return done.PhiAt(0);
34761cb0ef41Sopenharmony_ci}
34771cb0ef41Sopenharmony_ci
34781cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsSymbol(Node* node) {
34791cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
34801cb0ef41Sopenharmony_ci
34811cb0ef41Sopenharmony_ci  auto if_smi = __ MakeDeferredLabel();
34821cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
34831cb0ef41Sopenharmony_ci
34841cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
34851cb0ef41Sopenharmony_ci  __ GotoIf(check, &if_smi);
34861cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
34871cb0ef41Sopenharmony_ci  Node* value_instance_type =
34881cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
34891cb0ef41Sopenharmony_ci  Node* vfalse =
34901cb0ef41Sopenharmony_ci      __ Word32Equal(value_instance_type, __ Uint32Constant(SYMBOL_TYPE));
34911cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
34921cb0ef41Sopenharmony_ci
34931cb0ef41Sopenharmony_ci  __ Bind(&if_smi);
34941cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int32Constant(0));
34951cb0ef41Sopenharmony_ci
34961cb0ef41Sopenharmony_ci  __ Bind(&done);
34971cb0ef41Sopenharmony_ci  return done.PhiAt(0);
34981cb0ef41Sopenharmony_ci}
34991cb0ef41Sopenharmony_ci
35001cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerObjectIsUndetectable(Node* node) {
35011cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
35021cb0ef41Sopenharmony_ci
35031cb0ef41Sopenharmony_ci  auto if_smi = __ MakeDeferredLabel();
35041cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
35051cb0ef41Sopenharmony_ci
35061cb0ef41Sopenharmony_ci  Node* check = ObjectIsSmi(value);
35071cb0ef41Sopenharmony_ci  __ GotoIf(check, &if_smi);
35081cb0ef41Sopenharmony_ci
35091cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
35101cb0ef41Sopenharmony_ci  Node* value_bit_field =
35111cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapBitField(), value_map);
35121cb0ef41Sopenharmony_ci  Node* vfalse = __ Word32Equal(
35131cb0ef41Sopenharmony_ci      __ Word32Equal(
35141cb0ef41Sopenharmony_ci          __ Int32Constant(0),
35151cb0ef41Sopenharmony_ci          __ Word32And(value_bit_field,
35161cb0ef41Sopenharmony_ci                       __ Int32Constant(Map::Bits1::IsUndetectableBit::kMask))),
35171cb0ef41Sopenharmony_ci      __ Int32Constant(0));
35181cb0ef41Sopenharmony_ci  __ Goto(&done, vfalse);
35191cb0ef41Sopenharmony_ci
35201cb0ef41Sopenharmony_ci  __ Bind(&if_smi);
35211cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int32Constant(0));
35221cb0ef41Sopenharmony_ci
35231cb0ef41Sopenharmony_ci  __ Bind(&done);
35241cb0ef41Sopenharmony_ci  return done.PhiAt(0);
35251cb0ef41Sopenharmony_ci}
35261cb0ef41Sopenharmony_ci
35271cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerTypeOf(Node* node) {
35281cb0ef41Sopenharmony_ci  Node* obj = node->InputAt(0);
35291cb0ef41Sopenharmony_ci  Callable const callable = Builtins::CallableFor(isolate(), Builtin::kTypeof);
35301cb0ef41Sopenharmony_ci  Operator::Properties const properties = Operator::kEliminatable;
35311cb0ef41Sopenharmony_ci  CallDescriptor::Flags const flags = CallDescriptor::kNoAllocate;
35321cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
35331cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
35341cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), flags, properties);
35351cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ HeapConstant(callable.code()), obj,
35361cb0ef41Sopenharmony_ci                 __ NoContextConstant());
35371cb0ef41Sopenharmony_ci}
35381cb0ef41Sopenharmony_ci
35391cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerToBoolean(Node* node) {
35401cb0ef41Sopenharmony_ci  Node* obj = node->InputAt(0);
35411cb0ef41Sopenharmony_ci  Callable const callable =
35421cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kToBoolean);
35431cb0ef41Sopenharmony_ci  Operator::Properties const properties = Operator::kEliminatable;
35441cb0ef41Sopenharmony_ci  CallDescriptor::Flags const flags = CallDescriptor::kNoAllocate;
35451cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
35461cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
35471cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), flags, properties);
35481cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ HeapConstant(callable.code()), obj);
35491cb0ef41Sopenharmony_ci}
35501cb0ef41Sopenharmony_ci
35511cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerArgumentsLength(Node* node) {
35521cb0ef41Sopenharmony_ci  Node* arguments_length = ChangeIntPtrToSmi(
35531cb0ef41Sopenharmony_ci      __ Load(MachineType::Pointer(), __ LoadFramePointer(),
35541cb0ef41Sopenharmony_ci              __ IntPtrConstant(StandardFrameConstants::kArgCOffset)));
35551cb0ef41Sopenharmony_ci  arguments_length =
35561cb0ef41Sopenharmony_ci      __ SmiSub(arguments_length, __ SmiConstant(kJSArgcReceiverSlots));
35571cb0ef41Sopenharmony_ci  return arguments_length;
35581cb0ef41Sopenharmony_ci}
35591cb0ef41Sopenharmony_ci
35601cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerRestLength(Node* node) {
35611cb0ef41Sopenharmony_ci  int formal_parameter_count = FormalParameterCountOf(node->op());
35621cb0ef41Sopenharmony_ci  DCHECK_LE(0, formal_parameter_count);
35631cb0ef41Sopenharmony_ci
35641cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTaggedSigned);
35651cb0ef41Sopenharmony_ci  Node* frame = __ LoadFramePointer();
35661cb0ef41Sopenharmony_ci
35671cb0ef41Sopenharmony_ci  Node* arguments_length = ChangeIntPtrToSmi(
35681cb0ef41Sopenharmony_ci      __ Load(MachineType::Pointer(), frame,
35691cb0ef41Sopenharmony_ci              __ IntPtrConstant(StandardFrameConstants::kArgCOffset)));
35701cb0ef41Sopenharmony_ci  arguments_length =
35711cb0ef41Sopenharmony_ci      __ SmiSub(arguments_length, __ SmiConstant(kJSArgcReceiverSlots));
35721cb0ef41Sopenharmony_ci  Node* rest_length =
35731cb0ef41Sopenharmony_ci      __ SmiSub(arguments_length, __ SmiConstant(formal_parameter_count));
35741cb0ef41Sopenharmony_ci  __ GotoIf(__ SmiLessThan(rest_length, __ SmiConstant(0)), &done,
35751cb0ef41Sopenharmony_ci            __ SmiConstant(0));
35761cb0ef41Sopenharmony_ci  __ Goto(&done, rest_length);
35771cb0ef41Sopenharmony_ci
35781cb0ef41Sopenharmony_ci  __ Bind(&done);
35791cb0ef41Sopenharmony_ci  return done.PhiAt(0);
35801cb0ef41Sopenharmony_ci}
35811cb0ef41Sopenharmony_ci
35821cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerNewDoubleElements(Node* node) {
35831cb0ef41Sopenharmony_ci  AllocationType const allocation = AllocationTypeOf(node->op());
35841cb0ef41Sopenharmony_ci  Node* length = node->InputAt(0);
35851cb0ef41Sopenharmony_ci
35861cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer);
35871cb0ef41Sopenharmony_ci  Node* zero_length = __ IntPtrEqual(length, __ IntPtrConstant(0));
35881cb0ef41Sopenharmony_ci  __ GotoIf(zero_length, &done,
35891cb0ef41Sopenharmony_ci            __ HeapConstant(factory()->empty_fixed_array()));
35901cb0ef41Sopenharmony_ci
35911cb0ef41Sopenharmony_ci  // Compute the effective size of the backing store.
35921cb0ef41Sopenharmony_ci  Node* size = __ IntAdd(__ WordShl(length, __ IntPtrConstant(kDoubleSizeLog2)),
35931cb0ef41Sopenharmony_ci                         __ IntPtrConstant(FixedDoubleArray::kHeaderSize));
35941cb0ef41Sopenharmony_ci
35951cb0ef41Sopenharmony_ci  // Allocate the result and initialize the header.
35961cb0ef41Sopenharmony_ci  Node* result = __ Allocate(allocation, size);
35971cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForMap(), result,
35981cb0ef41Sopenharmony_ci                __ FixedDoubleArrayMapConstant());
35991cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForFixedArrayLength(), result,
36001cb0ef41Sopenharmony_ci                ChangeIntPtrToSmi(length));
36011cb0ef41Sopenharmony_ci
36021cb0ef41Sopenharmony_ci  // Initialize the backing store with holes.
36031cb0ef41Sopenharmony_ci  STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
36041cb0ef41Sopenharmony_ci                                    Oddball::kToNumberRawOffset);
36051cb0ef41Sopenharmony_ci  Node* the_hole =
36061cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForHeapNumberValue(), __ TheHoleConstant());
36071cb0ef41Sopenharmony_ci  auto loop = __ MakeLoopLabel(MachineType::PointerRepresentation());
36081cb0ef41Sopenharmony_ci  __ Goto(&loop, __ IntPtrConstant(0));
36091cb0ef41Sopenharmony_ci  __ Bind(&loop);
36101cb0ef41Sopenharmony_ci  {
36111cb0ef41Sopenharmony_ci    // Check if we've initialized everything.
36121cb0ef41Sopenharmony_ci    Node* index = loop.PhiAt(0);
36131cb0ef41Sopenharmony_ci    Node* check = __ UintLessThan(index, length);
36141cb0ef41Sopenharmony_ci    __ GotoIfNot(check, &done, result);
36151cb0ef41Sopenharmony_ci
36161cb0ef41Sopenharmony_ci    ElementAccess const access = {kTaggedBase, FixedDoubleArray::kHeaderSize,
36171cb0ef41Sopenharmony_ci                                  Type::NumberOrHole(), MachineType::Float64(),
36181cb0ef41Sopenharmony_ci                                  kNoWriteBarrier};
36191cb0ef41Sopenharmony_ci    __ StoreElement(access, result, index, the_hole);
36201cb0ef41Sopenharmony_ci
36211cb0ef41Sopenharmony_ci    // Advance the {index}.
36221cb0ef41Sopenharmony_ci    index = __ IntAdd(index, __ IntPtrConstant(1));
36231cb0ef41Sopenharmony_ci    __ Goto(&loop, index);
36241cb0ef41Sopenharmony_ci  }
36251cb0ef41Sopenharmony_ci
36261cb0ef41Sopenharmony_ci  __ Bind(&done);
36271cb0ef41Sopenharmony_ci  return done.PhiAt(0);
36281cb0ef41Sopenharmony_ci}
36291cb0ef41Sopenharmony_ci
36301cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerNewSmiOrObjectElements(Node* node) {
36311cb0ef41Sopenharmony_ci  AllocationType const allocation = AllocationTypeOf(node->op());
36321cb0ef41Sopenharmony_ci  Node* length = node->InputAt(0);
36331cb0ef41Sopenharmony_ci
36341cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer);
36351cb0ef41Sopenharmony_ci  Node* zero_length = __ IntPtrEqual(length, __ IntPtrConstant(0));
36361cb0ef41Sopenharmony_ci  __ GotoIf(zero_length, &done,
36371cb0ef41Sopenharmony_ci            __ HeapConstant(factory()->empty_fixed_array()));
36381cb0ef41Sopenharmony_ci
36391cb0ef41Sopenharmony_ci  // Compute the effective size of the backing store.
36401cb0ef41Sopenharmony_ci  Node* size = __ IntAdd(__ WordShl(length, __ IntPtrConstant(kTaggedSizeLog2)),
36411cb0ef41Sopenharmony_ci                         __ IntPtrConstant(FixedArray::kHeaderSize));
36421cb0ef41Sopenharmony_ci
36431cb0ef41Sopenharmony_ci  // Allocate the result and initialize the header.
36441cb0ef41Sopenharmony_ci  Node* result = __ Allocate(allocation, size);
36451cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForMap(), result, __ FixedArrayMapConstant());
36461cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForFixedArrayLength(), result,
36471cb0ef41Sopenharmony_ci                ChangeIntPtrToSmi(length));
36481cb0ef41Sopenharmony_ci
36491cb0ef41Sopenharmony_ci  // Initialize the backing store with holes.
36501cb0ef41Sopenharmony_ci  Node* the_hole = __ TheHoleConstant();
36511cb0ef41Sopenharmony_ci  auto loop = __ MakeLoopLabel(MachineType::PointerRepresentation());
36521cb0ef41Sopenharmony_ci  __ Goto(&loop, __ IntPtrConstant(0));
36531cb0ef41Sopenharmony_ci  __ Bind(&loop);
36541cb0ef41Sopenharmony_ci  {
36551cb0ef41Sopenharmony_ci    // Check if we've initialized everything.
36561cb0ef41Sopenharmony_ci    Node* index = loop.PhiAt(0);
36571cb0ef41Sopenharmony_ci    Node* check = __ UintLessThan(index, length);
36581cb0ef41Sopenharmony_ci    __ GotoIfNot(check, &done, result);
36591cb0ef41Sopenharmony_ci
36601cb0ef41Sopenharmony_ci    // Storing "the_hole" doesn't need a write barrier.
36611cb0ef41Sopenharmony_ci    ElementAccess const access = {kTaggedBase, FixedArray::kHeaderSize,
36621cb0ef41Sopenharmony_ci                                  Type::Any(), MachineType::AnyTagged(),
36631cb0ef41Sopenharmony_ci                                  kNoWriteBarrier};
36641cb0ef41Sopenharmony_ci    __ StoreElement(access, result, index, the_hole);
36651cb0ef41Sopenharmony_ci
36661cb0ef41Sopenharmony_ci    // Advance the {index}.
36671cb0ef41Sopenharmony_ci    index = __ IntAdd(index, __ IntPtrConstant(1));
36681cb0ef41Sopenharmony_ci    __ Goto(&loop, index);
36691cb0ef41Sopenharmony_ci  }
36701cb0ef41Sopenharmony_ci
36711cb0ef41Sopenharmony_ci  __ Bind(&done);
36721cb0ef41Sopenharmony_ci  return done.PhiAt(0);
36731cb0ef41Sopenharmony_ci}
36741cb0ef41Sopenharmony_ci
36751cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerNewArgumentsElements(Node* node) {
36761cb0ef41Sopenharmony_ci  const NewArgumentsElementsParameters& parameters =
36771cb0ef41Sopenharmony_ci      NewArgumentsElementsParametersOf(node->op());
36781cb0ef41Sopenharmony_ci  CreateArgumentsType type = parameters.arguments_type();
36791cb0ef41Sopenharmony_ci  Operator::Properties const properties = node->op()->properties();
36801cb0ef41Sopenharmony_ci  CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
36811cb0ef41Sopenharmony_ci  Node* frame = __ LoadFramePointer();
36821cb0ef41Sopenharmony_ci  Node* arguments_count = NodeProperties::GetValueInput(node, 0);
36831cb0ef41Sopenharmony_ci  Builtin builtin_name;
36841cb0ef41Sopenharmony_ci  switch (type) {
36851cb0ef41Sopenharmony_ci    case CreateArgumentsType::kMappedArguments:
36861cb0ef41Sopenharmony_ci      builtin_name = Builtin::kNewSloppyArgumentsElements;
36871cb0ef41Sopenharmony_ci      break;
36881cb0ef41Sopenharmony_ci    case CreateArgumentsType::kUnmappedArguments:
36891cb0ef41Sopenharmony_ci      builtin_name = Builtin::kNewStrictArgumentsElements;
36901cb0ef41Sopenharmony_ci      break;
36911cb0ef41Sopenharmony_ci    case CreateArgumentsType::kRestParameter:
36921cb0ef41Sopenharmony_ci      builtin_name = Builtin::kNewRestArgumentsElements;
36931cb0ef41Sopenharmony_ci      break;
36941cb0ef41Sopenharmony_ci  }
36951cb0ef41Sopenharmony_ci  Callable const callable = Builtins::CallableFor(isolate(), builtin_name);
36961cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
36971cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
36981cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), flags, properties);
36991cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ HeapConstant(callable.code()), frame,
37001cb0ef41Sopenharmony_ci                 __ IntPtrConstant(parameters.formal_parameter_count()),
37011cb0ef41Sopenharmony_ci                 arguments_count);
37021cb0ef41Sopenharmony_ci}
37031cb0ef41Sopenharmony_ci
37041cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerNewConsString(Node* node) {
37051cb0ef41Sopenharmony_ci  Node* length = node->InputAt(0);
37061cb0ef41Sopenharmony_ci  Node* first = node->InputAt(1);
37071cb0ef41Sopenharmony_ci  Node* second = node->InputAt(2);
37081cb0ef41Sopenharmony_ci
37091cb0ef41Sopenharmony_ci  // Determine the instance types of {first} and {second}.
37101cb0ef41Sopenharmony_ci  Node* first_map = __ LoadField(AccessBuilder::ForMap(), first);
37111cb0ef41Sopenharmony_ci  Node* first_instance_type =
37121cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), first_map);
37131cb0ef41Sopenharmony_ci  Node* second_map = __ LoadField(AccessBuilder::ForMap(), second);
37141cb0ef41Sopenharmony_ci  Node* second_instance_type =
37151cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), second_map);
37161cb0ef41Sopenharmony_ci
37171cb0ef41Sopenharmony_ci  // Determine the proper map for the resulting ConsString.
37181cb0ef41Sopenharmony_ci  // If both {first} and {second} are one-byte strings, we
37191cb0ef41Sopenharmony_ci  // create a new ConsOneByteString, otherwise we create a
37201cb0ef41Sopenharmony_ci  // new ConsString instead.
37211cb0ef41Sopenharmony_ci  auto if_onebyte = __ MakeLabel();
37221cb0ef41Sopenharmony_ci  auto if_twobyte = __ MakeLabel();
37231cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer);
37241cb0ef41Sopenharmony_ci  STATIC_ASSERT(kOneByteStringTag != 0);
37251cb0ef41Sopenharmony_ci  STATIC_ASSERT(kTwoByteStringTag == 0);
37261cb0ef41Sopenharmony_ci  Node* instance_type = __ Word32And(first_instance_type, second_instance_type);
37271cb0ef41Sopenharmony_ci  Node* encoding =
37281cb0ef41Sopenharmony_ci      __ Word32And(instance_type, __ Int32Constant(kStringEncodingMask));
37291cb0ef41Sopenharmony_ci  __ Branch(__ Word32Equal(encoding, __ Int32Constant(kTwoByteStringTag)),
37301cb0ef41Sopenharmony_ci            &if_twobyte, &if_onebyte);
37311cb0ef41Sopenharmony_ci  __ Bind(&if_onebyte);
37321cb0ef41Sopenharmony_ci  __ Goto(&done, __ HeapConstant(factory()->cons_one_byte_string_map()));
37331cb0ef41Sopenharmony_ci  __ Bind(&if_twobyte);
37341cb0ef41Sopenharmony_ci  __ Goto(&done, __ HeapConstant(factory()->cons_string_map()));
37351cb0ef41Sopenharmony_ci  __ Bind(&done);
37361cb0ef41Sopenharmony_ci  Node* result_map = done.PhiAt(0);
37371cb0ef41Sopenharmony_ci
37381cb0ef41Sopenharmony_ci  // Allocate the resulting ConsString.
37391cb0ef41Sopenharmony_ci  Node* result =
37401cb0ef41Sopenharmony_ci      __ Allocate(AllocationType::kYoung, __ IntPtrConstant(ConsString::kSize));
37411cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForMap(), result, result_map);
37421cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForNameRawHashField(), result,
37431cb0ef41Sopenharmony_ci                __ Int32Constant(Name::kEmptyHashField));
37441cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForStringLength(), result, length);
37451cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForConsStringFirst(), result, first);
37461cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForConsStringSecond(), result, second);
37471cb0ef41Sopenharmony_ci  return result;
37481cb0ef41Sopenharmony_ci}
37491cb0ef41Sopenharmony_ci
37501cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerSameValue(Node* node) {
37511cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(0);
37521cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(1);
37531cb0ef41Sopenharmony_ci
37541cb0ef41Sopenharmony_ci  Callable const callable =
37551cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kSameValue);
37561cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kEliminatable;
37571cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
37581cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
37591cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
37601cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), flags, properties);
37611cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs, rhs,
37621cb0ef41Sopenharmony_ci                 __ NoContextConstant());
37631cb0ef41Sopenharmony_ci}
37641cb0ef41Sopenharmony_ci
37651cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerSameValueNumbersOnly(Node* node) {
37661cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(0);
37671cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(1);
37681cb0ef41Sopenharmony_ci
37691cb0ef41Sopenharmony_ci  Callable const callable =
37701cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kSameValueNumbersOnly);
37711cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kEliminatable;
37721cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
37731cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
37741cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
37751cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), flags, properties);
37761cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs, rhs,
37771cb0ef41Sopenharmony_ci                 __ NoContextConstant());
37781cb0ef41Sopenharmony_ci}
37791cb0ef41Sopenharmony_ci
37801cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerNumberSameValue(Node* node) {
37811cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(0);
37821cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(1);
37831cb0ef41Sopenharmony_ci
37841cb0ef41Sopenharmony_ci  auto is_float64_equal = __ MakeLabel();
37851cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kBit);
37861cb0ef41Sopenharmony_ci
37871cb0ef41Sopenharmony_ci  __ GotoIf(__ Float64Equal(lhs, rhs), &is_float64_equal);
37881cb0ef41Sopenharmony_ci
37891cb0ef41Sopenharmony_ci  // Return true iff both {lhs} and {rhs} are NaN.
37901cb0ef41Sopenharmony_ci  __ GotoIf(__ Float64Equal(lhs, lhs), &done, __ Int32Constant(0));
37911cb0ef41Sopenharmony_ci  __ GotoIf(__ Float64Equal(rhs, rhs), &done, __ Int32Constant(0));
37921cb0ef41Sopenharmony_ci  __ Goto(&done, __ Int32Constant(1));
37931cb0ef41Sopenharmony_ci
37941cb0ef41Sopenharmony_ci  __ Bind(&is_float64_equal);
37951cb0ef41Sopenharmony_ci  // Even if the values are float64-equal, we still need to distinguish
37961cb0ef41Sopenharmony_ci  // zero and minus zero.
37971cb0ef41Sopenharmony_ci  Node* lhs_hi = __ Float64ExtractHighWord32(lhs);
37981cb0ef41Sopenharmony_ci  Node* rhs_hi = __ Float64ExtractHighWord32(rhs);
37991cb0ef41Sopenharmony_ci  __ Goto(&done, __ Word32Equal(lhs_hi, rhs_hi));
38001cb0ef41Sopenharmony_ci
38011cb0ef41Sopenharmony_ci  __ Bind(&done);
38021cb0ef41Sopenharmony_ci  return done.PhiAt(0);
38031cb0ef41Sopenharmony_ci}
38041cb0ef41Sopenharmony_ci
38051cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerDeadValue(Node* node) {
38061cb0ef41Sopenharmony_ci  Node* input = NodeProperties::GetValueInput(node, 0);
38071cb0ef41Sopenharmony_ci  if (input->opcode() != IrOpcode::kUnreachable) {
38081cb0ef41Sopenharmony_ci    // There is no fundamental reason not to connect to end here, except it
38091cb0ef41Sopenharmony_ci    // integrates into the way the graph is constructed in a simpler way at
38101cb0ef41Sopenharmony_ci    // this point.
38111cb0ef41Sopenharmony_ci    // TODO(jgruber): Connect to end here as well.
38121cb0ef41Sopenharmony_ci    Node* unreachable = __ UnreachableWithoutConnectToEnd();
38131cb0ef41Sopenharmony_ci    NodeProperties::ReplaceValueInput(node, unreachable, 0);
38141cb0ef41Sopenharmony_ci  }
38151cb0ef41Sopenharmony_ci  return gasm()->AddNode(node);
38161cb0ef41Sopenharmony_ci}
38171cb0ef41Sopenharmony_ci
38181cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringToNumber(Node* node) {
38191cb0ef41Sopenharmony_ci  Node* string = node->InputAt(0);
38201cb0ef41Sopenharmony_ci
38211cb0ef41Sopenharmony_ci  Callable const callable =
38221cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kStringToNumber);
38231cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kEliminatable;
38241cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
38251cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
38261cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
38271cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), flags, properties);
38281cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ HeapConstant(callable.code()), string,
38291cb0ef41Sopenharmony_ci                 __ NoContextConstant());
38301cb0ef41Sopenharmony_ci}
38311cb0ef41Sopenharmony_ci
38321cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::StringCharCodeAt(Node* receiver,
38331cb0ef41Sopenharmony_ci                                                Node* position) {
38341cb0ef41Sopenharmony_ci  // We need a loop here to properly deal with indirect strings
38351cb0ef41Sopenharmony_ci  // (SlicedString, ConsString and ThinString).
38361cb0ef41Sopenharmony_ci  auto loop = __ MakeLoopLabel(MachineRepresentation::kTagged,
38371cb0ef41Sopenharmony_ci                               MachineType::PointerRepresentation());
38381cb0ef41Sopenharmony_ci  auto loop_next = __ MakeLabel(MachineRepresentation::kTagged,
38391cb0ef41Sopenharmony_ci                                MachineType::PointerRepresentation());
38401cb0ef41Sopenharmony_ci  auto loop_done = __ MakeLabel(MachineRepresentation::kWord32);
38411cb0ef41Sopenharmony_ci  __ Goto(&loop, receiver, position);
38421cb0ef41Sopenharmony_ci  __ Bind(&loop);
38431cb0ef41Sopenharmony_ci  {
38441cb0ef41Sopenharmony_ci    receiver = loop.PhiAt(0);
38451cb0ef41Sopenharmony_ci    position = loop.PhiAt(1);
38461cb0ef41Sopenharmony_ci    Node* receiver_map = __ LoadField(AccessBuilder::ForMap(), receiver);
38471cb0ef41Sopenharmony_ci    Node* receiver_instance_type =
38481cb0ef41Sopenharmony_ci        __ LoadField(AccessBuilder::ForMapInstanceType(), receiver_map);
38491cb0ef41Sopenharmony_ci    Node* receiver_representation = __ Word32And(
38501cb0ef41Sopenharmony_ci        receiver_instance_type, __ Int32Constant(kStringRepresentationMask));
38511cb0ef41Sopenharmony_ci
38521cb0ef41Sopenharmony_ci    // Dispatch on the current {receiver}s string representation.
38531cb0ef41Sopenharmony_ci    auto if_lessthanoreq_cons = __ MakeLabel();
38541cb0ef41Sopenharmony_ci    auto if_greaterthan_cons = __ MakeLabel();
38551cb0ef41Sopenharmony_ci    auto if_seqstring = __ MakeLabel();
38561cb0ef41Sopenharmony_ci    auto if_consstring = __ MakeLabel();
38571cb0ef41Sopenharmony_ci    auto if_thinstring = __ MakeLabel();
38581cb0ef41Sopenharmony_ci    auto if_externalstring = __ MakeLabel();
38591cb0ef41Sopenharmony_ci    auto if_slicedstring = __ MakeLabel();
38601cb0ef41Sopenharmony_ci    auto if_runtime = __ MakeDeferredLabel();
38611cb0ef41Sopenharmony_ci
38621cb0ef41Sopenharmony_ci    __ Branch(__ Int32LessThanOrEqual(receiver_representation,
38631cb0ef41Sopenharmony_ci                                      __ Int32Constant(kConsStringTag)),
38641cb0ef41Sopenharmony_ci              &if_lessthanoreq_cons, &if_greaterthan_cons);
38651cb0ef41Sopenharmony_ci
38661cb0ef41Sopenharmony_ci    __ Bind(&if_lessthanoreq_cons);
38671cb0ef41Sopenharmony_ci    {
38681cb0ef41Sopenharmony_ci      __ Branch(__ Word32Equal(receiver_representation,
38691cb0ef41Sopenharmony_ci                               __ Int32Constant(kConsStringTag)),
38701cb0ef41Sopenharmony_ci                &if_consstring, &if_seqstring);
38711cb0ef41Sopenharmony_ci    }
38721cb0ef41Sopenharmony_ci
38731cb0ef41Sopenharmony_ci    __ Bind(&if_greaterthan_cons);
38741cb0ef41Sopenharmony_ci    {
38751cb0ef41Sopenharmony_ci      __ GotoIf(__ Word32Equal(receiver_representation,
38761cb0ef41Sopenharmony_ci                               __ Int32Constant(kThinStringTag)),
38771cb0ef41Sopenharmony_ci                &if_thinstring);
38781cb0ef41Sopenharmony_ci      __ GotoIf(__ Word32Equal(receiver_representation,
38791cb0ef41Sopenharmony_ci                               __ Int32Constant(kExternalStringTag)),
38801cb0ef41Sopenharmony_ci                &if_externalstring);
38811cb0ef41Sopenharmony_ci      __ Branch(__ Word32Equal(receiver_representation,
38821cb0ef41Sopenharmony_ci                               __ Int32Constant(kSlicedStringTag)),
38831cb0ef41Sopenharmony_ci                &if_slicedstring, &if_runtime);
38841cb0ef41Sopenharmony_ci    }
38851cb0ef41Sopenharmony_ci
38861cb0ef41Sopenharmony_ci    __ Bind(&if_seqstring);
38871cb0ef41Sopenharmony_ci    {
38881cb0ef41Sopenharmony_ci      Node* receiver_is_onebyte = __ Word32Equal(
38891cb0ef41Sopenharmony_ci          __ Word32Equal(__ Word32And(receiver_instance_type,
38901cb0ef41Sopenharmony_ci                                      __ Int32Constant(kStringEncodingMask)),
38911cb0ef41Sopenharmony_ci                         __ Int32Constant(kTwoByteStringTag)),
38921cb0ef41Sopenharmony_ci          __ Int32Constant(0));
38931cb0ef41Sopenharmony_ci      Node* result = LoadFromSeqString(receiver, position, receiver_is_onebyte);
38941cb0ef41Sopenharmony_ci      __ Goto(&loop_done, result);
38951cb0ef41Sopenharmony_ci    }
38961cb0ef41Sopenharmony_ci
38971cb0ef41Sopenharmony_ci    __ Bind(&if_consstring);
38981cb0ef41Sopenharmony_ci    {
38991cb0ef41Sopenharmony_ci      Node* receiver_second =
39001cb0ef41Sopenharmony_ci          __ LoadField(AccessBuilder::ForConsStringSecond(), receiver);
39011cb0ef41Sopenharmony_ci      __ GotoIfNot(__ TaggedEqual(receiver_second, __ EmptyStringConstant()),
39021cb0ef41Sopenharmony_ci                   &if_runtime);
39031cb0ef41Sopenharmony_ci      Node* receiver_first =
39041cb0ef41Sopenharmony_ci          __ LoadField(AccessBuilder::ForConsStringFirst(), receiver);
39051cb0ef41Sopenharmony_ci      __ Goto(&loop_next, receiver_first, position);
39061cb0ef41Sopenharmony_ci    }
39071cb0ef41Sopenharmony_ci
39081cb0ef41Sopenharmony_ci    __ Bind(&if_thinstring);
39091cb0ef41Sopenharmony_ci    {
39101cb0ef41Sopenharmony_ci      Node* receiver_actual =
39111cb0ef41Sopenharmony_ci          __ LoadField(AccessBuilder::ForThinStringActual(), receiver);
39121cb0ef41Sopenharmony_ci      __ Goto(&loop_next, receiver_actual, position);
39131cb0ef41Sopenharmony_ci    }
39141cb0ef41Sopenharmony_ci
39151cb0ef41Sopenharmony_ci    __ Bind(&if_externalstring);
39161cb0ef41Sopenharmony_ci    {
39171cb0ef41Sopenharmony_ci      // We need to bailout to the runtime for uncached external strings.
39181cb0ef41Sopenharmony_ci      __ GotoIf(__ Word32Equal(
39191cb0ef41Sopenharmony_ci                    __ Word32And(receiver_instance_type,
39201cb0ef41Sopenharmony_ci                                 __ Int32Constant(kUncachedExternalStringMask)),
39211cb0ef41Sopenharmony_ci                    __ Int32Constant(kUncachedExternalStringTag)),
39221cb0ef41Sopenharmony_ci                &if_runtime);
39231cb0ef41Sopenharmony_ci
39241cb0ef41Sopenharmony_ci      Node* receiver_data = __ LoadField(
39251cb0ef41Sopenharmony_ci          AccessBuilder::ForExternalStringResourceData(), receiver);
39261cb0ef41Sopenharmony_ci
39271cb0ef41Sopenharmony_ci      auto if_onebyte = __ MakeLabel();
39281cb0ef41Sopenharmony_ci      auto if_twobyte = __ MakeLabel();
39291cb0ef41Sopenharmony_ci      __ Branch(
39301cb0ef41Sopenharmony_ci          __ Word32Equal(__ Word32And(receiver_instance_type,
39311cb0ef41Sopenharmony_ci                                      __ Int32Constant(kStringEncodingMask)),
39321cb0ef41Sopenharmony_ci                         __ Int32Constant(kTwoByteStringTag)),
39331cb0ef41Sopenharmony_ci          &if_twobyte, &if_onebyte);
39341cb0ef41Sopenharmony_ci
39351cb0ef41Sopenharmony_ci      __ Bind(&if_onebyte);
39361cb0ef41Sopenharmony_ci      {
39371cb0ef41Sopenharmony_ci        Node* result = __ Load(MachineType::Uint8(), receiver_data, position);
39381cb0ef41Sopenharmony_ci        __ Goto(&loop_done, result);
39391cb0ef41Sopenharmony_ci      }
39401cb0ef41Sopenharmony_ci
39411cb0ef41Sopenharmony_ci      __ Bind(&if_twobyte);
39421cb0ef41Sopenharmony_ci      {
39431cb0ef41Sopenharmony_ci        Node* result = __ Load(MachineType::Uint16(), receiver_data,
39441cb0ef41Sopenharmony_ci                               __ WordShl(position, __ IntPtrConstant(1)));
39451cb0ef41Sopenharmony_ci        __ Goto(&loop_done, result);
39461cb0ef41Sopenharmony_ci      }
39471cb0ef41Sopenharmony_ci    }
39481cb0ef41Sopenharmony_ci
39491cb0ef41Sopenharmony_ci    __ Bind(&if_slicedstring);
39501cb0ef41Sopenharmony_ci    {
39511cb0ef41Sopenharmony_ci      Node* receiver_offset =
39521cb0ef41Sopenharmony_ci          __ LoadField(AccessBuilder::ForSlicedStringOffset(), receiver);
39531cb0ef41Sopenharmony_ci      Node* receiver_parent =
39541cb0ef41Sopenharmony_ci          __ LoadField(AccessBuilder::ForSlicedStringParent(), receiver);
39551cb0ef41Sopenharmony_ci      __ Goto(&loop_next, receiver_parent,
39561cb0ef41Sopenharmony_ci              __ IntAdd(position, ChangeSmiToIntPtr(receiver_offset)));
39571cb0ef41Sopenharmony_ci    }
39581cb0ef41Sopenharmony_ci
39591cb0ef41Sopenharmony_ci    __ Bind(&if_runtime);
39601cb0ef41Sopenharmony_ci    {
39611cb0ef41Sopenharmony_ci      Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
39621cb0ef41Sopenharmony_ci      Runtime::FunctionId id = Runtime::kStringCharCodeAt;
39631cb0ef41Sopenharmony_ci      auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
39641cb0ef41Sopenharmony_ci          graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
39651cb0ef41Sopenharmony_ci      Node* result = __ Call(call_descriptor, __ CEntryStubConstant(1),
39661cb0ef41Sopenharmony_ci                             receiver, ChangeIntPtrToSmi(position),
39671cb0ef41Sopenharmony_ci                             __ ExternalConstant(ExternalReference::Create(id)),
39681cb0ef41Sopenharmony_ci                             __ Int32Constant(2), __ NoContextConstant());
39691cb0ef41Sopenharmony_ci      __ Goto(&loop_done, ChangeSmiToInt32(result));
39701cb0ef41Sopenharmony_ci    }
39711cb0ef41Sopenharmony_ci
39721cb0ef41Sopenharmony_ci    __ Bind(&loop_next);
39731cb0ef41Sopenharmony_ci    __ Goto(&loop, loop_next.PhiAt(0), loop_next.PhiAt(1));
39741cb0ef41Sopenharmony_ci  }
39751cb0ef41Sopenharmony_ci  __ Bind(&loop_done);
39761cb0ef41Sopenharmony_ci  return loop_done.PhiAt(0);
39771cb0ef41Sopenharmony_ci}
39781cb0ef41Sopenharmony_ci
39791cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringCharCodeAt(Node* node) {
39801cb0ef41Sopenharmony_ci  Node* receiver = node->InputAt(0);
39811cb0ef41Sopenharmony_ci  Node* position = node->InputAt(1);
39821cb0ef41Sopenharmony_ci  return StringCharCodeAt(receiver, position);
39831cb0ef41Sopenharmony_ci}
39841cb0ef41Sopenharmony_ci
39851cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringCodePointAt(Node* node) {
39861cb0ef41Sopenharmony_ci  Node* receiver = node->InputAt(0);
39871cb0ef41Sopenharmony_ci  Node* position = node->InputAt(1);
39881cb0ef41Sopenharmony_ci
39891cb0ef41Sopenharmony_ci  auto return_result = __ MakeLabel(MachineRepresentation::kWord32);
39901cb0ef41Sopenharmony_ci  Node* first_code_unit = StringCharCodeAt(receiver, position);
39911cb0ef41Sopenharmony_ci
39921cb0ef41Sopenharmony_ci  __ GotoIfNot(
39931cb0ef41Sopenharmony_ci      __ Word32Equal(__ Word32And(first_code_unit, __ Int32Constant(0xFC00)),
39941cb0ef41Sopenharmony_ci                     __ Int32Constant(0xD800)),
39951cb0ef41Sopenharmony_ci      &return_result, BranchHint::kFalse, first_code_unit);
39961cb0ef41Sopenharmony_ci
39971cb0ef41Sopenharmony_ci  auto length = __ LoadField(AccessBuilder::ForStringLength(), receiver);
39981cb0ef41Sopenharmony_ci  auto next_index = __ IntAdd(position, __ IntPtrConstant(1));
39991cb0ef41Sopenharmony_ci  __ GotoIfNot(__ IntLessThan(next_index, length), &return_result,
40001cb0ef41Sopenharmony_ci               first_code_unit);
40011cb0ef41Sopenharmony_ci  Node* second_code_unit = StringCharCodeAt(receiver, next_index);
40021cb0ef41Sopenharmony_ci  __ GotoIfNot(
40031cb0ef41Sopenharmony_ci      __ Word32Equal(__ Word32And(second_code_unit, __ Int32Constant(0xFC00)),
40041cb0ef41Sopenharmony_ci                     __ Int32Constant(0xDC00)),
40051cb0ef41Sopenharmony_ci      &return_result, first_code_unit);
40061cb0ef41Sopenharmony_ci
40071cb0ef41Sopenharmony_ci  auto surrogate_offset = __ Int32Constant(0x10000 - (0xD800 << 10) - 0xDC00);
40081cb0ef41Sopenharmony_ci  auto result = __ Int32Add(__ Word32Shl(first_code_unit, __ Int32Constant(10)),
40091cb0ef41Sopenharmony_ci                            __ Int32Add(second_code_unit, surrogate_offset));
40101cb0ef41Sopenharmony_ci  __ Goto(&return_result, result);
40111cb0ef41Sopenharmony_ci
40121cb0ef41Sopenharmony_ci  __ Bind(&return_result);
40131cb0ef41Sopenharmony_ci  return return_result.PhiAt(0);
40141cb0ef41Sopenharmony_ci}
40151cb0ef41Sopenharmony_ci
40161cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LoadFromSeqString(Node* receiver, Node* position,
40171cb0ef41Sopenharmony_ci                                                 Node* is_one_byte) {
40181cb0ef41Sopenharmony_ci  auto one_byte_load = __ MakeLabel();
40191cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kWord32);
40201cb0ef41Sopenharmony_ci  __ GotoIf(is_one_byte, &one_byte_load);
40211cb0ef41Sopenharmony_ci  Node* two_byte_result = __ LoadElement(
40221cb0ef41Sopenharmony_ci      AccessBuilder::ForSeqTwoByteStringCharacter(), receiver, position);
40231cb0ef41Sopenharmony_ci  __ Goto(&done, two_byte_result);
40241cb0ef41Sopenharmony_ci
40251cb0ef41Sopenharmony_ci  __ Bind(&one_byte_load);
40261cb0ef41Sopenharmony_ci  Node* one_byte_element = __ LoadElement(
40271cb0ef41Sopenharmony_ci      AccessBuilder::ForSeqOneByteStringCharacter(), receiver, position);
40281cb0ef41Sopenharmony_ci  __ Goto(&done, one_byte_element);
40291cb0ef41Sopenharmony_ci
40301cb0ef41Sopenharmony_ci  __ Bind(&done);
40311cb0ef41Sopenharmony_ci  return done.PhiAt(0);
40321cb0ef41Sopenharmony_ci}
40331cb0ef41Sopenharmony_ci
40341cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringFromSingleCharCode(Node* node) {
40351cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
40361cb0ef41Sopenharmony_ci  Node* code = __ Word32And(value, __ Uint32Constant(0xFFFF));
40371cb0ef41Sopenharmony_ci
40381cb0ef41Sopenharmony_ci  auto if_not_one_byte = __ MakeDeferredLabel();
40391cb0ef41Sopenharmony_ci  auto cache_miss = __ MakeDeferredLabel();
40401cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
40411cb0ef41Sopenharmony_ci
40421cb0ef41Sopenharmony_ci  // Check if the {code} is a one byte character
40431cb0ef41Sopenharmony_ci  Node* check1 = __ Uint32LessThanOrEqual(
40441cb0ef41Sopenharmony_ci      code, __ Uint32Constant(String::kMaxOneByteCharCode));
40451cb0ef41Sopenharmony_ci  __ GotoIfNot(check1, &if_not_one_byte);
40461cb0ef41Sopenharmony_ci  {
40471cb0ef41Sopenharmony_ci    // Load the isolate wide single character string cache.
40481cb0ef41Sopenharmony_ci    Node* cache = __ HeapConstant(factory()->single_character_string_cache());
40491cb0ef41Sopenharmony_ci
40501cb0ef41Sopenharmony_ci    // Compute the {cache} index for {code}.
40511cb0ef41Sopenharmony_ci    Node* index = machine()->Is32() ? code : __ ChangeUint32ToUint64(code);
40521cb0ef41Sopenharmony_ci
40531cb0ef41Sopenharmony_ci    // Check if we have an entry for the {code} in the single character string
40541cb0ef41Sopenharmony_ci    // cache already.
40551cb0ef41Sopenharmony_ci    Node* entry =
40561cb0ef41Sopenharmony_ci        __ LoadElement(AccessBuilder::ForFixedArrayElement(), cache, index);
40571cb0ef41Sopenharmony_ci
40581cb0ef41Sopenharmony_ci    Node* check2 = __ TaggedEqual(entry, __ UndefinedConstant());
40591cb0ef41Sopenharmony_ci    __ GotoIf(check2, &cache_miss);
40601cb0ef41Sopenharmony_ci
40611cb0ef41Sopenharmony_ci    // Use the {entry} from the {cache}.
40621cb0ef41Sopenharmony_ci    __ Goto(&done, entry);
40631cb0ef41Sopenharmony_ci
40641cb0ef41Sopenharmony_ci    __ Bind(&cache_miss);
40651cb0ef41Sopenharmony_ci    {
40661cb0ef41Sopenharmony_ci      // Allocate a new SeqOneByteString for {code}.
40671cb0ef41Sopenharmony_ci      Node* vtrue2 =
40681cb0ef41Sopenharmony_ci          __ Allocate(AllocationType::kYoung,
40691cb0ef41Sopenharmony_ci                      __ IntPtrConstant(SeqOneByteString::SizeFor(1)));
40701cb0ef41Sopenharmony_ci      __ StoreField(AccessBuilder::ForMap(), vtrue2,
40711cb0ef41Sopenharmony_ci                    __ HeapConstant(factory()->one_byte_string_map()));
40721cb0ef41Sopenharmony_ci      __ StoreField(AccessBuilder::ForNameRawHashField(), vtrue2,
40731cb0ef41Sopenharmony_ci                    __ Int32Constant(Name::kEmptyHashField));
40741cb0ef41Sopenharmony_ci      __ StoreField(AccessBuilder::ForStringLength(), vtrue2,
40751cb0ef41Sopenharmony_ci                    __ Int32Constant(1));
40761cb0ef41Sopenharmony_ci      __ Store(
40771cb0ef41Sopenharmony_ci          StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
40781cb0ef41Sopenharmony_ci          vtrue2,
40791cb0ef41Sopenharmony_ci          __ IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag),
40801cb0ef41Sopenharmony_ci          code);
40811cb0ef41Sopenharmony_ci
40821cb0ef41Sopenharmony_ci      // Remember it in the {cache}.
40831cb0ef41Sopenharmony_ci      __ StoreElement(AccessBuilder::ForFixedArrayElement(), cache, index,
40841cb0ef41Sopenharmony_ci                      vtrue2);
40851cb0ef41Sopenharmony_ci      __ Goto(&done, vtrue2);
40861cb0ef41Sopenharmony_ci    }
40871cb0ef41Sopenharmony_ci  }
40881cb0ef41Sopenharmony_ci
40891cb0ef41Sopenharmony_ci  __ Bind(&if_not_one_byte);
40901cb0ef41Sopenharmony_ci  {
40911cb0ef41Sopenharmony_ci    // Allocate a new SeqTwoByteString for {code}.
40921cb0ef41Sopenharmony_ci    Node* vfalse1 =
40931cb0ef41Sopenharmony_ci        __ Allocate(AllocationType::kYoung,
40941cb0ef41Sopenharmony_ci                    __ IntPtrConstant(SeqTwoByteString::SizeFor(1)));
40951cb0ef41Sopenharmony_ci    __ StoreField(AccessBuilder::ForMap(), vfalse1,
40961cb0ef41Sopenharmony_ci                  __ HeapConstant(factory()->string_map()));
40971cb0ef41Sopenharmony_ci    __ StoreField(AccessBuilder::ForNameRawHashField(), vfalse1,
40981cb0ef41Sopenharmony_ci                  __ Int32Constant(Name::kEmptyHashField));
40991cb0ef41Sopenharmony_ci    __ StoreField(AccessBuilder::ForStringLength(), vfalse1,
41001cb0ef41Sopenharmony_ci                  __ Int32Constant(1));
41011cb0ef41Sopenharmony_ci    __ Store(
41021cb0ef41Sopenharmony_ci        StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier),
41031cb0ef41Sopenharmony_ci        vfalse1,
41041cb0ef41Sopenharmony_ci        __ IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag),
41051cb0ef41Sopenharmony_ci        code);
41061cb0ef41Sopenharmony_ci    __ Goto(&done, vfalse1);
41071cb0ef41Sopenharmony_ci  }
41081cb0ef41Sopenharmony_ci
41091cb0ef41Sopenharmony_ci  __ Bind(&done);
41101cb0ef41Sopenharmony_ci  return done.PhiAt(0);
41111cb0ef41Sopenharmony_ci}
41121cb0ef41Sopenharmony_ci
41131cb0ef41Sopenharmony_ci#ifdef V8_INTL_SUPPORT
41141cb0ef41Sopenharmony_ci
41151cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringToLowerCaseIntl(Node* node) {
41161cb0ef41Sopenharmony_ci  Node* receiver = node->InputAt(0);
41171cb0ef41Sopenharmony_ci
41181cb0ef41Sopenharmony_ci  Callable callable =
41191cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kStringToLowerCaseIntl);
41201cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
41211cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
41221cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
41231cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
41241cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), flags, properties);
41251cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ HeapConstant(callable.code()), receiver,
41261cb0ef41Sopenharmony_ci                 __ NoContextConstant());
41271cb0ef41Sopenharmony_ci}
41281cb0ef41Sopenharmony_ci
41291cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringToUpperCaseIntl(Node* node) {
41301cb0ef41Sopenharmony_ci  Node* receiver = node->InputAt(0);
41311cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
41321cb0ef41Sopenharmony_ci  Runtime::FunctionId id = Runtime::kStringToUpperCaseIntl;
41331cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
41341cb0ef41Sopenharmony_ci      graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
41351cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ CEntryStubConstant(1), receiver,
41361cb0ef41Sopenharmony_ci                 __ ExternalConstant(ExternalReference::Create(id)),
41371cb0ef41Sopenharmony_ci                 __ Int32Constant(1), __ NoContextConstant());
41381cb0ef41Sopenharmony_ci}
41391cb0ef41Sopenharmony_ci
41401cb0ef41Sopenharmony_ci#else
41411cb0ef41Sopenharmony_ci
41421cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringToLowerCaseIntl(Node* node) {
41431cb0ef41Sopenharmony_ci  UNREACHABLE();
41441cb0ef41Sopenharmony_ci}
41451cb0ef41Sopenharmony_ci
41461cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringToUpperCaseIntl(Node* node) {
41471cb0ef41Sopenharmony_ci  UNREACHABLE();
41481cb0ef41Sopenharmony_ci}
41491cb0ef41Sopenharmony_ci
41501cb0ef41Sopenharmony_ci#endif  // V8_INTL_SUPPORT
41511cb0ef41Sopenharmony_ci
41521cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
41531cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
41541cb0ef41Sopenharmony_ci  Node* code = value;
41551cb0ef41Sopenharmony_ci
41561cb0ef41Sopenharmony_ci  auto if_not_single_code = __ MakeDeferredLabel();
41571cb0ef41Sopenharmony_ci  auto if_not_one_byte = __ MakeDeferredLabel();
41581cb0ef41Sopenharmony_ci  auto cache_miss = __ MakeDeferredLabel();
41591cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
41601cb0ef41Sopenharmony_ci
41611cb0ef41Sopenharmony_ci  // Check if the {code} is a single code unit
41621cb0ef41Sopenharmony_ci  Node* check0 = __ Uint32LessThanOrEqual(code, __ Uint32Constant(0xFFFF));
41631cb0ef41Sopenharmony_ci  __ GotoIfNot(check0, &if_not_single_code);
41641cb0ef41Sopenharmony_ci
41651cb0ef41Sopenharmony_ci  {
41661cb0ef41Sopenharmony_ci    // Check if the {code} is a one byte character
41671cb0ef41Sopenharmony_ci    Node* check1 = __ Uint32LessThanOrEqual(
41681cb0ef41Sopenharmony_ci        code, __ Uint32Constant(String::kMaxOneByteCharCode));
41691cb0ef41Sopenharmony_ci    __ GotoIfNot(check1, &if_not_one_byte);
41701cb0ef41Sopenharmony_ci    {
41711cb0ef41Sopenharmony_ci      // Load the isolate wide single character string cache.
41721cb0ef41Sopenharmony_ci      Node* cache = __ HeapConstant(factory()->single_character_string_cache());
41731cb0ef41Sopenharmony_ci
41741cb0ef41Sopenharmony_ci      // Compute the {cache} index for {code}.
41751cb0ef41Sopenharmony_ci      Node* index = machine()->Is32() ? code : __ ChangeUint32ToUint64(code);
41761cb0ef41Sopenharmony_ci
41771cb0ef41Sopenharmony_ci      // Check if we have an entry for the {code} in the single character string
41781cb0ef41Sopenharmony_ci      // cache already.
41791cb0ef41Sopenharmony_ci      Node* entry =
41801cb0ef41Sopenharmony_ci          __ LoadElement(AccessBuilder::ForFixedArrayElement(), cache, index);
41811cb0ef41Sopenharmony_ci
41821cb0ef41Sopenharmony_ci      Node* check2 = __ TaggedEqual(entry, __ UndefinedConstant());
41831cb0ef41Sopenharmony_ci      __ GotoIf(check2, &cache_miss);
41841cb0ef41Sopenharmony_ci
41851cb0ef41Sopenharmony_ci      // Use the {entry} from the {cache}.
41861cb0ef41Sopenharmony_ci      __ Goto(&done, entry);
41871cb0ef41Sopenharmony_ci
41881cb0ef41Sopenharmony_ci      __ Bind(&cache_miss);
41891cb0ef41Sopenharmony_ci      {
41901cb0ef41Sopenharmony_ci        // Allocate a new SeqOneByteString for {code}.
41911cb0ef41Sopenharmony_ci        Node* vtrue2 =
41921cb0ef41Sopenharmony_ci            __ Allocate(AllocationType::kYoung,
41931cb0ef41Sopenharmony_ci                        __ IntPtrConstant(SeqOneByteString::SizeFor(1)));
41941cb0ef41Sopenharmony_ci        __ StoreField(AccessBuilder::ForMap(), vtrue2,
41951cb0ef41Sopenharmony_ci                      __ HeapConstant(factory()->one_byte_string_map()));
41961cb0ef41Sopenharmony_ci        __ StoreField(AccessBuilder::ForNameRawHashField(), vtrue2,
41971cb0ef41Sopenharmony_ci                      __ Int32Constant(Name::kEmptyHashField));
41981cb0ef41Sopenharmony_ci        __ StoreField(AccessBuilder::ForStringLength(), vtrue2,
41991cb0ef41Sopenharmony_ci                      __ Int32Constant(1));
42001cb0ef41Sopenharmony_ci        __ Store(
42011cb0ef41Sopenharmony_ci            StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
42021cb0ef41Sopenharmony_ci            vtrue2,
42031cb0ef41Sopenharmony_ci            __ IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag),
42041cb0ef41Sopenharmony_ci            code);
42051cb0ef41Sopenharmony_ci
42061cb0ef41Sopenharmony_ci        // Remember it in the {cache}.
42071cb0ef41Sopenharmony_ci        __ StoreElement(AccessBuilder::ForFixedArrayElement(), cache, index,
42081cb0ef41Sopenharmony_ci                        vtrue2);
42091cb0ef41Sopenharmony_ci        __ Goto(&done, vtrue2);
42101cb0ef41Sopenharmony_ci      }
42111cb0ef41Sopenharmony_ci    }
42121cb0ef41Sopenharmony_ci
42131cb0ef41Sopenharmony_ci    __ Bind(&if_not_one_byte);
42141cb0ef41Sopenharmony_ci    {
42151cb0ef41Sopenharmony_ci      // Allocate a new SeqTwoByteString for {code}.
42161cb0ef41Sopenharmony_ci      Node* vfalse1 =
42171cb0ef41Sopenharmony_ci          __ Allocate(AllocationType::kYoung,
42181cb0ef41Sopenharmony_ci                      __ IntPtrConstant(SeqTwoByteString::SizeFor(1)));
42191cb0ef41Sopenharmony_ci      __ StoreField(AccessBuilder::ForMap(), vfalse1,
42201cb0ef41Sopenharmony_ci                    __ HeapConstant(factory()->string_map()));
42211cb0ef41Sopenharmony_ci      __ StoreField(AccessBuilder::ForNameRawHashField(), vfalse1,
42221cb0ef41Sopenharmony_ci                    __ IntPtrConstant(Name::kEmptyHashField));
42231cb0ef41Sopenharmony_ci      __ StoreField(AccessBuilder::ForStringLength(), vfalse1,
42241cb0ef41Sopenharmony_ci                    __ Int32Constant(1));
42251cb0ef41Sopenharmony_ci      __ Store(
42261cb0ef41Sopenharmony_ci          StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier),
42271cb0ef41Sopenharmony_ci          vfalse1,
42281cb0ef41Sopenharmony_ci          __ IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag),
42291cb0ef41Sopenharmony_ci          code);
42301cb0ef41Sopenharmony_ci      __ Goto(&done, vfalse1);
42311cb0ef41Sopenharmony_ci    }
42321cb0ef41Sopenharmony_ci  }
42331cb0ef41Sopenharmony_ci
42341cb0ef41Sopenharmony_ci  __ Bind(&if_not_single_code);
42351cb0ef41Sopenharmony_ci  // Generate surrogate pair string
42361cb0ef41Sopenharmony_ci  {
42371cb0ef41Sopenharmony_ci    // Convert UTF32 to UTF16 code units, and store as a 32 bit word.
42381cb0ef41Sopenharmony_ci    Node* lead_offset = __ Int32Constant(0xD800 - (0x10000 >> 10));
42391cb0ef41Sopenharmony_ci
42401cb0ef41Sopenharmony_ci    // lead = (codepoint >> 10) + LEAD_OFFSET
42411cb0ef41Sopenharmony_ci    Node* lead =
42421cb0ef41Sopenharmony_ci        __ Int32Add(__ Word32Shr(code, __ Int32Constant(10)), lead_offset);
42431cb0ef41Sopenharmony_ci
42441cb0ef41Sopenharmony_ci    // trail = (codepoint & 0x3FF) + 0xDC00;
42451cb0ef41Sopenharmony_ci    Node* trail = __ Int32Add(__ Word32And(code, __ Int32Constant(0x3FF)),
42461cb0ef41Sopenharmony_ci                              __ Int32Constant(0xDC00));
42471cb0ef41Sopenharmony_ci
42481cb0ef41Sopenharmony_ci    // codpoint = (trail << 16) | lead;
42491cb0ef41Sopenharmony_ci#if V8_TARGET_BIG_ENDIAN
42501cb0ef41Sopenharmony_ci    code = __ Word32Or(__ Word32Shl(lead, __ Int32Constant(16)), trail);
42511cb0ef41Sopenharmony_ci#else
42521cb0ef41Sopenharmony_ci    code = __ Word32Or(__ Word32Shl(trail, __ Int32Constant(16)), lead);
42531cb0ef41Sopenharmony_ci#endif
42541cb0ef41Sopenharmony_ci
42551cb0ef41Sopenharmony_ci    // Allocate a new SeqTwoByteString for {code}.
42561cb0ef41Sopenharmony_ci    Node* vfalse0 =
42571cb0ef41Sopenharmony_ci        __ Allocate(AllocationType::kYoung,
42581cb0ef41Sopenharmony_ci                    __ IntPtrConstant(SeqTwoByteString::SizeFor(2)));
42591cb0ef41Sopenharmony_ci    __ StoreField(AccessBuilder::ForMap(), vfalse0,
42601cb0ef41Sopenharmony_ci                  __ HeapConstant(factory()->string_map()));
42611cb0ef41Sopenharmony_ci    __ StoreField(AccessBuilder::ForNameRawHashField(), vfalse0,
42621cb0ef41Sopenharmony_ci                  __ Int32Constant(Name::kEmptyHashField));
42631cb0ef41Sopenharmony_ci    __ StoreField(AccessBuilder::ForStringLength(), vfalse0,
42641cb0ef41Sopenharmony_ci                  __ Int32Constant(2));
42651cb0ef41Sopenharmony_ci    __ Store(
42661cb0ef41Sopenharmony_ci        StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier),
42671cb0ef41Sopenharmony_ci        vfalse0,
42681cb0ef41Sopenharmony_ci        __ IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag),
42691cb0ef41Sopenharmony_ci        code);
42701cb0ef41Sopenharmony_ci    __ Goto(&done, vfalse0);
42711cb0ef41Sopenharmony_ci  }
42721cb0ef41Sopenharmony_ci
42731cb0ef41Sopenharmony_ci  __ Bind(&done);
42741cb0ef41Sopenharmony_ci  return done.PhiAt(0);
42751cb0ef41Sopenharmony_ci}
42761cb0ef41Sopenharmony_ci
42771cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringIndexOf(Node* node) {
42781cb0ef41Sopenharmony_ci  Node* subject = node->InputAt(0);
42791cb0ef41Sopenharmony_ci  Node* search_string = node->InputAt(1);
42801cb0ef41Sopenharmony_ci  Node* position = node->InputAt(2);
42811cb0ef41Sopenharmony_ci
42821cb0ef41Sopenharmony_ci  Callable callable = Builtins::CallableFor(isolate(), Builtin::kStringIndexOf);
42831cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kEliminatable;
42841cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
42851cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
42861cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
42871cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), flags, properties);
42881cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ HeapConstant(callable.code()), subject,
42891cb0ef41Sopenharmony_ci                 search_string, position, __ NoContextConstant());
42901cb0ef41Sopenharmony_ci}
42911cb0ef41Sopenharmony_ci
42921cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringFromCodePointAt(Node* node) {
42931cb0ef41Sopenharmony_ci  Node* string = node->InputAt(0);
42941cb0ef41Sopenharmony_ci  Node* index = node->InputAt(1);
42951cb0ef41Sopenharmony_ci
42961cb0ef41Sopenharmony_ci  Callable callable =
42971cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kStringFromCodePointAt);
42981cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kEliminatable;
42991cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
43001cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
43011cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
43021cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), flags, properties);
43031cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ HeapConstant(callable.code()), string,
43041cb0ef41Sopenharmony_ci                 index, __ NoContextConstant());
43051cb0ef41Sopenharmony_ci}
43061cb0ef41Sopenharmony_ci
43071cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringLength(Node* node) {
43081cb0ef41Sopenharmony_ci  Node* subject = node->InputAt(0);
43091cb0ef41Sopenharmony_ci
43101cb0ef41Sopenharmony_ci  return __ LoadField(AccessBuilder::ForStringLength(), subject);
43111cb0ef41Sopenharmony_ci}
43121cb0ef41Sopenharmony_ci
43131cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringComparison(Callable const& callable,
43141cb0ef41Sopenharmony_ci                                                     Node* node) {
43151cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(0);
43161cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(1);
43171cb0ef41Sopenharmony_ci
43181cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kEliminatable;
43191cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
43201cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
43211cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
43221cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), flags, properties);
43231cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs, rhs,
43241cb0ef41Sopenharmony_ci                 __ NoContextConstant());
43251cb0ef41Sopenharmony_ci}
43261cb0ef41Sopenharmony_ci
43271cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringSubstring(Node* node) {
43281cb0ef41Sopenharmony_ci  Node* receiver = node->InputAt(0);
43291cb0ef41Sopenharmony_ci  Node* start = ChangeInt32ToIntPtr(node->InputAt(1));
43301cb0ef41Sopenharmony_ci  Node* end = ChangeInt32ToIntPtr(node->InputAt(2));
43311cb0ef41Sopenharmony_ci
43321cb0ef41Sopenharmony_ci  Callable callable =
43331cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kStringSubstring);
43341cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kEliminatable;
43351cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
43361cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
43371cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
43381cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), flags, properties);
43391cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ HeapConstant(callable.code()), receiver,
43401cb0ef41Sopenharmony_ci                 start, end, __ NoContextConstant());
43411cb0ef41Sopenharmony_ci}
43421cb0ef41Sopenharmony_ci
43431cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringEqual(Node* node) {
43441cb0ef41Sopenharmony_ci  return LowerStringComparison(
43451cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kStringEqual), node);
43461cb0ef41Sopenharmony_ci}
43471cb0ef41Sopenharmony_ci
43481cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringLessThan(Node* node) {
43491cb0ef41Sopenharmony_ci  return LowerStringComparison(
43501cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kStringLessThan), node);
43511cb0ef41Sopenharmony_ci}
43521cb0ef41Sopenharmony_ci
43531cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerStringLessThanOrEqual(Node* node) {
43541cb0ef41Sopenharmony_ci  return LowerStringComparison(
43551cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kStringLessThanOrEqual), node);
43561cb0ef41Sopenharmony_ci}
43571cb0ef41Sopenharmony_ci
43581cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerBigIntAdd(Node* node, Node* frame_state) {
43591cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(0);
43601cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(1);
43611cb0ef41Sopenharmony_ci
43621cb0ef41Sopenharmony_ci  Callable const callable =
43631cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kBigIntAddNoThrow);
43641cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
43651cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
43661cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags,
43671cb0ef41Sopenharmony_ci      Operator::kFoldable | Operator::kNoThrow);
43681cb0ef41Sopenharmony_ci  Node* value = __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs,
43691cb0ef41Sopenharmony_ci                        rhs, __ NoContextConstant());
43701cb0ef41Sopenharmony_ci
43711cb0ef41Sopenharmony_ci  // Check for exception sentinel: Smi is returned to signal BigIntTooBig.
43721cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kBigIntTooBig, FeedbackSource{},
43731cb0ef41Sopenharmony_ci                  ObjectIsSmi(value), frame_state);
43741cb0ef41Sopenharmony_ci
43751cb0ef41Sopenharmony_ci  return value;
43761cb0ef41Sopenharmony_ci}
43771cb0ef41Sopenharmony_ci
43781cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerBigIntSubtract(Node* node,
43791cb0ef41Sopenharmony_ci                                                   Node* frame_state) {
43801cb0ef41Sopenharmony_ci  Node* lhs = node->InputAt(0);
43811cb0ef41Sopenharmony_ci  Node* rhs = node->InputAt(1);
43821cb0ef41Sopenharmony_ci
43831cb0ef41Sopenharmony_ci  Callable const callable =
43841cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kBigIntSubtractNoThrow);
43851cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
43861cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
43871cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags,
43881cb0ef41Sopenharmony_ci      Operator::kFoldable | Operator::kNoThrow);
43891cb0ef41Sopenharmony_ci  Node* value = __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs,
43901cb0ef41Sopenharmony_ci                        rhs, __ NoContextConstant());
43911cb0ef41Sopenharmony_ci
43921cb0ef41Sopenharmony_ci  // Check for exception sentinel: Smi is returned to signal BigIntTooBig.
43931cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kBigIntTooBig, FeedbackSource{},
43941cb0ef41Sopenharmony_ci                  ObjectIsSmi(value), frame_state);
43951cb0ef41Sopenharmony_ci
43961cb0ef41Sopenharmony_ci  return value;
43971cb0ef41Sopenharmony_ci}
43981cb0ef41Sopenharmony_ci
43991cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerBigIntNegate(Node* node) {
44001cb0ef41Sopenharmony_ci  Callable const callable =
44011cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kBigIntUnaryMinus);
44021cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
44031cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
44041cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags,
44051cb0ef41Sopenharmony_ci      Operator::kFoldable | Operator::kNoThrow);
44061cb0ef41Sopenharmony_ci  Node* value = __ Call(call_descriptor, __ HeapConstant(callable.code()),
44071cb0ef41Sopenharmony_ci                        node->InputAt(0), __ NoContextConstant());
44081cb0ef41Sopenharmony_ci
44091cb0ef41Sopenharmony_ci  return value;
44101cb0ef41Sopenharmony_ci}
44111cb0ef41Sopenharmony_ci
44121cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckFloat64Hole(Node* node,
44131cb0ef41Sopenharmony_ci                                                     Node* frame_state) {
44141cb0ef41Sopenharmony_ci  // If we reach this point w/o eliminating the {node} that's marked
44151cb0ef41Sopenharmony_ci  // with allow-return-hole, we cannot do anything, so just deoptimize
44161cb0ef41Sopenharmony_ci  // in case of the hole NaN.
44171cb0ef41Sopenharmony_ci  CheckFloat64HoleParameters const& params =
44181cb0ef41Sopenharmony_ci      CheckFloat64HoleParametersOf(node->op());
44191cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
44201cb0ef41Sopenharmony_ci
44211cb0ef41Sopenharmony_ci  auto if_nan = __ MakeDeferredLabel();
44221cb0ef41Sopenharmony_ci  auto done = __ MakeLabel();
44231cb0ef41Sopenharmony_ci
44241cb0ef41Sopenharmony_ci  // First check whether {value} is a NaN at all...
44251cb0ef41Sopenharmony_ci  __ Branch(__ Float64Equal(value, value), &done, &if_nan);
44261cb0ef41Sopenharmony_ci
44271cb0ef41Sopenharmony_ci  __ Bind(&if_nan);
44281cb0ef41Sopenharmony_ci  {
44291cb0ef41Sopenharmony_ci    // ...and only if {value} is a NaN, perform the expensive bit
44301cb0ef41Sopenharmony_ci    // check. See http://crbug.com/v8/8264 for details.
44311cb0ef41Sopenharmony_ci    Node* check = __ Word32Equal(__ Float64ExtractHighWord32(value),
44321cb0ef41Sopenharmony_ci                                 __ Int32Constant(kHoleNanUpper32));
44331cb0ef41Sopenharmony_ci    __ DeoptimizeIf(DeoptimizeReason::kHole, params.feedback(), check,
44341cb0ef41Sopenharmony_ci                    frame_state);
44351cb0ef41Sopenharmony_ci    __ Goto(&done);
44361cb0ef41Sopenharmony_ci  }
44371cb0ef41Sopenharmony_ci
44381cb0ef41Sopenharmony_ci  __ Bind(&done);
44391cb0ef41Sopenharmony_ci  return value;
44401cb0ef41Sopenharmony_ci}
44411cb0ef41Sopenharmony_ci
44421cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerCheckNotTaggedHole(Node* node,
44431cb0ef41Sopenharmony_ci                                                       Node* frame_state) {
44441cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
44451cb0ef41Sopenharmony_ci  Node* check = __ TaggedEqual(value, __ TheHoleConstant());
44461cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kHole, FeedbackSource(), check,
44471cb0ef41Sopenharmony_ci                  frame_state);
44481cb0ef41Sopenharmony_ci  return value;
44491cb0ef41Sopenharmony_ci}
44501cb0ef41Sopenharmony_ci
44511cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerConvertTaggedHoleToUndefined(Node* node) {
44521cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
44531cb0ef41Sopenharmony_ci
44541cb0ef41Sopenharmony_ci  auto if_is_hole = __ MakeDeferredLabel();
44551cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
44561cb0ef41Sopenharmony_ci
44571cb0ef41Sopenharmony_ci  Node* check = __ TaggedEqual(value, __ TheHoleConstant());
44581cb0ef41Sopenharmony_ci  __ GotoIf(check, &if_is_hole);
44591cb0ef41Sopenharmony_ci  __ Goto(&done, value);
44601cb0ef41Sopenharmony_ci
44611cb0ef41Sopenharmony_ci  __ Bind(&if_is_hole);
44621cb0ef41Sopenharmony_ci  __ Goto(&done, __ UndefinedConstant());
44631cb0ef41Sopenharmony_ci
44641cb0ef41Sopenharmony_ci  __ Bind(&done);
44651cb0ef41Sopenharmony_ci  return done.PhiAt(0);
44661cb0ef41Sopenharmony_ci}
44671cb0ef41Sopenharmony_ci
44681cb0ef41Sopenharmony_civoid EffectControlLinearizer::LowerCheckEqualsInternalizedString(
44691cb0ef41Sopenharmony_ci    Node* node, Node* frame_state) {
44701cb0ef41Sopenharmony_ci  Node* exp = node->InputAt(0);
44711cb0ef41Sopenharmony_ci  Node* val = node->InputAt(1);
44721cb0ef41Sopenharmony_ci
44731cb0ef41Sopenharmony_ci  auto if_same = __ MakeLabel();
44741cb0ef41Sopenharmony_ci  auto if_notsame = __ MakeDeferredLabel();
44751cb0ef41Sopenharmony_ci  auto if_thinstring = __ MakeLabel();
44761cb0ef41Sopenharmony_ci  auto if_notthinstring = __ MakeLabel();
44771cb0ef41Sopenharmony_ci
44781cb0ef41Sopenharmony_ci  // Check if {exp} and {val} are the same, which is the likely case.
44791cb0ef41Sopenharmony_ci  __ Branch(__ TaggedEqual(exp, val), &if_same, &if_notsame);
44801cb0ef41Sopenharmony_ci
44811cb0ef41Sopenharmony_ci  __ Bind(&if_notsame);
44821cb0ef41Sopenharmony_ci  {
44831cb0ef41Sopenharmony_ci    // Now {val} could still be a non-internalized String that matches {exp}.
44841cb0ef41Sopenharmony_ci    __ DeoptimizeIf(DeoptimizeReason::kWrongName, FeedbackSource(),
44851cb0ef41Sopenharmony_ci                    ObjectIsSmi(val), frame_state);
44861cb0ef41Sopenharmony_ci    Node* val_map = __ LoadField(AccessBuilder::ForMap(), val);
44871cb0ef41Sopenharmony_ci    Node* val_instance_type =
44881cb0ef41Sopenharmony_ci        __ LoadField(AccessBuilder::ForMapInstanceType(), val_map);
44891cb0ef41Sopenharmony_ci
44901cb0ef41Sopenharmony_ci    // Check for the common case of ThinString first.
44911cb0ef41Sopenharmony_ci    __ GotoIf(__ Word32Equal(val_instance_type,
44921cb0ef41Sopenharmony_ci                             __ Int32Constant(THIN_ONE_BYTE_STRING_TYPE)),
44931cb0ef41Sopenharmony_ci              &if_thinstring);
44941cb0ef41Sopenharmony_ci    __ Branch(
44951cb0ef41Sopenharmony_ci        __ Word32Equal(val_instance_type, __ Int32Constant(THIN_STRING_TYPE)),
44961cb0ef41Sopenharmony_ci        &if_thinstring, &if_notthinstring);
44971cb0ef41Sopenharmony_ci
44981cb0ef41Sopenharmony_ci    __ Bind(&if_notthinstring);
44991cb0ef41Sopenharmony_ci    {
45001cb0ef41Sopenharmony_ci      // Check that the {val} is a non-internalized String, if it's anything
45011cb0ef41Sopenharmony_ci      // else it cannot match the recorded feedback {exp} anyways.
45021cb0ef41Sopenharmony_ci      __ DeoptimizeIfNot(
45031cb0ef41Sopenharmony_ci          DeoptimizeReason::kWrongName, FeedbackSource(),
45041cb0ef41Sopenharmony_ci          __ Word32Equal(__ Word32And(val_instance_type,
45051cb0ef41Sopenharmony_ci                                      __ Int32Constant(kIsNotStringMask |
45061cb0ef41Sopenharmony_ci                                                       kIsNotInternalizedMask)),
45071cb0ef41Sopenharmony_ci                         __ Int32Constant(kStringTag | kNotInternalizedTag)),
45081cb0ef41Sopenharmony_ci          frame_state);
45091cb0ef41Sopenharmony_ci
45101cb0ef41Sopenharmony_ci      // Try to find the {val} in the string table.
45111cb0ef41Sopenharmony_ci      MachineSignature::Builder builder(graph()->zone(), 1, 2);
45121cb0ef41Sopenharmony_ci      builder.AddReturn(MachineType::AnyTagged());
45131cb0ef41Sopenharmony_ci      builder.AddParam(MachineType::Pointer());
45141cb0ef41Sopenharmony_ci      builder.AddParam(MachineType::AnyTagged());
45151cb0ef41Sopenharmony_ci      Node* try_string_to_index_or_lookup_existing = __ ExternalConstant(
45161cb0ef41Sopenharmony_ci          ExternalReference::try_string_to_index_or_lookup_existing());
45171cb0ef41Sopenharmony_ci      Node* const isolate_ptr =
45181cb0ef41Sopenharmony_ci          __ ExternalConstant(ExternalReference::isolate_address(isolate()));
45191cb0ef41Sopenharmony_ci      auto call_descriptor =
45201cb0ef41Sopenharmony_ci          Linkage::GetSimplifiedCDescriptor(graph()->zone(), builder.Build());
45211cb0ef41Sopenharmony_ci      Node* val_internalized =
45221cb0ef41Sopenharmony_ci          __ Call(common()->Call(call_descriptor),
45231cb0ef41Sopenharmony_ci                  try_string_to_index_or_lookup_existing, isolate_ptr, val);
45241cb0ef41Sopenharmony_ci
45251cb0ef41Sopenharmony_ci      // Now see if the results match.
45261cb0ef41Sopenharmony_ci      __ DeoptimizeIfNot(DeoptimizeReason::kWrongName, FeedbackSource(),
45271cb0ef41Sopenharmony_ci                         __ TaggedEqual(exp, val_internalized), frame_state);
45281cb0ef41Sopenharmony_ci      __ Goto(&if_same);
45291cb0ef41Sopenharmony_ci    }
45301cb0ef41Sopenharmony_ci
45311cb0ef41Sopenharmony_ci    __ Bind(&if_thinstring);
45321cb0ef41Sopenharmony_ci    {
45331cb0ef41Sopenharmony_ci      // The {val} is a ThinString, let's check the actual value.
45341cb0ef41Sopenharmony_ci      Node* val_actual =
45351cb0ef41Sopenharmony_ci          __ LoadField(AccessBuilder::ForThinStringActual(), val);
45361cb0ef41Sopenharmony_ci      __ DeoptimizeIfNot(DeoptimizeReason::kWrongName, FeedbackSource(),
45371cb0ef41Sopenharmony_ci                         __ TaggedEqual(exp, val_actual), frame_state);
45381cb0ef41Sopenharmony_ci      __ Goto(&if_same);
45391cb0ef41Sopenharmony_ci    }
45401cb0ef41Sopenharmony_ci  }
45411cb0ef41Sopenharmony_ci
45421cb0ef41Sopenharmony_ci  __ Bind(&if_same);
45431cb0ef41Sopenharmony_ci}
45441cb0ef41Sopenharmony_ci
45451cb0ef41Sopenharmony_civoid EffectControlLinearizer::LowerCheckEqualsSymbol(Node* node,
45461cb0ef41Sopenharmony_ci                                                     Node* frame_state) {
45471cb0ef41Sopenharmony_ci  Node* exp = node->InputAt(0);
45481cb0ef41Sopenharmony_ci  Node* val = node->InputAt(1);
45491cb0ef41Sopenharmony_ci  Node* check = __ TaggedEqual(exp, val);
45501cb0ef41Sopenharmony_ci  __ DeoptimizeIfNot(DeoptimizeReason::kWrongName, FeedbackSource(), check,
45511cb0ef41Sopenharmony_ci                     frame_state);
45521cb0ef41Sopenharmony_ci}
45531cb0ef41Sopenharmony_ci
45541cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value) {
45551cb0ef41Sopenharmony_ci  Node* result =
45561cb0ef41Sopenharmony_ci      __ Allocate(AllocationType::kYoung, __ IntPtrConstant(HeapNumber::kSize));
45571cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForMap(), result, __ HeapNumberMapConstant());
45581cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForHeapNumberValue(), result, value);
45591cb0ef41Sopenharmony_ci  return result;
45601cb0ef41Sopenharmony_ci}
45611cb0ef41Sopenharmony_ci
45621cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeIntPtrToSmi(Node* value) {
45631cb0ef41Sopenharmony_ci  // Do shift on 32bit values if Smis are stored in the lower word.
45641cb0ef41Sopenharmony_ci  if (machine()->Is64() && SmiValuesAre31Bits()) {
45651cb0ef41Sopenharmony_ci    return ChangeTaggedInt32ToSmi(__ Word32Shl(value, SmiShiftBitsConstant()));
45661cb0ef41Sopenharmony_ci  }
45671cb0ef41Sopenharmony_ci  return __ WordShl(value, SmiShiftBitsConstant());
45681cb0ef41Sopenharmony_ci}
45691cb0ef41Sopenharmony_ci
45701cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeTaggedInt32ToSmi(Node* value) {
45711cb0ef41Sopenharmony_ci  DCHECK(SmiValuesAre31Bits());
45721cb0ef41Sopenharmony_ci  // In pointer compression, we smi-corrupt. Then, the upper bits are not
45731cb0ef41Sopenharmony_ci  // important.
45741cb0ef41Sopenharmony_ci  return COMPRESS_POINTERS_BOOL ? __ BitcastWord32ToWord64(value)
45751cb0ef41Sopenharmony_ci                                : ChangeInt32ToIntPtr(value);
45761cb0ef41Sopenharmony_ci}
45771cb0ef41Sopenharmony_ci
45781cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeInt32ToIntPtr(Node* value) {
45791cb0ef41Sopenharmony_ci  if (machine()->Is64()) {
45801cb0ef41Sopenharmony_ci    value = __ ChangeInt32ToInt64(value);
45811cb0ef41Sopenharmony_ci  }
45821cb0ef41Sopenharmony_ci  return value;
45831cb0ef41Sopenharmony_ci}
45841cb0ef41Sopenharmony_ci
45851cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeIntPtrToInt32(Node* value) {
45861cb0ef41Sopenharmony_ci  if (machine()->Is64()) {
45871cb0ef41Sopenharmony_ci    value = __ TruncateInt64ToInt32(value);
45881cb0ef41Sopenharmony_ci  }
45891cb0ef41Sopenharmony_ci  return value;
45901cb0ef41Sopenharmony_ci}
45911cb0ef41Sopenharmony_ci
45921cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeInt32ToSmi(Node* value) {
45931cb0ef41Sopenharmony_ci  // Do shift on 32bit values if Smis are stored in the lower word.
45941cb0ef41Sopenharmony_ci  if (machine()->Is64() && SmiValuesAre31Bits()) {
45951cb0ef41Sopenharmony_ci    return ChangeIntPtrToSmi(value);
45961cb0ef41Sopenharmony_ci  }
45971cb0ef41Sopenharmony_ci  return ChangeIntPtrToSmi(ChangeInt32ToIntPtr(value));
45981cb0ef41Sopenharmony_ci}
45991cb0ef41Sopenharmony_ci
46001cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeInt64ToSmi(Node* value) {
46011cb0ef41Sopenharmony_ci  DCHECK(machine()->Is64());
46021cb0ef41Sopenharmony_ci  return ChangeIntPtrToSmi(value);
46031cb0ef41Sopenharmony_ci}
46041cb0ef41Sopenharmony_ci
46051cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeUint32ToUintPtr(Node* value) {
46061cb0ef41Sopenharmony_ci  if (machine()->Is64()) {
46071cb0ef41Sopenharmony_ci    value = __ ChangeUint32ToUint64(value);
46081cb0ef41Sopenharmony_ci  }
46091cb0ef41Sopenharmony_ci  return value;
46101cb0ef41Sopenharmony_ci}
46111cb0ef41Sopenharmony_ci
46121cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeUint32ToSmi(Node* value) {
46131cb0ef41Sopenharmony_ci  // Do shift on 32bit values if Smis are stored in the lower word.
46141cb0ef41Sopenharmony_ci  if (machine()->Is64() && SmiValuesAre31Bits()) {
46151cb0ef41Sopenharmony_ci    Node* smi_value = __ Word32Shl(value, SmiShiftBitsConstant());
46161cb0ef41Sopenharmony_ci    // In pointer compression, we smi-corrupt. Then, the upper bits are not
46171cb0ef41Sopenharmony_ci    // important.
46181cb0ef41Sopenharmony_ci    return COMPRESS_POINTERS_BOOL ? __ BitcastWord32ToWord64(smi_value)
46191cb0ef41Sopenharmony_ci                                  : __ ChangeUint32ToUint64(smi_value);
46201cb0ef41Sopenharmony_ci  } else {
46211cb0ef41Sopenharmony_ci    return __ WordShl(ChangeUint32ToUintPtr(value), SmiShiftBitsConstant());
46221cb0ef41Sopenharmony_ci  }
46231cb0ef41Sopenharmony_ci}
46241cb0ef41Sopenharmony_ci
46251cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeSmiToIntPtr(Node* value) {
46261cb0ef41Sopenharmony_ci  if (machine()->Is64() && SmiValuesAre31Bits()) {
46271cb0ef41Sopenharmony_ci    // First sign-extend the upper half, then shift away the Smi tag.
46281cb0ef41Sopenharmony_ci    return __ WordSarShiftOutZeros(
46291cb0ef41Sopenharmony_ci        __ ChangeInt32ToInt64(__ TruncateInt64ToInt32(value)),
46301cb0ef41Sopenharmony_ci        SmiShiftBitsConstant());
46311cb0ef41Sopenharmony_ci  }
46321cb0ef41Sopenharmony_ci  return __ WordSarShiftOutZeros(value, SmiShiftBitsConstant());
46331cb0ef41Sopenharmony_ci}
46341cb0ef41Sopenharmony_ci
46351cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeSmiToInt32(Node* value) {
46361cb0ef41Sopenharmony_ci  // Do shift on 32bit values if Smis are stored in the lower word.
46371cb0ef41Sopenharmony_ci  if (machine()->Is64() && SmiValuesAre31Bits()) {
46381cb0ef41Sopenharmony_ci    return __ Word32SarShiftOutZeros(__ TruncateInt64ToInt32(value),
46391cb0ef41Sopenharmony_ci                                     SmiShiftBitsConstant());
46401cb0ef41Sopenharmony_ci  }
46411cb0ef41Sopenharmony_ci  if (machine()->Is64()) {
46421cb0ef41Sopenharmony_ci    return __ TruncateInt64ToInt32(ChangeSmiToIntPtr(value));
46431cb0ef41Sopenharmony_ci  }
46441cb0ef41Sopenharmony_ci  return ChangeSmiToIntPtr(value);
46451cb0ef41Sopenharmony_ci}
46461cb0ef41Sopenharmony_ci
46471cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ChangeSmiToInt64(Node* value) {
46481cb0ef41Sopenharmony_ci  CHECK(machine()->Is64());
46491cb0ef41Sopenharmony_ci  return ChangeSmiToIntPtr(value);
46501cb0ef41Sopenharmony_ci}
46511cb0ef41Sopenharmony_ci
46521cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ObjectIsSmi(Node* value) {
46531cb0ef41Sopenharmony_ci  return __ Word32Equal(__ Word32And(value, __ Int32Constant(kSmiTagMask)),
46541cb0ef41Sopenharmony_ci                        __ Int32Constant(kSmiTag));
46551cb0ef41Sopenharmony_ci}
46561cb0ef41Sopenharmony_ci
46571cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::SmiMaxValueConstant() {
46581cb0ef41Sopenharmony_ci  return __ Int32Constant(Smi::kMaxValue);
46591cb0ef41Sopenharmony_ci}
46601cb0ef41Sopenharmony_ci
46611cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::SmiShiftBitsConstant() {
46621cb0ef41Sopenharmony_ci  if (machine()->Is64() && SmiValuesAre31Bits()) {
46631cb0ef41Sopenharmony_ci    return __ Int32Constant(kSmiShiftSize + kSmiTagSize);
46641cb0ef41Sopenharmony_ci  }
46651cb0ef41Sopenharmony_ci  return __ IntPtrConstant(kSmiShiftSize + kSmiTagSize);
46661cb0ef41Sopenharmony_ci}
46671cb0ef41Sopenharmony_ci
46681cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerPlainPrimitiveToNumber(Node* node) {
46691cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
46701cb0ef41Sopenharmony_ci  return __ PlainPrimitiveToNumber(TNode<Object>::UncheckedCast(value));
46711cb0ef41Sopenharmony_ci}
46721cb0ef41Sopenharmony_ci
46731cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerPlainPrimitiveToWord32(Node* node) {
46741cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
46751cb0ef41Sopenharmony_ci
46761cb0ef41Sopenharmony_ci  auto if_not_smi = __ MakeDeferredLabel();
46771cb0ef41Sopenharmony_ci  auto if_to_number_smi = __ MakeLabel();
46781cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kWord32);
46791cb0ef41Sopenharmony_ci
46801cb0ef41Sopenharmony_ci  Node* check0 = ObjectIsSmi(value);
46811cb0ef41Sopenharmony_ci  __ GotoIfNot(check0, &if_not_smi);
46821cb0ef41Sopenharmony_ci  __ Goto(&done, ChangeSmiToInt32(value));
46831cb0ef41Sopenharmony_ci
46841cb0ef41Sopenharmony_ci  __ Bind(&if_not_smi);
46851cb0ef41Sopenharmony_ci  Node* to_number =
46861cb0ef41Sopenharmony_ci      __ PlainPrimitiveToNumber(TNode<Object>::UncheckedCast(value));
46871cb0ef41Sopenharmony_ci
46881cb0ef41Sopenharmony_ci  Node* check1 = ObjectIsSmi(to_number);
46891cb0ef41Sopenharmony_ci  __ GotoIf(check1, &if_to_number_smi);
46901cb0ef41Sopenharmony_ci  Node* number = __ LoadField(AccessBuilder::ForHeapNumberValue(), to_number);
46911cb0ef41Sopenharmony_ci  __ Goto(&done, __ TruncateFloat64ToWord32(number));
46921cb0ef41Sopenharmony_ci
46931cb0ef41Sopenharmony_ci  __ Bind(&if_to_number_smi);
46941cb0ef41Sopenharmony_ci  __ Goto(&done, ChangeSmiToInt32(to_number));
46951cb0ef41Sopenharmony_ci
46961cb0ef41Sopenharmony_ci  __ Bind(&done);
46971cb0ef41Sopenharmony_ci  return done.PhiAt(0);
46981cb0ef41Sopenharmony_ci}
46991cb0ef41Sopenharmony_ci
47001cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerPlainPrimitiveToFloat64(Node* node) {
47011cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
47021cb0ef41Sopenharmony_ci
47031cb0ef41Sopenharmony_ci  auto if_not_smi = __ MakeDeferredLabel();
47041cb0ef41Sopenharmony_ci  auto if_to_number_smi = __ MakeLabel();
47051cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kFloat64);
47061cb0ef41Sopenharmony_ci
47071cb0ef41Sopenharmony_ci  Node* check0 = ObjectIsSmi(value);
47081cb0ef41Sopenharmony_ci  __ GotoIfNot(check0, &if_not_smi);
47091cb0ef41Sopenharmony_ci  Node* from_smi = ChangeSmiToInt32(value);
47101cb0ef41Sopenharmony_ci  __ Goto(&done, __ ChangeInt32ToFloat64(from_smi));
47111cb0ef41Sopenharmony_ci
47121cb0ef41Sopenharmony_ci  __ Bind(&if_not_smi);
47131cb0ef41Sopenharmony_ci  Node* to_number =
47141cb0ef41Sopenharmony_ci      __ PlainPrimitiveToNumber(TNode<Object>::UncheckedCast(value));
47151cb0ef41Sopenharmony_ci  Node* check1 = ObjectIsSmi(to_number);
47161cb0ef41Sopenharmony_ci  __ GotoIf(check1, &if_to_number_smi);
47171cb0ef41Sopenharmony_ci
47181cb0ef41Sopenharmony_ci  Node* number = __ LoadField(AccessBuilder::ForHeapNumberValue(), to_number);
47191cb0ef41Sopenharmony_ci  __ Goto(&done, number);
47201cb0ef41Sopenharmony_ci
47211cb0ef41Sopenharmony_ci  __ Bind(&if_to_number_smi);
47221cb0ef41Sopenharmony_ci  Node* number_from_smi = ChangeSmiToInt32(to_number);
47231cb0ef41Sopenharmony_ci  number_from_smi = __ ChangeInt32ToFloat64(number_from_smi);
47241cb0ef41Sopenharmony_ci  __ Goto(&done, number_from_smi);
47251cb0ef41Sopenharmony_ci
47261cb0ef41Sopenharmony_ci  __ Bind(&done);
47271cb0ef41Sopenharmony_ci  return done.PhiAt(0);
47281cb0ef41Sopenharmony_ci}
47291cb0ef41Sopenharmony_ci
47301cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerEnsureWritableFastElements(Node* node) {
47311cb0ef41Sopenharmony_ci  Node* object = node->InputAt(0);
47321cb0ef41Sopenharmony_ci  Node* elements = node->InputAt(1);
47331cb0ef41Sopenharmony_ci
47341cb0ef41Sopenharmony_ci  auto if_not_fixed_array = __ MakeDeferredLabel();
47351cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
47361cb0ef41Sopenharmony_ci
47371cb0ef41Sopenharmony_ci  // Load the current map of {elements}.
47381cb0ef41Sopenharmony_ci  Node* elements_map = __ LoadField(AccessBuilder::ForMap(), elements);
47391cb0ef41Sopenharmony_ci
47401cb0ef41Sopenharmony_ci  // Check if {elements} is not a copy-on-write FixedArray.
47411cb0ef41Sopenharmony_ci  Node* check = __ TaggedEqual(elements_map, __ FixedArrayMapConstant());
47421cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &if_not_fixed_array);
47431cb0ef41Sopenharmony_ci  // Nothing to do if the {elements} are not copy-on-write.
47441cb0ef41Sopenharmony_ci  __ Goto(&done, elements);
47451cb0ef41Sopenharmony_ci
47461cb0ef41Sopenharmony_ci  __ Bind(&if_not_fixed_array);
47471cb0ef41Sopenharmony_ci  // We need to take a copy of the {elements} and set them up for {object}.
47481cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kEliminatable;
47491cb0ef41Sopenharmony_ci  Callable callable =
47501cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kCopyFastSmiOrObjectElements);
47511cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
47521cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
47531cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
47541cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), flags, properties);
47551cb0ef41Sopenharmony_ci  Node* result = __ Call(call_descriptor, __ HeapConstant(callable.code()),
47561cb0ef41Sopenharmony_ci                         object, __ NoContextConstant());
47571cb0ef41Sopenharmony_ci  __ Goto(&done, result);
47581cb0ef41Sopenharmony_ci
47591cb0ef41Sopenharmony_ci  __ Bind(&done);
47601cb0ef41Sopenharmony_ci  return done.PhiAt(0);
47611cb0ef41Sopenharmony_ci}
47621cb0ef41Sopenharmony_ci
47631cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node,
47641cb0ef41Sopenharmony_ci                                                          Node* frame_state) {
47651cb0ef41Sopenharmony_ci  GrowFastElementsParameters params = GrowFastElementsParametersOf(node->op());
47661cb0ef41Sopenharmony_ci  Node* object = node->InputAt(0);
47671cb0ef41Sopenharmony_ci  Node* elements = node->InputAt(1);
47681cb0ef41Sopenharmony_ci  Node* index = node->InputAt(2);
47691cb0ef41Sopenharmony_ci  Node* elements_length = node->InputAt(3);
47701cb0ef41Sopenharmony_ci
47711cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
47721cb0ef41Sopenharmony_ci  auto if_grow = __ MakeDeferredLabel();
47731cb0ef41Sopenharmony_ci  auto if_not_grow = __ MakeLabel();
47741cb0ef41Sopenharmony_ci
47751cb0ef41Sopenharmony_ci  // Check if we need to grow the {elements} backing store.
47761cb0ef41Sopenharmony_ci  Node* check = __ Uint32LessThan(index, elements_length);
47771cb0ef41Sopenharmony_ci  __ GotoIfNot(check, &if_grow);
47781cb0ef41Sopenharmony_ci  __ Goto(&done, elements);
47791cb0ef41Sopenharmony_ci
47801cb0ef41Sopenharmony_ci  __ Bind(&if_grow);
47811cb0ef41Sopenharmony_ci  // We need to grow the {elements} for {object}.
47821cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kEliminatable;
47831cb0ef41Sopenharmony_ci  Callable callable =
47841cb0ef41Sopenharmony_ci      (params.mode() == GrowFastElementsMode::kDoubleElements)
47851cb0ef41Sopenharmony_ci          ? Builtins::CallableFor(isolate(), Builtin::kGrowFastDoubleElements)
47861cb0ef41Sopenharmony_ci          : Builtins::CallableFor(isolate(),
47871cb0ef41Sopenharmony_ci                                  Builtin::kGrowFastSmiOrObjectElements);
47881cb0ef41Sopenharmony_ci  CallDescriptor::Flags call_flags = CallDescriptor::kNoFlags;
47891cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
47901cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
47911cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), call_flags, properties);
47921cb0ef41Sopenharmony_ci  Node* new_elements =
47931cb0ef41Sopenharmony_ci      __ Call(call_descriptor, __ HeapConstant(callable.code()), object,
47941cb0ef41Sopenharmony_ci              ChangeInt32ToSmi(index), __ NoContextConstant());
47951cb0ef41Sopenharmony_ci
47961cb0ef41Sopenharmony_ci  // Ensure that we were able to grow the {elements}.
47971cb0ef41Sopenharmony_ci  __ DeoptimizeIf(DeoptimizeReason::kCouldNotGrowElements, params.feedback(),
47981cb0ef41Sopenharmony_ci                  ObjectIsSmi(new_elements), frame_state);
47991cb0ef41Sopenharmony_ci  __ Goto(&done, new_elements);
48001cb0ef41Sopenharmony_ci
48011cb0ef41Sopenharmony_ci  __ Bind(&done);
48021cb0ef41Sopenharmony_ci  return done.PhiAt(0);
48031cb0ef41Sopenharmony_ci}
48041cb0ef41Sopenharmony_ci
48051cb0ef41Sopenharmony_civoid EffectControlLinearizer::LowerTransitionElementsKind(Node* node) {
48061cb0ef41Sopenharmony_ci  ElementsTransition const transition = ElementsTransitionOf(node->op());
48071cb0ef41Sopenharmony_ci  Node* object = node->InputAt(0);
48081cb0ef41Sopenharmony_ci
48091cb0ef41Sopenharmony_ci  auto if_map_same = __ MakeDeferredLabel();
48101cb0ef41Sopenharmony_ci  auto done = __ MakeLabel();
48111cb0ef41Sopenharmony_ci
48121cb0ef41Sopenharmony_ci  Node* source_map = __ HeapConstant(transition.source());
48131cb0ef41Sopenharmony_ci  Node* target_map = __ HeapConstant(transition.target());
48141cb0ef41Sopenharmony_ci
48151cb0ef41Sopenharmony_ci  // Load the current map of {object}.
48161cb0ef41Sopenharmony_ci  Node* object_map = __ LoadField(AccessBuilder::ForMap(), object);
48171cb0ef41Sopenharmony_ci
48181cb0ef41Sopenharmony_ci  // Check if {object_map} is the same as {source_map}.
48191cb0ef41Sopenharmony_ci  Node* check = __ TaggedEqual(object_map, source_map);
48201cb0ef41Sopenharmony_ci  __ GotoIf(check, &if_map_same);
48211cb0ef41Sopenharmony_ci  __ Goto(&done);
48221cb0ef41Sopenharmony_ci
48231cb0ef41Sopenharmony_ci  __ Bind(&if_map_same);
48241cb0ef41Sopenharmony_ci  switch (transition.mode()) {
48251cb0ef41Sopenharmony_ci    case ElementsTransition::kFastTransition:
48261cb0ef41Sopenharmony_ci      // In-place migration of {object}, just store the {target_map}.
48271cb0ef41Sopenharmony_ci      __ StoreField(AccessBuilder::ForMap(), object, target_map);
48281cb0ef41Sopenharmony_ci      break;
48291cb0ef41Sopenharmony_ci    case ElementsTransition::kSlowTransition: {
48301cb0ef41Sopenharmony_ci      // Instance migration, call out to the runtime for {object}.
48311cb0ef41Sopenharmony_ci      Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
48321cb0ef41Sopenharmony_ci      Runtime::FunctionId id = Runtime::kTransitionElementsKind;
48331cb0ef41Sopenharmony_ci      auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
48341cb0ef41Sopenharmony_ci          graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
48351cb0ef41Sopenharmony_ci      __ Call(call_descriptor, __ CEntryStubConstant(1), object, target_map,
48361cb0ef41Sopenharmony_ci              __ ExternalConstant(ExternalReference::Create(id)),
48371cb0ef41Sopenharmony_ci              __ Int32Constant(2), __ NoContextConstant());
48381cb0ef41Sopenharmony_ci      break;
48391cb0ef41Sopenharmony_ci    }
48401cb0ef41Sopenharmony_ci  }
48411cb0ef41Sopenharmony_ci  __ Goto(&done);
48421cb0ef41Sopenharmony_ci
48431cb0ef41Sopenharmony_ci  __ Bind(&done);
48441cb0ef41Sopenharmony_ci}
48451cb0ef41Sopenharmony_ci
48461cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerLoadMessage(Node* node) {
48471cb0ef41Sopenharmony_ci  Node* offset = node->InputAt(0);
48481cb0ef41Sopenharmony_ci  Node* object_pattern =
48491cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForExternalIntPtr(), offset);
48501cb0ef41Sopenharmony_ci  return __ BitcastWordToTagged(object_pattern);
48511cb0ef41Sopenharmony_ci}
48521cb0ef41Sopenharmony_ci
48531cb0ef41Sopenharmony_civoid EffectControlLinearizer::LowerStoreMessage(Node* node) {
48541cb0ef41Sopenharmony_ci  Node* offset = node->InputAt(0);
48551cb0ef41Sopenharmony_ci  Node* object = node->InputAt(1);
48561cb0ef41Sopenharmony_ci  Node* object_pattern = __ BitcastTaggedToWord(object);
48571cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForExternalIntPtr(), offset, object_pattern);
48581cb0ef41Sopenharmony_ci}
48591cb0ef41Sopenharmony_ci
48601cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::AdaptFastCallTypedArrayArgument(
48611cb0ef41Sopenharmony_ci    Node* node, ElementsKind expected_elements_kind,
48621cb0ef41Sopenharmony_ci    GraphAssemblerLabel<0>* bailout) {
48631cb0ef41Sopenharmony_ci  Node* value_map = __ LoadField(AccessBuilder::ForMap(), node);
48641cb0ef41Sopenharmony_ci  Node* value_instance_type =
48651cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
48661cb0ef41Sopenharmony_ci  Node* value_is_typed_array = __ Word32Equal(
48671cb0ef41Sopenharmony_ci      value_instance_type, __ Int32Constant(JS_TYPED_ARRAY_TYPE));
48681cb0ef41Sopenharmony_ci  __ GotoIfNot(value_is_typed_array, bailout);
48691cb0ef41Sopenharmony_ci
48701cb0ef41Sopenharmony_ci  Node* bit_field2 = __ LoadField(AccessBuilder::ForMapBitField2(), value_map);
48711cb0ef41Sopenharmony_ci  Node* mask = __ Int32Constant(Map::Bits2::ElementsKindBits::kMask);
48721cb0ef41Sopenharmony_ci  Node* andit = __ Word32And(bit_field2, mask);
48731cb0ef41Sopenharmony_ci  Node* shift = __ Int32Constant(Map::Bits2::ElementsKindBits::kShift);
48741cb0ef41Sopenharmony_ci  Node* kind = __ Word32Shr(andit, shift);
48751cb0ef41Sopenharmony_ci
48761cb0ef41Sopenharmony_ci  Node* value_is_expected_elements_kind =
48771cb0ef41Sopenharmony_ci      __ Word32Equal(kind, __ Int32Constant(expected_elements_kind));
48781cb0ef41Sopenharmony_ci  __ GotoIfNot(value_is_expected_elements_kind, bailout);
48791cb0ef41Sopenharmony_ci
48801cb0ef41Sopenharmony_ci  Node* buffer =
48811cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForJSArrayBufferViewBuffer(), node);
48821cb0ef41Sopenharmony_ci  Node* buffer_bit_field =
48831cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForJSArrayBufferBitField(), buffer);
48841cb0ef41Sopenharmony_ci
48851cb0ef41Sopenharmony_ci  // Go to the slow path if the {buffer} was detached.
48861cb0ef41Sopenharmony_ci  Node* buffer_is_not_detached = __ Word32Equal(
48871cb0ef41Sopenharmony_ci      __ Word32And(buffer_bit_field,
48881cb0ef41Sopenharmony_ci                   __ Int32Constant(JSArrayBuffer::WasDetachedBit::kMask)),
48891cb0ef41Sopenharmony_ci      __ ZeroConstant());
48901cb0ef41Sopenharmony_ci  __ GotoIfNot(buffer_is_not_detached, bailout);
48911cb0ef41Sopenharmony_ci
48921cb0ef41Sopenharmony_ci  // Go to the slow path if the {buffer} is shared.
48931cb0ef41Sopenharmony_ci  Node* buffer_is_not_shared = __ Word32Equal(
48941cb0ef41Sopenharmony_ci      __ Word32And(buffer_bit_field,
48951cb0ef41Sopenharmony_ci                   __ Int32Constant(JSArrayBuffer::IsSharedBit::kMask)),
48961cb0ef41Sopenharmony_ci      __ ZeroConstant());
48971cb0ef41Sopenharmony_ci  __ GotoIfNot(buffer_is_not_shared, bailout);
48981cb0ef41Sopenharmony_ci
48991cb0ef41Sopenharmony_ci  // Unpack the store and length, and store them to a struct
49001cb0ef41Sopenharmony_ci  // FastApiTypedArray.
49011cb0ef41Sopenharmony_ci  Node* external_pointer =
49021cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForJSTypedArrayExternalPointer(), node);
49031cb0ef41Sopenharmony_ci
49041cb0ef41Sopenharmony_ci  // Load the base pointer for the buffer. This will always be Smi
49051cb0ef41Sopenharmony_ci  // zero unless we allow on-heap TypedArrays, which is only the case
49061cb0ef41Sopenharmony_ci  // for Chrome. Node and Electron both set this limit to 0. Setting
49071cb0ef41Sopenharmony_ci  // the base to Smi zero here allows the BuildTypedArrayDataPointer
49081cb0ef41Sopenharmony_ci  // to optimize away the tricky part of the access later.
49091cb0ef41Sopenharmony_ci  Node* base_pointer =
49101cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForJSTypedArrayBasePointer(), node);
49111cb0ef41Sopenharmony_ci  if (JSTypedArray::kMaxSizeInHeap == 0) {
49121cb0ef41Sopenharmony_ci    base_pointer = jsgraph()->ZeroConstant();
49131cb0ef41Sopenharmony_ci  }
49141cb0ef41Sopenharmony_ci  Node* data_ptr = BuildTypedArrayDataPointer(base_pointer, external_pointer);
49151cb0ef41Sopenharmony_ci  Node* length_in_bytes =
49161cb0ef41Sopenharmony_ci      __ LoadField(AccessBuilder::ForJSTypedArrayLength(), node);
49171cb0ef41Sopenharmony_ci
49181cb0ef41Sopenharmony_ci  // We hard-code int32_t here, because all specializations of
49191cb0ef41Sopenharmony_ci  // FastApiTypedArray have the same size.
49201cb0ef41Sopenharmony_ci  constexpr int kAlign = alignof(FastApiTypedArray<int32_t>);
49211cb0ef41Sopenharmony_ci  constexpr int kSize = sizeof(FastApiTypedArray<int32_t>);
49221cb0ef41Sopenharmony_ci  static_assert(kAlign == alignof(FastApiTypedArray<double>),
49231cb0ef41Sopenharmony_ci                "Alignment mismatch between different specializations of "
49241cb0ef41Sopenharmony_ci                "FastApiTypedArray");
49251cb0ef41Sopenharmony_ci  static_assert(kSize == sizeof(FastApiTypedArray<double>),
49261cb0ef41Sopenharmony_ci                "Size mismatch between different specializations of "
49271cb0ef41Sopenharmony_ci                "FastApiTypedArray");
49281cb0ef41Sopenharmony_ci  static_assert(
49291cb0ef41Sopenharmony_ci      kSize == sizeof(uintptr_t) + sizeof(size_t),
49301cb0ef41Sopenharmony_ci      "The size of "
49311cb0ef41Sopenharmony_ci      "FastApiTypedArray isn't equal to the sum of its expected members.");
49321cb0ef41Sopenharmony_ci  Node* stack_slot = __ StackSlot(kSize, kAlign);
49331cb0ef41Sopenharmony_ci
49341cb0ef41Sopenharmony_ci  __ Store(StoreRepresentation(MachineType::PointerRepresentation(),
49351cb0ef41Sopenharmony_ci                               kNoWriteBarrier),
49361cb0ef41Sopenharmony_ci           stack_slot, 0, length_in_bytes);
49371cb0ef41Sopenharmony_ci  __ Store(StoreRepresentation(MachineType::PointerRepresentation(),
49381cb0ef41Sopenharmony_ci                               kNoWriteBarrier),
49391cb0ef41Sopenharmony_ci           stack_slot, sizeof(size_t), data_ptr);
49401cb0ef41Sopenharmony_ci  static_assert(sizeof(uintptr_t) == sizeof(size_t),
49411cb0ef41Sopenharmony_ci                "The buffer length can't "
49421cb0ef41Sopenharmony_ci                "fit the PointerRepresentation used to store it.");
49431cb0ef41Sopenharmony_ci
49441cb0ef41Sopenharmony_ci  return stack_slot;
49451cb0ef41Sopenharmony_ci}
49461cb0ef41Sopenharmony_ci
49471cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::AdaptFastCallArgument(
49481cb0ef41Sopenharmony_ci    Node* node, CTypeInfo arg_type, GraphAssemblerLabel<0>* if_error) {
49491cb0ef41Sopenharmony_ci  int kAlign = alignof(uintptr_t);
49501cb0ef41Sopenharmony_ci  int kSize = sizeof(uintptr_t);
49511cb0ef41Sopenharmony_ci  switch (arg_type.GetSequenceType()) {
49521cb0ef41Sopenharmony_ci    case CTypeInfo::SequenceType::kScalar: {
49531cb0ef41Sopenharmony_ci      switch (arg_type.GetType()) {
49541cb0ef41Sopenharmony_ci        case CTypeInfo::Type::kV8Value: {
49551cb0ef41Sopenharmony_ci          Node* stack_slot = __ StackSlot(kSize, kAlign);
49561cb0ef41Sopenharmony_ci          __ Store(StoreRepresentation(MachineType::PointerRepresentation(),
49571cb0ef41Sopenharmony_ci                                       kNoWriteBarrier),
49581cb0ef41Sopenharmony_ci                   stack_slot, 0, node);
49591cb0ef41Sopenharmony_ci
49601cb0ef41Sopenharmony_ci          return stack_slot;
49611cb0ef41Sopenharmony_ci        }
49621cb0ef41Sopenharmony_ci        case CTypeInfo::Type::kFloat32: {
49631cb0ef41Sopenharmony_ci          return __ TruncateFloat64ToFloat32(node);
49641cb0ef41Sopenharmony_ci        }
49651cb0ef41Sopenharmony_ci        default: {
49661cb0ef41Sopenharmony_ci          return node;
49671cb0ef41Sopenharmony_ci        }
49681cb0ef41Sopenharmony_ci      }
49691cb0ef41Sopenharmony_ci    }
49701cb0ef41Sopenharmony_ci    case CTypeInfo::SequenceType::kIsSequence: {
49711cb0ef41Sopenharmony_ci      CHECK_EQ(arg_type.GetType(), CTypeInfo::Type::kVoid);
49721cb0ef41Sopenharmony_ci
49731cb0ef41Sopenharmony_ci      // Check that the value is a HeapObject.
49741cb0ef41Sopenharmony_ci      Node* value_is_smi = ObjectIsSmi(node);
49751cb0ef41Sopenharmony_ci      __ GotoIf(value_is_smi, if_error);
49761cb0ef41Sopenharmony_ci
49771cb0ef41Sopenharmony_ci      Node* stack_slot = __ StackSlot(kSize, kAlign);
49781cb0ef41Sopenharmony_ci      __ Store(StoreRepresentation(MachineType::PointerRepresentation(),
49791cb0ef41Sopenharmony_ci                                   kNoWriteBarrier),
49801cb0ef41Sopenharmony_ci               stack_slot, 0, node);
49811cb0ef41Sopenharmony_ci
49821cb0ef41Sopenharmony_ci      // Check that the value is a JSArray.
49831cb0ef41Sopenharmony_ci      Node* value_map = __ LoadField(AccessBuilder::ForMap(), node);
49841cb0ef41Sopenharmony_ci      Node* value_instance_type =
49851cb0ef41Sopenharmony_ci          __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
49861cb0ef41Sopenharmony_ci      Node* value_is_js_array =
49871cb0ef41Sopenharmony_ci          __ Word32Equal(value_instance_type, __ Int32Constant(JS_ARRAY_TYPE));
49881cb0ef41Sopenharmony_ci      __ GotoIfNot(value_is_js_array, if_error);
49891cb0ef41Sopenharmony_ci
49901cb0ef41Sopenharmony_ci      return stack_slot;
49911cb0ef41Sopenharmony_ci    }
49921cb0ef41Sopenharmony_ci    case CTypeInfo::SequenceType::kIsTypedArray: {
49931cb0ef41Sopenharmony_ci      // Check that the value is a HeapObject.
49941cb0ef41Sopenharmony_ci      Node* value_is_smi = ObjectIsSmi(node);
49951cb0ef41Sopenharmony_ci      __ GotoIf(value_is_smi, if_error);
49961cb0ef41Sopenharmony_ci
49971cb0ef41Sopenharmony_ci      return AdaptFastCallTypedArrayArgument(
49981cb0ef41Sopenharmony_ci          node, fast_api_call::GetTypedArrayElementsKind(arg_type.GetType()),
49991cb0ef41Sopenharmony_ci          if_error);
50001cb0ef41Sopenharmony_ci    }
50011cb0ef41Sopenharmony_ci    default: {
50021cb0ef41Sopenharmony_ci      UNREACHABLE();
50031cb0ef41Sopenharmony_ci    }
50041cb0ef41Sopenharmony_ci  }
50051cb0ef41Sopenharmony_ci}
50061cb0ef41Sopenharmony_ci
50071cb0ef41Sopenharmony_ciEffectControlLinearizer::AdaptOverloadedFastCallResult
50081cb0ef41Sopenharmony_ciEffectControlLinearizer::AdaptOverloadedFastCallArgument(
50091cb0ef41Sopenharmony_ci    Node* node, const FastApiCallFunctionVector& c_functions,
50101cb0ef41Sopenharmony_ci    const fast_api_call::OverloadsResolutionResult& overloads_resolution_result,
50111cb0ef41Sopenharmony_ci    GraphAssemblerLabel<0>* if_error) {
50121cb0ef41Sopenharmony_ci  static constexpr int kReceiver = 1;
50131cb0ef41Sopenharmony_ci
50141cb0ef41Sopenharmony_ci  auto merge = __ MakeLabel(MachineRepresentation::kTagged,
50151cb0ef41Sopenharmony_ci                            MachineRepresentation::kTagged);
50161cb0ef41Sopenharmony_ci
50171cb0ef41Sopenharmony_ci  for (size_t func_index = 0; func_index < c_functions.size(); func_index++) {
50181cb0ef41Sopenharmony_ci    const CFunctionInfo* c_signature = c_functions[func_index].signature;
50191cb0ef41Sopenharmony_ci    CTypeInfo arg_type = c_signature->ArgumentInfo(
50201cb0ef41Sopenharmony_ci        overloads_resolution_result.distinguishable_arg_index + kReceiver);
50211cb0ef41Sopenharmony_ci
50221cb0ef41Sopenharmony_ci    auto next = __ MakeLabel();
50231cb0ef41Sopenharmony_ci
50241cb0ef41Sopenharmony_ci    // Check that the value is a HeapObject.
50251cb0ef41Sopenharmony_ci    Node* value_is_smi = ObjectIsSmi(node);
50261cb0ef41Sopenharmony_ci    __ GotoIf(value_is_smi, if_error);
50271cb0ef41Sopenharmony_ci
50281cb0ef41Sopenharmony_ci    ExternalReference::Type ref_type = ExternalReference::FAST_C_CALL;
50291cb0ef41Sopenharmony_ci
50301cb0ef41Sopenharmony_ci    switch (arg_type.GetSequenceType()) {
50311cb0ef41Sopenharmony_ci      case CTypeInfo::SequenceType::kIsSequence: {
50321cb0ef41Sopenharmony_ci        CHECK_EQ(arg_type.GetType(), CTypeInfo::Type::kVoid);
50331cb0ef41Sopenharmony_ci
50341cb0ef41Sopenharmony_ci        // Check that the value is a JSArray.
50351cb0ef41Sopenharmony_ci        Node* value_map = __ LoadField(AccessBuilder::ForMap(), node);
50361cb0ef41Sopenharmony_ci        Node* value_instance_type =
50371cb0ef41Sopenharmony_ci            __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
50381cb0ef41Sopenharmony_ci        Node* value_is_js_array = __ Word32Equal(
50391cb0ef41Sopenharmony_ci            value_instance_type, __ Int32Constant(JS_ARRAY_TYPE));
50401cb0ef41Sopenharmony_ci        __ GotoIfNot(value_is_js_array, &next);
50411cb0ef41Sopenharmony_ci
50421cb0ef41Sopenharmony_ci        int kAlign = alignof(uintptr_t);
50431cb0ef41Sopenharmony_ci        int kSize = sizeof(uintptr_t);
50441cb0ef41Sopenharmony_ci        Node* stack_slot = __ StackSlot(kSize, kAlign);
50451cb0ef41Sopenharmony_ci
50461cb0ef41Sopenharmony_ci        __ Store(StoreRepresentation(MachineType::PointerRepresentation(),
50471cb0ef41Sopenharmony_ci                                     kNoWriteBarrier),
50481cb0ef41Sopenharmony_ci                 stack_slot, 0, node);
50491cb0ef41Sopenharmony_ci
50501cb0ef41Sopenharmony_ci        Node* target_address = __ ExternalConstant(ExternalReference::Create(
50511cb0ef41Sopenharmony_ci            c_functions[func_index].address, ref_type));
50521cb0ef41Sopenharmony_ci        __ Goto(&merge, target_address, stack_slot);
50531cb0ef41Sopenharmony_ci        break;
50541cb0ef41Sopenharmony_ci      }
50551cb0ef41Sopenharmony_ci
50561cb0ef41Sopenharmony_ci      case CTypeInfo::SequenceType::kIsTypedArray: {
50571cb0ef41Sopenharmony_ci        // Check that the value is a TypedArray with a type that matches the
50581cb0ef41Sopenharmony_ci        // type declared in the c-function.
50591cb0ef41Sopenharmony_ci        Node* stack_slot = AdaptFastCallTypedArrayArgument(
50601cb0ef41Sopenharmony_ci            node,
50611cb0ef41Sopenharmony_ci            fast_api_call::GetTypedArrayElementsKind(
50621cb0ef41Sopenharmony_ci                overloads_resolution_result.element_type),
50631cb0ef41Sopenharmony_ci            &next);
50641cb0ef41Sopenharmony_ci        Node* target_address = __ ExternalConstant(ExternalReference::Create(
50651cb0ef41Sopenharmony_ci            c_functions[func_index].address, ref_type));
50661cb0ef41Sopenharmony_ci        __ Goto(&merge, target_address, stack_slot);
50671cb0ef41Sopenharmony_ci        break;
50681cb0ef41Sopenharmony_ci      }
50691cb0ef41Sopenharmony_ci
50701cb0ef41Sopenharmony_ci      default: {
50711cb0ef41Sopenharmony_ci        UNREACHABLE();
50721cb0ef41Sopenharmony_ci      }
50731cb0ef41Sopenharmony_ci    }
50741cb0ef41Sopenharmony_ci
50751cb0ef41Sopenharmony_ci    __ Bind(&next);
50761cb0ef41Sopenharmony_ci  }
50771cb0ef41Sopenharmony_ci  __ Goto(if_error);
50781cb0ef41Sopenharmony_ci
50791cb0ef41Sopenharmony_ci  __ Bind(&merge);
50801cb0ef41Sopenharmony_ci  return {merge.PhiAt(0), merge.PhiAt(1)};
50811cb0ef41Sopenharmony_ci}
50821cb0ef41Sopenharmony_ci
50831cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::WrapFastCall(
50841cb0ef41Sopenharmony_ci    const CallDescriptor* call_descriptor, int inputs_size, Node** inputs,
50851cb0ef41Sopenharmony_ci    Node* target, const CFunctionInfo* c_signature, int c_arg_count,
50861cb0ef41Sopenharmony_ci    Node* stack_slot) {
50871cb0ef41Sopenharmony_ci  // CPU profiler support
50881cb0ef41Sopenharmony_ci  Node* target_address = __ ExternalConstant(
50891cb0ef41Sopenharmony_ci      ExternalReference::fast_api_call_target_address(isolate()));
50901cb0ef41Sopenharmony_ci  __ Store(StoreRepresentation(MachineType::PointerRepresentation(),
50911cb0ef41Sopenharmony_ci                               kNoWriteBarrier),
50921cb0ef41Sopenharmony_ci           target_address, 0, target);
50931cb0ef41Sopenharmony_ci
50941cb0ef41Sopenharmony_ci  // Disable JS execution
50951cb0ef41Sopenharmony_ci  Node* javascript_execution_assert = __ ExternalConstant(
50961cb0ef41Sopenharmony_ci      ExternalReference::javascript_execution_assert(isolate()));
50971cb0ef41Sopenharmony_ci  static_assert(sizeof(bool) == 1, "Wrong assumption about boolean size.");
50981cb0ef41Sopenharmony_ci
50991cb0ef41Sopenharmony_ci  if (FLAG_debug_code) {
51001cb0ef41Sopenharmony_ci    auto do_store = __ MakeLabel();
51011cb0ef41Sopenharmony_ci    Node* old_scope_value =
51021cb0ef41Sopenharmony_ci        __ Load(MachineType::Int8(), javascript_execution_assert, 0);
51031cb0ef41Sopenharmony_ci    __ GotoIf(__ Word32Equal(old_scope_value, __ Int32Constant(1)), &do_store);
51041cb0ef41Sopenharmony_ci
51051cb0ef41Sopenharmony_ci    // We expect that JS execution is enabled, otherwise assert.
51061cb0ef41Sopenharmony_ci    __ Unreachable(&do_store);
51071cb0ef41Sopenharmony_ci    __ Bind(&do_store);
51081cb0ef41Sopenharmony_ci  }
51091cb0ef41Sopenharmony_ci  __ Store(StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
51101cb0ef41Sopenharmony_ci           javascript_execution_assert, 0, __ Int32Constant(0));
51111cb0ef41Sopenharmony_ci
51121cb0ef41Sopenharmony_ci  // Update effect and control
51131cb0ef41Sopenharmony_ci  if (c_signature->HasOptions()) {
51141cb0ef41Sopenharmony_ci    inputs[c_arg_count + 1] = stack_slot;
51151cb0ef41Sopenharmony_ci    inputs[c_arg_count + 2] = __ effect();
51161cb0ef41Sopenharmony_ci    inputs[c_arg_count + 3] = __ control();
51171cb0ef41Sopenharmony_ci  } else {
51181cb0ef41Sopenharmony_ci    inputs[c_arg_count + 1] = __ effect();
51191cb0ef41Sopenharmony_ci    inputs[c_arg_count + 2] = __ control();
51201cb0ef41Sopenharmony_ci  }
51211cb0ef41Sopenharmony_ci
51221cb0ef41Sopenharmony_ci  // Create the fast call
51231cb0ef41Sopenharmony_ci  Node* call = __ Call(call_descriptor, inputs_size, inputs);
51241cb0ef41Sopenharmony_ci
51251cb0ef41Sopenharmony_ci  // Reenable JS execution
51261cb0ef41Sopenharmony_ci  __ Store(StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
51271cb0ef41Sopenharmony_ci           javascript_execution_assert, 0, __ Int32Constant(1));
51281cb0ef41Sopenharmony_ci
51291cb0ef41Sopenharmony_ci  // Reset the CPU profiler target address.
51301cb0ef41Sopenharmony_ci  __ Store(StoreRepresentation(MachineType::PointerRepresentation(),
51311cb0ef41Sopenharmony_ci                               kNoWriteBarrier),
51321cb0ef41Sopenharmony_ci           target_address, 0, __ IntPtrConstant(0));
51331cb0ef41Sopenharmony_ci
51341cb0ef41Sopenharmony_ci  return call;
51351cb0ef41Sopenharmony_ci}
51361cb0ef41Sopenharmony_ci
51371cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::GenerateSlowApiCall(Node* node) {
51381cb0ef41Sopenharmony_ci  FastApiCallNode n(node);
51391cb0ef41Sopenharmony_ci  FastApiCallParameters const& params = n.Parameters();
51401cb0ef41Sopenharmony_ci  const CFunctionInfo* c_signature = params.c_functions()[0].signature;
51411cb0ef41Sopenharmony_ci  const int c_arg_count = c_signature->ArgumentCount();
51421cb0ef41Sopenharmony_ci
51431cb0ef41Sopenharmony_ci  Node** const slow_inputs = graph()->zone()->NewArray<Node*>(
51441cb0ef41Sopenharmony_ci      n.SlowCallArgumentCount() + FastApiCallNode::kEffectAndControlInputCount);
51451cb0ef41Sopenharmony_ci
51461cb0ef41Sopenharmony_ci  int fast_call_params = c_arg_count;
51471cb0ef41Sopenharmony_ci  CHECK_EQ(node->op()->ValueInputCount() - fast_call_params,
51481cb0ef41Sopenharmony_ci           n.SlowCallArgumentCount());
51491cb0ef41Sopenharmony_ci  int index = 0;
51501cb0ef41Sopenharmony_ci  for (; index < n.SlowCallArgumentCount(); ++index) {
51511cb0ef41Sopenharmony_ci    slow_inputs[index] = n.SlowCallArgument(index);
51521cb0ef41Sopenharmony_ci  }
51531cb0ef41Sopenharmony_ci
51541cb0ef41Sopenharmony_ci  slow_inputs[index] = __ effect();
51551cb0ef41Sopenharmony_ci  slow_inputs[index + 1] = __ control();
51561cb0ef41Sopenharmony_ci  Node* slow_call_result = __ Call(
51571cb0ef41Sopenharmony_ci      params.descriptor(), index + FastApiCallNode::kEffectAndControlInputCount,
51581cb0ef41Sopenharmony_ci      slow_inputs);
51591cb0ef41Sopenharmony_ci  return slow_call_result;
51601cb0ef41Sopenharmony_ci}
51611cb0ef41Sopenharmony_ci
51621cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerFastApiCall(Node* node) {
51631cb0ef41Sopenharmony_ci  FastApiCallNode n(node);
51641cb0ef41Sopenharmony_ci  FastApiCallParameters const& params = n.Parameters();
51651cb0ef41Sopenharmony_ci
51661cb0ef41Sopenharmony_ci  static constexpr int kReceiver = 1;
51671cb0ef41Sopenharmony_ci
51681cb0ef41Sopenharmony_ci  const FastApiCallFunctionVector& c_functions = params.c_functions();
51691cb0ef41Sopenharmony_ci  const CFunctionInfo* c_signature = params.c_functions()[0].signature;
51701cb0ef41Sopenharmony_ci  const int c_arg_count = c_signature->ArgumentCount();
51711cb0ef41Sopenharmony_ci  CallDescriptor* js_call_descriptor = params.descriptor();
51721cb0ef41Sopenharmony_ci  int js_arg_count = static_cast<int>(js_call_descriptor->ParameterCount());
51731cb0ef41Sopenharmony_ci  const int value_input_count = node->op()->ValueInputCount();
51741cb0ef41Sopenharmony_ci  CHECK_EQ(FastApiCallNode::ArityForArgc(c_arg_count, js_arg_count),
51751cb0ef41Sopenharmony_ci           value_input_count);
51761cb0ef41Sopenharmony_ci
51771cb0ef41Sopenharmony_ci  Node* stack_slot = nullptr;
51781cb0ef41Sopenharmony_ci  int kAlign = alignof(v8::FastApiCallbackOptions);
51791cb0ef41Sopenharmony_ci  int kSize = sizeof(v8::FastApiCallbackOptions);
51801cb0ef41Sopenharmony_ci  // If this check fails, you've probably added new fields to
51811cb0ef41Sopenharmony_ci  // v8::FastApiCallbackOptions, which means you'll need to write code
51821cb0ef41Sopenharmony_ci  // that initializes and reads from them too.
51831cb0ef41Sopenharmony_ci  CHECK_EQ(kSize, sizeof(uintptr_t) * 2);
51841cb0ef41Sopenharmony_ci  stack_slot = __ StackSlot(kSize, kAlign);
51851cb0ef41Sopenharmony_ci  if (c_signature->HasOptions()) {
51861cb0ef41Sopenharmony_ci    __ Store(
51871cb0ef41Sopenharmony_ci        StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier),
51881cb0ef41Sopenharmony_ci        stack_slot,
51891cb0ef41Sopenharmony_ci        static_cast<int>(offsetof(v8::FastApiCallbackOptions, fallback)),
51901cb0ef41Sopenharmony_ci        __ Int32Constant(0));
51911cb0ef41Sopenharmony_ci    __ Store(StoreRepresentation(MachineType::PointerRepresentation(),
51921cb0ef41Sopenharmony_ci                                 kNoWriteBarrier),
51931cb0ef41Sopenharmony_ci             stack_slot,
51941cb0ef41Sopenharmony_ci             static_cast<int>(offsetof(v8::FastApiCallbackOptions, data)),
51951cb0ef41Sopenharmony_ci             n.SlowCallArgument(FastApiCallNode::kSlowCallDataArgumentIndex));
51961cb0ef41Sopenharmony_ci  } else {
51971cb0ef41Sopenharmony_ci    __ Store(
51981cb0ef41Sopenharmony_ci        StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier),
51991cb0ef41Sopenharmony_ci        stack_slot,
52001cb0ef41Sopenharmony_ci        0,  // fallback = false
52011cb0ef41Sopenharmony_ci        __ Int32Constant(0));
52021cb0ef41Sopenharmony_ci    __ Store(StoreRepresentation(MachineType::PointerRepresentation(),
52031cb0ef41Sopenharmony_ci                                 kNoWriteBarrier),
52041cb0ef41Sopenharmony_ci             stack_slot,
52051cb0ef41Sopenharmony_ci             0,  // no data
52061cb0ef41Sopenharmony_ci             n.SlowCallArgument(FastApiCallNode::kSlowCallDataArgumentIndex));
52071cb0ef41Sopenharmony_ci  }
52081cb0ef41Sopenharmony_ci
52091cb0ef41Sopenharmony_ci  MachineSignature::Builder builder(
52101cb0ef41Sopenharmony_ci      graph()->zone(), 1, c_arg_count + (c_signature->HasOptions() ? 1 : 0));
52111cb0ef41Sopenharmony_ci  MachineType return_type =
52121cb0ef41Sopenharmony_ci      MachineType::TypeForCType(c_signature->ReturnInfo());
52131cb0ef41Sopenharmony_ci  builder.AddReturn(return_type);
52141cb0ef41Sopenharmony_ci  for (int i = 0; i < c_arg_count; ++i) {
52151cb0ef41Sopenharmony_ci    CTypeInfo type = c_signature->ArgumentInfo(i);
52161cb0ef41Sopenharmony_ci    MachineType machine_type =
52171cb0ef41Sopenharmony_ci        type.GetSequenceType() == CTypeInfo::SequenceType::kScalar
52181cb0ef41Sopenharmony_ci            ? MachineType::TypeForCType(type)
52191cb0ef41Sopenharmony_ci            : MachineType::AnyTagged();
52201cb0ef41Sopenharmony_ci    builder.AddParam(machine_type);
52211cb0ef41Sopenharmony_ci  }
52221cb0ef41Sopenharmony_ci  if (c_signature->HasOptions()) {
52231cb0ef41Sopenharmony_ci    builder.AddParam(MachineType::Pointer());  // stack_slot
52241cb0ef41Sopenharmony_ci  }
52251cb0ef41Sopenharmony_ci
52261cb0ef41Sopenharmony_ci  CallDescriptor* call_descriptor =
52271cb0ef41Sopenharmony_ci      Linkage::GetSimplifiedCDescriptor(graph()->zone(), builder.Build());
52281cb0ef41Sopenharmony_ci
52291cb0ef41Sopenharmony_ci  // Hint to fast path.
52301cb0ef41Sopenharmony_ci  auto if_success = __ MakeLabel();
52311cb0ef41Sopenharmony_ci  auto if_error = __ MakeDeferredLabel();
52321cb0ef41Sopenharmony_ci
52331cb0ef41Sopenharmony_ci  // Overload resolution
52341cb0ef41Sopenharmony_ci
52351cb0ef41Sopenharmony_ci  bool generate_fast_call = false;
52361cb0ef41Sopenharmony_ci  int distinguishable_arg_index = INT_MIN;
52371cb0ef41Sopenharmony_ci  fast_api_call::OverloadsResolutionResult overloads_resolution_result =
52381cb0ef41Sopenharmony_ci      fast_api_call::OverloadsResolutionResult::Invalid();
52391cb0ef41Sopenharmony_ci
52401cb0ef41Sopenharmony_ci  if (c_functions.size() == 1) {
52411cb0ef41Sopenharmony_ci    generate_fast_call = true;
52421cb0ef41Sopenharmony_ci  } else {
52431cb0ef41Sopenharmony_ci    DCHECK_EQ(c_functions.size(), 2);
52441cb0ef41Sopenharmony_ci    overloads_resolution_result = fast_api_call::ResolveOverloads(
52451cb0ef41Sopenharmony_ci        graph()->zone(), c_functions, c_arg_count);
52461cb0ef41Sopenharmony_ci    if (overloads_resolution_result.is_valid()) {
52471cb0ef41Sopenharmony_ci      generate_fast_call = true;
52481cb0ef41Sopenharmony_ci      distinguishable_arg_index =
52491cb0ef41Sopenharmony_ci          overloads_resolution_result.distinguishable_arg_index;
52501cb0ef41Sopenharmony_ci    }
52511cb0ef41Sopenharmony_ci  }
52521cb0ef41Sopenharmony_ci
52531cb0ef41Sopenharmony_ci  if (!generate_fast_call) {
52541cb0ef41Sopenharmony_ci    // Only generate the slow call.
52551cb0ef41Sopenharmony_ci    return GenerateSlowApiCall(node);
52561cb0ef41Sopenharmony_ci  }
52571cb0ef41Sopenharmony_ci
52581cb0ef41Sopenharmony_ci  // Generate fast call.
52591cb0ef41Sopenharmony_ci
52601cb0ef41Sopenharmony_ci  const int kFastTargetAddressInputIndex = 0;
52611cb0ef41Sopenharmony_ci  const int kFastTargetAddressInputCount = 1;
52621cb0ef41Sopenharmony_ci
52631cb0ef41Sopenharmony_ci  Node** const inputs = graph()->zone()->NewArray<Node*>(
52641cb0ef41Sopenharmony_ci      kFastTargetAddressInputCount + c_arg_count + n.FastCallExtraInputCount());
52651cb0ef41Sopenharmony_ci
52661cb0ef41Sopenharmony_ci  ExternalReference::Type ref_type = ExternalReference::FAST_C_CALL;
52671cb0ef41Sopenharmony_ci
52681cb0ef41Sopenharmony_ci  // The inputs to {Call} node for the fast call look like:
52691cb0ef41Sopenharmony_ci  // [fast callee, receiver, ... C arguments, [optional Options], effect,
52701cb0ef41Sopenharmony_ci  //  control].
52711cb0ef41Sopenharmony_ci  //
52721cb0ef41Sopenharmony_ci  // The first input node represents the target address for the fast call.
52731cb0ef41Sopenharmony_ci  // If the function is not overloaded (c_functions.size() == 1) this is the
52741cb0ef41Sopenharmony_ci  // address associated to the first and only element in the c_functions vector.
52751cb0ef41Sopenharmony_ci  // If there are multiple overloads the value of this input will be set later
52761cb0ef41Sopenharmony_ci  // with a Phi node created by AdaptOverloadedFastCallArgument.
52771cb0ef41Sopenharmony_ci  inputs[kFastTargetAddressInputIndex] =
52781cb0ef41Sopenharmony_ci      (c_functions.size() == 1) ? __ ExternalConstant(ExternalReference::Create(
52791cb0ef41Sopenharmony_ci                                      c_functions[0].address, ref_type))
52801cb0ef41Sopenharmony_ci                                : nullptr;
52811cb0ef41Sopenharmony_ci
52821cb0ef41Sopenharmony_ci  for (int i = 0; i < c_arg_count; ++i) {
52831cb0ef41Sopenharmony_ci    Node* value = NodeProperties::GetValueInput(node, i);
52841cb0ef41Sopenharmony_ci
52851cb0ef41Sopenharmony_ci    if (i == distinguishable_arg_index + kReceiver) {
52861cb0ef41Sopenharmony_ci      // This only happens when the FastApiCall node represents multiple
52871cb0ef41Sopenharmony_ci      // overloaded functions and {i} is the index of the distinguishable
52881cb0ef41Sopenharmony_ci      // argument.
52891cb0ef41Sopenharmony_ci      AdaptOverloadedFastCallResult nodes = AdaptOverloadedFastCallArgument(
52901cb0ef41Sopenharmony_ci          value, c_functions, overloads_resolution_result, &if_error);
52911cb0ef41Sopenharmony_ci      inputs[i + kFastTargetAddressInputCount] = nodes.argument;
52921cb0ef41Sopenharmony_ci
52931cb0ef41Sopenharmony_ci      // Replace the target address node with a Phi node that represents the
52941cb0ef41Sopenharmony_ci      // choice between the target addreseses of overloaded functions.
52951cb0ef41Sopenharmony_ci      inputs[kFastTargetAddressInputIndex] = nodes.target_address;
52961cb0ef41Sopenharmony_ci    } else {
52971cb0ef41Sopenharmony_ci      CTypeInfo type = c_signature->ArgumentInfo(i);
52981cb0ef41Sopenharmony_ci      inputs[i + kFastTargetAddressInputCount] =
52991cb0ef41Sopenharmony_ci          AdaptFastCallArgument(value, type, &if_error);
53001cb0ef41Sopenharmony_ci    }
53011cb0ef41Sopenharmony_ci  }
53021cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(inputs[0]);
53031cb0ef41Sopenharmony_ci
53041cb0ef41Sopenharmony_ci  Node* c_call_result = WrapFastCall(
53051cb0ef41Sopenharmony_ci      call_descriptor, c_arg_count + n.FastCallExtraInputCount() + 1, inputs,
53061cb0ef41Sopenharmony_ci      inputs[0], c_signature, c_arg_count, stack_slot);
53071cb0ef41Sopenharmony_ci
53081cb0ef41Sopenharmony_ci  Node* fast_call_result = nullptr;
53091cb0ef41Sopenharmony_ci  switch (c_signature->ReturnInfo().GetType()) {
53101cb0ef41Sopenharmony_ci    case CTypeInfo::Type::kVoid:
53111cb0ef41Sopenharmony_ci      fast_call_result = __ UndefinedConstant();
53121cb0ef41Sopenharmony_ci      break;
53131cb0ef41Sopenharmony_ci    case CTypeInfo::Type::kBool:
53141cb0ef41Sopenharmony_ci      static_assert(sizeof(bool) == 1, "unsupported bool size");
53151cb0ef41Sopenharmony_ci      fast_call_result = ChangeBitToTagged(
53161cb0ef41Sopenharmony_ci          __ Word32And(c_call_result, __ Int32Constant(0xFF)));
53171cb0ef41Sopenharmony_ci      break;
53181cb0ef41Sopenharmony_ci    case CTypeInfo::Type::kInt32:
53191cb0ef41Sopenharmony_ci      fast_call_result = ChangeInt32ToTagged(c_call_result);
53201cb0ef41Sopenharmony_ci      break;
53211cb0ef41Sopenharmony_ci    case CTypeInfo::Type::kUint32:
53221cb0ef41Sopenharmony_ci      fast_call_result = ChangeUint32ToTagged(c_call_result);
53231cb0ef41Sopenharmony_ci      break;
53241cb0ef41Sopenharmony_ci    case CTypeInfo::Type::kInt64:
53251cb0ef41Sopenharmony_ci    case CTypeInfo::Type::kUint64:
53261cb0ef41Sopenharmony_ci      UNREACHABLE();
53271cb0ef41Sopenharmony_ci    case CTypeInfo::Type::kFloat32:
53281cb0ef41Sopenharmony_ci      fast_call_result =
53291cb0ef41Sopenharmony_ci          ChangeFloat64ToTagged(__ ChangeFloat32ToFloat64(c_call_result),
53301cb0ef41Sopenharmony_ci                                CheckForMinusZeroMode::kCheckForMinusZero);
53311cb0ef41Sopenharmony_ci      break;
53321cb0ef41Sopenharmony_ci    case CTypeInfo::Type::kFloat64:
53331cb0ef41Sopenharmony_ci      fast_call_result = ChangeFloat64ToTagged(
53341cb0ef41Sopenharmony_ci          c_call_result, CheckForMinusZeroMode::kCheckForMinusZero);
53351cb0ef41Sopenharmony_ci      break;
53361cb0ef41Sopenharmony_ci    case CTypeInfo::Type::kV8Value:
53371cb0ef41Sopenharmony_ci    case CTypeInfo::Type::kApiObject:
53381cb0ef41Sopenharmony_ci      UNREACHABLE();
53391cb0ef41Sopenharmony_ci    case CTypeInfo::Type::kAny:
53401cb0ef41Sopenharmony_ci      fast_call_result =
53411cb0ef41Sopenharmony_ci          ChangeFloat64ToTagged(__ ChangeInt64ToFloat64(c_call_result),
53421cb0ef41Sopenharmony_ci                                CheckForMinusZeroMode::kCheckForMinusZero);
53431cb0ef41Sopenharmony_ci      break;
53441cb0ef41Sopenharmony_ci  }
53451cb0ef41Sopenharmony_ci
53461cb0ef41Sopenharmony_ci  auto merge = __ MakeLabel(MachineRepresentation::kTagged);
53471cb0ef41Sopenharmony_ci  if (c_signature->HasOptions()) {
53481cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(stack_slot);
53491cb0ef41Sopenharmony_ci    Node* load = __ Load(
53501cb0ef41Sopenharmony_ci        MachineType::Int32(), stack_slot,
53511cb0ef41Sopenharmony_ci        static_cast<int>(offsetof(v8::FastApiCallbackOptions, fallback)));
53521cb0ef41Sopenharmony_ci
53531cb0ef41Sopenharmony_ci    Node* is_zero = __ Word32Equal(load, __ Int32Constant(0));
53541cb0ef41Sopenharmony_ci    __ Branch(is_zero, &if_success, &if_error);
53551cb0ef41Sopenharmony_ci  } else {
53561cb0ef41Sopenharmony_ci    Node* true_constant = __ TrueConstant();
53571cb0ef41Sopenharmony_ci    __ Branch(true_constant, &if_success, &if_error);
53581cb0ef41Sopenharmony_ci  }
53591cb0ef41Sopenharmony_ci
53601cb0ef41Sopenharmony_ci  __ Bind(&if_success);
53611cb0ef41Sopenharmony_ci  __ Goto(&merge, fast_call_result);
53621cb0ef41Sopenharmony_ci
53631cb0ef41Sopenharmony_ci  // Generate direct slow call.
53641cb0ef41Sopenharmony_ci  __ Bind(&if_error);
53651cb0ef41Sopenharmony_ci  {
53661cb0ef41Sopenharmony_ci    Node* slow_call_result = GenerateSlowApiCall(node);
53671cb0ef41Sopenharmony_ci    __ Goto(&merge, slow_call_result);
53681cb0ef41Sopenharmony_ci  }
53691cb0ef41Sopenharmony_ci
53701cb0ef41Sopenharmony_ci  __ Bind(&merge);
53711cb0ef41Sopenharmony_ci  return merge.PhiAt(0);
53721cb0ef41Sopenharmony_ci}
53731cb0ef41Sopenharmony_ci
53741cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
53751cb0ef41Sopenharmony_ci  Node* object = node->InputAt(0);
53761cb0ef41Sopenharmony_ci  Node* index = node->InputAt(1);
53771cb0ef41Sopenharmony_ci  Node* zero = __ IntPtrConstant(0);
53781cb0ef41Sopenharmony_ci  Node* one = __ IntPtrConstant(1);
53791cb0ef41Sopenharmony_ci
53801cb0ef41Sopenharmony_ci  // Sign-extend the {index} on 64-bit architectures.
53811cb0ef41Sopenharmony_ci  if (machine()->Is64()) {
53821cb0ef41Sopenharmony_ci    index = __ ChangeInt32ToInt64(index);
53831cb0ef41Sopenharmony_ci  }
53841cb0ef41Sopenharmony_ci
53851cb0ef41Sopenharmony_ci  auto if_double = __ MakeDeferredLabel();
53861cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kTagged);
53871cb0ef41Sopenharmony_ci  auto loaded_field = __ MakeLabel(MachineRepresentation::kTagged);
53881cb0ef41Sopenharmony_ci  auto done_double = __ MakeLabel(MachineRepresentation::kFloat64);
53891cb0ef41Sopenharmony_ci
53901cb0ef41Sopenharmony_ci  // Check if field is a mutable double field.
53911cb0ef41Sopenharmony_ci  __ GotoIfNot(__ IntPtrEqual(__ WordAnd(index, one), zero), &if_double);
53921cb0ef41Sopenharmony_ci
53931cb0ef41Sopenharmony_ci  // The field is a proper Tagged field on {object}. The {index} is shifted
53941cb0ef41Sopenharmony_ci  // to the left by one in the code below.
53951cb0ef41Sopenharmony_ci  {
53961cb0ef41Sopenharmony_ci    // Check if field is in-object or out-of-object.
53971cb0ef41Sopenharmony_ci    auto if_outofobject = __ MakeLabel();
53981cb0ef41Sopenharmony_ci    __ GotoIf(__ IntLessThan(index, zero), &if_outofobject);
53991cb0ef41Sopenharmony_ci
54001cb0ef41Sopenharmony_ci    // The field is located in the {object} itself.
54011cb0ef41Sopenharmony_ci    {
54021cb0ef41Sopenharmony_ci      Node* offset =
54031cb0ef41Sopenharmony_ci          __ IntAdd(__ WordShl(index, __ IntPtrConstant(kTaggedSizeLog2 - 1)),
54041cb0ef41Sopenharmony_ci                    __ IntPtrConstant(JSObject::kHeaderSize - kHeapObjectTag));
54051cb0ef41Sopenharmony_ci      Node* field = __ Load(MachineType::AnyTagged(), object, offset);
54061cb0ef41Sopenharmony_ci      __ Goto(&loaded_field, field);
54071cb0ef41Sopenharmony_ci    }
54081cb0ef41Sopenharmony_ci
54091cb0ef41Sopenharmony_ci    // The field is located in the properties backing store of {object}.
54101cb0ef41Sopenharmony_ci    // The {index} is equal to the negated out of property index plus 1.
54111cb0ef41Sopenharmony_ci    __ Bind(&if_outofobject);
54121cb0ef41Sopenharmony_ci    {
54131cb0ef41Sopenharmony_ci      Node* properties = __ LoadField(
54141cb0ef41Sopenharmony_ci          AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(), object);
54151cb0ef41Sopenharmony_ci      Node* offset =
54161cb0ef41Sopenharmony_ci          __ IntAdd(__ WordShl(__ IntSub(zero, index),
54171cb0ef41Sopenharmony_ci                               __ IntPtrConstant(kTaggedSizeLog2 - 1)),
54181cb0ef41Sopenharmony_ci                    __ IntPtrConstant((FixedArray::kHeaderSize - kTaggedSize) -
54191cb0ef41Sopenharmony_ci                                      kHeapObjectTag));
54201cb0ef41Sopenharmony_ci      Node* field = __ Load(MachineType::AnyTagged(), properties, offset);
54211cb0ef41Sopenharmony_ci      __ Goto(&loaded_field, field);
54221cb0ef41Sopenharmony_ci    }
54231cb0ef41Sopenharmony_ci  }
54241cb0ef41Sopenharmony_ci
54251cb0ef41Sopenharmony_ci  // The field is a Double field, either unboxed in the object on 64-bit
54261cb0ef41Sopenharmony_ci  // architectures, or a mutable HeapNumber.
54271cb0ef41Sopenharmony_ci  __ Bind(&if_double);
54281cb0ef41Sopenharmony_ci  {
54291cb0ef41Sopenharmony_ci    index = __ WordSar(index, one);
54301cb0ef41Sopenharmony_ci
54311cb0ef41Sopenharmony_ci    // Check if field is in-object or out-of-object.
54321cb0ef41Sopenharmony_ci    auto if_outofobject = __ MakeLabel();
54331cb0ef41Sopenharmony_ci    __ GotoIf(__ IntLessThan(index, zero), &if_outofobject);
54341cb0ef41Sopenharmony_ci
54351cb0ef41Sopenharmony_ci    // The field is located in the {object} itself.
54361cb0ef41Sopenharmony_ci    {
54371cb0ef41Sopenharmony_ci      Node* offset =
54381cb0ef41Sopenharmony_ci          __ IntAdd(__ WordShl(index, __ IntPtrConstant(kTaggedSizeLog2)),
54391cb0ef41Sopenharmony_ci                    __ IntPtrConstant(JSObject::kHeaderSize - kHeapObjectTag));
54401cb0ef41Sopenharmony_ci      Node* field = __ Load(MachineType::AnyTagged(), object, offset);
54411cb0ef41Sopenharmony_ci      __ Goto(&loaded_field, field);
54421cb0ef41Sopenharmony_ci    }
54431cb0ef41Sopenharmony_ci
54441cb0ef41Sopenharmony_ci    __ Bind(&if_outofobject);
54451cb0ef41Sopenharmony_ci    {
54461cb0ef41Sopenharmony_ci      Node* properties = __ LoadField(
54471cb0ef41Sopenharmony_ci          AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(), object);
54481cb0ef41Sopenharmony_ci      Node* offset =
54491cb0ef41Sopenharmony_ci          __ IntAdd(__ WordShl(__ IntSub(zero, index),
54501cb0ef41Sopenharmony_ci                               __ IntPtrConstant(kTaggedSizeLog2)),
54511cb0ef41Sopenharmony_ci                    __ IntPtrConstant((FixedArray::kHeaderSize - kTaggedSize) -
54521cb0ef41Sopenharmony_ci                                      kHeapObjectTag));
54531cb0ef41Sopenharmony_ci      Node* field = __ Load(MachineType::AnyTagged(), properties, offset);
54541cb0ef41Sopenharmony_ci      __ Goto(&loaded_field, field);
54551cb0ef41Sopenharmony_ci    }
54561cb0ef41Sopenharmony_ci  }
54571cb0ef41Sopenharmony_ci
54581cb0ef41Sopenharmony_ci  __ Bind(&loaded_field);
54591cb0ef41Sopenharmony_ci  {
54601cb0ef41Sopenharmony_ci    Node* field = loaded_field.PhiAt(0);
54611cb0ef41Sopenharmony_ci    // We may have transitioned in-place away from double, so check that
54621cb0ef41Sopenharmony_ci    // this is a HeapNumber -- otherwise the load is fine and we don't need
54631cb0ef41Sopenharmony_ci    // to copy anything anyway.
54641cb0ef41Sopenharmony_ci    __ GotoIf(ObjectIsSmi(field), &done, field);
54651cb0ef41Sopenharmony_ci    Node* field_map = __ LoadField(AccessBuilder::ForMap(), field);
54661cb0ef41Sopenharmony_ci    __ GotoIfNot(__ TaggedEqual(field_map, __ HeapNumberMapConstant()), &done,
54671cb0ef41Sopenharmony_ci                 field);
54681cb0ef41Sopenharmony_ci
54691cb0ef41Sopenharmony_ci    Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), field);
54701cb0ef41Sopenharmony_ci    __ Goto(&done_double, value);
54711cb0ef41Sopenharmony_ci  }
54721cb0ef41Sopenharmony_ci
54731cb0ef41Sopenharmony_ci  __ Bind(&done_double);
54741cb0ef41Sopenharmony_ci  {
54751cb0ef41Sopenharmony_ci    Node* result = AllocateHeapNumberWithValue(done_double.PhiAt(0));
54761cb0ef41Sopenharmony_ci    __ Goto(&done, result);
54771cb0ef41Sopenharmony_ci  }
54781cb0ef41Sopenharmony_ci
54791cb0ef41Sopenharmony_ci  __ Bind(&done);
54801cb0ef41Sopenharmony_ci  return done.PhiAt(0);
54811cb0ef41Sopenharmony_ci}
54821cb0ef41Sopenharmony_ci
54831cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildReverseBytes(ExternalArrayType type,
54841cb0ef41Sopenharmony_ci                                                 Node* value) {
54851cb0ef41Sopenharmony_ci  switch (type) {
54861cb0ef41Sopenharmony_ci    case kExternalInt8Array:
54871cb0ef41Sopenharmony_ci    case kExternalUint8Array:
54881cb0ef41Sopenharmony_ci    case kExternalUint8ClampedArray:
54891cb0ef41Sopenharmony_ci      return value;
54901cb0ef41Sopenharmony_ci
54911cb0ef41Sopenharmony_ci    case kExternalInt16Array: {
54921cb0ef41Sopenharmony_ci      Node* result = __ Word32ReverseBytes(value);
54931cb0ef41Sopenharmony_ci      result = __ Word32Sar(result, __ Int32Constant(16));
54941cb0ef41Sopenharmony_ci      return result;
54951cb0ef41Sopenharmony_ci    }
54961cb0ef41Sopenharmony_ci
54971cb0ef41Sopenharmony_ci    case kExternalUint16Array: {
54981cb0ef41Sopenharmony_ci      Node* result = __ Word32ReverseBytes(value);
54991cb0ef41Sopenharmony_ci      result = __ Word32Shr(result, __ Int32Constant(16));
55001cb0ef41Sopenharmony_ci      return result;
55011cb0ef41Sopenharmony_ci    }
55021cb0ef41Sopenharmony_ci
55031cb0ef41Sopenharmony_ci    case kExternalInt32Array:  // Fall through.
55041cb0ef41Sopenharmony_ci    case kExternalUint32Array:
55051cb0ef41Sopenharmony_ci      return __ Word32ReverseBytes(value);
55061cb0ef41Sopenharmony_ci
55071cb0ef41Sopenharmony_ci    case kExternalFloat32Array: {
55081cb0ef41Sopenharmony_ci      Node* result = __ BitcastFloat32ToInt32(value);
55091cb0ef41Sopenharmony_ci      result = __ Word32ReverseBytes(result);
55101cb0ef41Sopenharmony_ci      result = __ BitcastInt32ToFloat32(result);
55111cb0ef41Sopenharmony_ci      return result;
55121cb0ef41Sopenharmony_ci    }
55131cb0ef41Sopenharmony_ci
55141cb0ef41Sopenharmony_ci    case kExternalFloat64Array: {
55151cb0ef41Sopenharmony_ci      if (machine()->Is64()) {
55161cb0ef41Sopenharmony_ci        Node* result = __ BitcastFloat64ToInt64(value);
55171cb0ef41Sopenharmony_ci        result = __ Word64ReverseBytes(result);
55181cb0ef41Sopenharmony_ci        result = __ BitcastInt64ToFloat64(result);
55191cb0ef41Sopenharmony_ci        return result;
55201cb0ef41Sopenharmony_ci      } else {
55211cb0ef41Sopenharmony_ci        Node* lo = __ Word32ReverseBytes(__ Float64ExtractLowWord32(value));
55221cb0ef41Sopenharmony_ci        Node* hi = __ Word32ReverseBytes(__ Float64ExtractHighWord32(value));
55231cb0ef41Sopenharmony_ci        Node* result = __ Float64Constant(0.0);
55241cb0ef41Sopenharmony_ci        result = __ Float64InsertLowWord32(result, hi);
55251cb0ef41Sopenharmony_ci        result = __ Float64InsertHighWord32(result, lo);
55261cb0ef41Sopenharmony_ci        return result;
55271cb0ef41Sopenharmony_ci      }
55281cb0ef41Sopenharmony_ci    }
55291cb0ef41Sopenharmony_ci
55301cb0ef41Sopenharmony_ci    case kExternalBigInt64Array:
55311cb0ef41Sopenharmony_ci    case kExternalBigUint64Array:
55321cb0ef41Sopenharmony_ci      UNREACHABLE();
55331cb0ef41Sopenharmony_ci  }
55341cb0ef41Sopenharmony_ci}
55351cb0ef41Sopenharmony_ci
55361cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerLoadDataViewElement(Node* node) {
55371cb0ef41Sopenharmony_ci  ExternalArrayType element_type = ExternalArrayTypeOf(node->op());
55381cb0ef41Sopenharmony_ci  Node* object = node->InputAt(0);
55391cb0ef41Sopenharmony_ci  Node* storage = node->InputAt(1);
55401cb0ef41Sopenharmony_ci  Node* index = node->InputAt(2);
55411cb0ef41Sopenharmony_ci  Node* is_little_endian = node->InputAt(3);
55421cb0ef41Sopenharmony_ci
55431cb0ef41Sopenharmony_ci  // We need to keep the {object} (either the JSArrayBuffer or the JSDataView)
55441cb0ef41Sopenharmony_ci  // alive so that the GC will not release the JSArrayBuffer (if there's any)
55451cb0ef41Sopenharmony_ci  // as long as we are still operating on it.
55461cb0ef41Sopenharmony_ci  __ Retain(object);
55471cb0ef41Sopenharmony_ci
55481cb0ef41Sopenharmony_ci  MachineType const machine_type =
55491cb0ef41Sopenharmony_ci      AccessBuilder::ForTypedArrayElement(element_type, true).machine_type;
55501cb0ef41Sopenharmony_ci
55511cb0ef41Sopenharmony_ci  Node* value = __ LoadUnaligned(machine_type, storage, index);
55521cb0ef41Sopenharmony_ci  auto big_endian = __ MakeLabel();
55531cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(machine_type.representation());
55541cb0ef41Sopenharmony_ci
55551cb0ef41Sopenharmony_ci  __ GotoIfNot(is_little_endian, &big_endian);
55561cb0ef41Sopenharmony_ci  {  // Little-endian load.
55571cb0ef41Sopenharmony_ci#if V8_TARGET_LITTLE_ENDIAN
55581cb0ef41Sopenharmony_ci    __ Goto(&done, value);
55591cb0ef41Sopenharmony_ci#else
55601cb0ef41Sopenharmony_ci    __ Goto(&done, BuildReverseBytes(element_type, value));
55611cb0ef41Sopenharmony_ci#endif  // V8_TARGET_LITTLE_ENDIAN
55621cb0ef41Sopenharmony_ci  }
55631cb0ef41Sopenharmony_ci
55641cb0ef41Sopenharmony_ci  __ Bind(&big_endian);
55651cb0ef41Sopenharmony_ci  {  // Big-endian load.
55661cb0ef41Sopenharmony_ci#if V8_TARGET_LITTLE_ENDIAN
55671cb0ef41Sopenharmony_ci    __ Goto(&done, BuildReverseBytes(element_type, value));
55681cb0ef41Sopenharmony_ci#else
55691cb0ef41Sopenharmony_ci    __ Goto(&done, value);
55701cb0ef41Sopenharmony_ci#endif  // V8_TARGET_LITTLE_ENDIAN
55711cb0ef41Sopenharmony_ci  }
55721cb0ef41Sopenharmony_ci
55731cb0ef41Sopenharmony_ci  // We're done, return {result}.
55741cb0ef41Sopenharmony_ci  __ Bind(&done);
55751cb0ef41Sopenharmony_ci  return done.PhiAt(0);
55761cb0ef41Sopenharmony_ci}
55771cb0ef41Sopenharmony_ci
55781cb0ef41Sopenharmony_civoid EffectControlLinearizer::LowerStoreDataViewElement(Node* node) {
55791cb0ef41Sopenharmony_ci  ExternalArrayType element_type = ExternalArrayTypeOf(node->op());
55801cb0ef41Sopenharmony_ci  Node* object = node->InputAt(0);
55811cb0ef41Sopenharmony_ci  Node* storage = node->InputAt(1);
55821cb0ef41Sopenharmony_ci  Node* index = node->InputAt(2);
55831cb0ef41Sopenharmony_ci  Node* value = node->InputAt(3);
55841cb0ef41Sopenharmony_ci  Node* is_little_endian = node->InputAt(4);
55851cb0ef41Sopenharmony_ci
55861cb0ef41Sopenharmony_ci  // We need to keep the {object} (either the JSArrayBuffer or the JSDataView)
55871cb0ef41Sopenharmony_ci  // alive so that the GC will not release the JSArrayBuffer (if there's any)
55881cb0ef41Sopenharmony_ci  // as long as we are still operating on it.
55891cb0ef41Sopenharmony_ci  __ Retain(object);
55901cb0ef41Sopenharmony_ci
55911cb0ef41Sopenharmony_ci  MachineType const machine_type =
55921cb0ef41Sopenharmony_ci      AccessBuilder::ForTypedArrayElement(element_type, true).machine_type;
55931cb0ef41Sopenharmony_ci
55941cb0ef41Sopenharmony_ci  auto big_endian = __ MakeLabel();
55951cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(machine_type.representation());
55961cb0ef41Sopenharmony_ci
55971cb0ef41Sopenharmony_ci  __ GotoIfNot(is_little_endian, &big_endian);
55981cb0ef41Sopenharmony_ci  {  // Little-endian store.
55991cb0ef41Sopenharmony_ci#if V8_TARGET_LITTLE_ENDIAN
56001cb0ef41Sopenharmony_ci    __ Goto(&done, value);
56011cb0ef41Sopenharmony_ci#else
56021cb0ef41Sopenharmony_ci    __ Goto(&done, BuildReverseBytes(element_type, value));
56031cb0ef41Sopenharmony_ci#endif  // V8_TARGET_LITTLE_ENDIAN
56041cb0ef41Sopenharmony_ci  }
56051cb0ef41Sopenharmony_ci
56061cb0ef41Sopenharmony_ci  __ Bind(&big_endian);
56071cb0ef41Sopenharmony_ci  {  // Big-endian store.
56081cb0ef41Sopenharmony_ci#if V8_TARGET_LITTLE_ENDIAN
56091cb0ef41Sopenharmony_ci    __ Goto(&done, BuildReverseBytes(element_type, value));
56101cb0ef41Sopenharmony_ci#else
56111cb0ef41Sopenharmony_ci    __ Goto(&done, value);
56121cb0ef41Sopenharmony_ci#endif  // V8_TARGET_LITTLE_ENDIAN
56131cb0ef41Sopenharmony_ci  }
56141cb0ef41Sopenharmony_ci
56151cb0ef41Sopenharmony_ci  __ Bind(&done);
56161cb0ef41Sopenharmony_ci  __ StoreUnaligned(machine_type.representation(), storage, index,
56171cb0ef41Sopenharmony_ci                    done.PhiAt(0));
56181cb0ef41Sopenharmony_ci}
56191cb0ef41Sopenharmony_ci
56201cb0ef41Sopenharmony_ci// Compute the data pointer, handling the case where the {external} pointer
56211cb0ef41Sopenharmony_ci// is the effective data pointer (i.e. the {base} is Smi zero).
56221cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildTypedArrayDataPointer(Node* base,
56231cb0ef41Sopenharmony_ci                                                          Node* external) {
56241cb0ef41Sopenharmony_ci  if (IntPtrMatcher(base).Is(0)) {
56251cb0ef41Sopenharmony_ci    return external;
56261cb0ef41Sopenharmony_ci  } else {
56271cb0ef41Sopenharmony_ci    if (COMPRESS_POINTERS_BOOL) {
56281cb0ef41Sopenharmony_ci      base = __ BitcastTaggedToWord(base);
56291cb0ef41Sopenharmony_ci      // Zero-extend Tagged_t to UintPtr according to current compression
56301cb0ef41Sopenharmony_ci      // scheme so that the addition with |external_pointer| (which already
56311cb0ef41Sopenharmony_ci      // contains compensated offset value) will decompress the tagged value.
56321cb0ef41Sopenharmony_ci      // See JSTypedArray::ExternalPointerCompensationForOnHeapArray() for
56331cb0ef41Sopenharmony_ci      // details.
56341cb0ef41Sopenharmony_ci      base = ChangeUint32ToUintPtr(base);
56351cb0ef41Sopenharmony_ci    }
56361cb0ef41Sopenharmony_ci    return __ UnsafePointerAdd(base, external);
56371cb0ef41Sopenharmony_ci  }
56381cb0ef41Sopenharmony_ci}
56391cb0ef41Sopenharmony_ci
56401cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerLoadTypedElement(Node* node) {
56411cb0ef41Sopenharmony_ci  ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
56421cb0ef41Sopenharmony_ci  Node* buffer = node->InputAt(0);
56431cb0ef41Sopenharmony_ci  Node* base = node->InputAt(1);
56441cb0ef41Sopenharmony_ci  Node* external = node->InputAt(2);
56451cb0ef41Sopenharmony_ci  Node* index = node->InputAt(3);
56461cb0ef41Sopenharmony_ci
56471cb0ef41Sopenharmony_ci  // We need to keep the {buffer} alive so that the GC will not release the
56481cb0ef41Sopenharmony_ci  // ArrayBuffer (if there's any) as long as we are still operating on it.
56491cb0ef41Sopenharmony_ci  __ Retain(buffer);
56501cb0ef41Sopenharmony_ci
56511cb0ef41Sopenharmony_ci  Node* data_ptr = BuildTypedArrayDataPointer(base, external);
56521cb0ef41Sopenharmony_ci
56531cb0ef41Sopenharmony_ci  // Perform the actual typed element access.
56541cb0ef41Sopenharmony_ci  return __ LoadElement(AccessBuilder::ForTypedArrayElement(array_type, true),
56551cb0ef41Sopenharmony_ci                        data_ptr, index);
56561cb0ef41Sopenharmony_ci}
56571cb0ef41Sopenharmony_ci
56581cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerLoadStackArgument(Node* node) {
56591cb0ef41Sopenharmony_ci  Node* base = node->InputAt(0);
56601cb0ef41Sopenharmony_ci  Node* index = node->InputAt(1);
56611cb0ef41Sopenharmony_ci
56621cb0ef41Sopenharmony_ci  Node* argument =
56631cb0ef41Sopenharmony_ci      __ LoadElement(AccessBuilder::ForStackArgument(), base, index);
56641cb0ef41Sopenharmony_ci
56651cb0ef41Sopenharmony_ci  return __ BitcastWordToTagged(argument);
56661cb0ef41Sopenharmony_ci}
56671cb0ef41Sopenharmony_ci
56681cb0ef41Sopenharmony_civoid EffectControlLinearizer::LowerStoreTypedElement(Node* node) {
56691cb0ef41Sopenharmony_ci  ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
56701cb0ef41Sopenharmony_ci  Node* buffer = node->InputAt(0);
56711cb0ef41Sopenharmony_ci  Node* base = node->InputAt(1);
56721cb0ef41Sopenharmony_ci  Node* external = node->InputAt(2);
56731cb0ef41Sopenharmony_ci  Node* index = node->InputAt(3);
56741cb0ef41Sopenharmony_ci  Node* value = node->InputAt(4);
56751cb0ef41Sopenharmony_ci
56761cb0ef41Sopenharmony_ci  // We need to keep the {buffer} alive so that the GC will not release the
56771cb0ef41Sopenharmony_ci  // ArrayBuffer (if there's any) as long as we are still operating on it.
56781cb0ef41Sopenharmony_ci  __ Retain(buffer);
56791cb0ef41Sopenharmony_ci
56801cb0ef41Sopenharmony_ci  Node* data_ptr = BuildTypedArrayDataPointer(base, external);
56811cb0ef41Sopenharmony_ci
56821cb0ef41Sopenharmony_ci  // Perform the actual typed element access.
56831cb0ef41Sopenharmony_ci  __ StoreElement(AccessBuilder::ForTypedArrayElement(array_type, true),
56841cb0ef41Sopenharmony_ci                  data_ptr, index, value);
56851cb0ef41Sopenharmony_ci}
56861cb0ef41Sopenharmony_ci
56871cb0ef41Sopenharmony_civoid EffectControlLinearizer::TransitionElementsTo(Node* node, Node* array,
56881cb0ef41Sopenharmony_ci                                                   ElementsKind from,
56891cb0ef41Sopenharmony_ci                                                   ElementsKind to) {
56901cb0ef41Sopenharmony_ci  DCHECK(IsMoreGeneralElementsKindTransition(from, to));
56911cb0ef41Sopenharmony_ci  DCHECK(to == HOLEY_ELEMENTS || to == HOLEY_DOUBLE_ELEMENTS);
56921cb0ef41Sopenharmony_ci
56931cb0ef41Sopenharmony_ci  Handle<Map> target(to == HOLEY_ELEMENTS ? FastMapParameterOf(node->op())
56941cb0ef41Sopenharmony_ci                                          : DoubleMapParameterOf(node->op()));
56951cb0ef41Sopenharmony_ci  Node* target_map = __ HeapConstant(target);
56961cb0ef41Sopenharmony_ci
56971cb0ef41Sopenharmony_ci  if (IsSimpleMapChangeTransition(from, to)) {
56981cb0ef41Sopenharmony_ci    __ StoreField(AccessBuilder::ForMap(), array, target_map);
56991cb0ef41Sopenharmony_ci  } else {
57001cb0ef41Sopenharmony_ci    // Instance migration, call out to the runtime for {array}.
57011cb0ef41Sopenharmony_ci    Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
57021cb0ef41Sopenharmony_ci    Runtime::FunctionId id = Runtime::kTransitionElementsKind;
57031cb0ef41Sopenharmony_ci    auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
57041cb0ef41Sopenharmony_ci        graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
57051cb0ef41Sopenharmony_ci    __ Call(call_descriptor, __ CEntryStubConstant(1), array, target_map,
57061cb0ef41Sopenharmony_ci            __ ExternalConstant(ExternalReference::Create(id)),
57071cb0ef41Sopenharmony_ci            __ Int32Constant(2), __ NoContextConstant());
57081cb0ef41Sopenharmony_ci  }
57091cb0ef41Sopenharmony_ci}
57101cb0ef41Sopenharmony_ci
57111cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::IsElementsKindGreaterThan(
57121cb0ef41Sopenharmony_ci    Node* kind, ElementsKind reference_kind) {
57131cb0ef41Sopenharmony_ci  Node* ref_kind = __ Int32Constant(reference_kind);
57141cb0ef41Sopenharmony_ci  Node* ret = __ Int32LessThan(ref_kind, kind);
57151cb0ef41Sopenharmony_ci  return ret;
57161cb0ef41Sopenharmony_ci}
57171cb0ef41Sopenharmony_ci
57181cb0ef41Sopenharmony_civoid EffectControlLinearizer::LowerTransitionAndStoreElement(Node* node) {
57191cb0ef41Sopenharmony_ci  Node* array = node->InputAt(0);
57201cb0ef41Sopenharmony_ci  Node* index = node->InputAt(1);
57211cb0ef41Sopenharmony_ci  Node* value = node->InputAt(2);
57221cb0ef41Sopenharmony_ci
57231cb0ef41Sopenharmony_ci  // Possibly transition array based on input and store.
57241cb0ef41Sopenharmony_ci  //
57251cb0ef41Sopenharmony_ci  //   -- TRANSITION PHASE -----------------
57261cb0ef41Sopenharmony_ci  //   kind = ElementsKind(array)
57271cb0ef41Sopenharmony_ci  //   if value is not smi {
57281cb0ef41Sopenharmony_ci  //     if kind == HOLEY_SMI_ELEMENTS {
57291cb0ef41Sopenharmony_ci  //       if value is heap number {
57301cb0ef41Sopenharmony_ci  //         Transition array to HOLEY_DOUBLE_ELEMENTS
57311cb0ef41Sopenharmony_ci  //         kind = HOLEY_DOUBLE_ELEMENTS
57321cb0ef41Sopenharmony_ci  //       } else {
57331cb0ef41Sopenharmony_ci  //         Transition array to HOLEY_ELEMENTS
57341cb0ef41Sopenharmony_ci  //         kind = HOLEY_ELEMENTS
57351cb0ef41Sopenharmony_ci  //       }
57361cb0ef41Sopenharmony_ci  //     } else if kind == HOLEY_DOUBLE_ELEMENTS {
57371cb0ef41Sopenharmony_ci  //       if value is not heap number {
57381cb0ef41Sopenharmony_ci  //         Transition array to HOLEY_ELEMENTS
57391cb0ef41Sopenharmony_ci  //         kind = HOLEY_ELEMENTS
57401cb0ef41Sopenharmony_ci  //       }
57411cb0ef41Sopenharmony_ci  //     }
57421cb0ef41Sopenharmony_ci  //   }
57431cb0ef41Sopenharmony_ci  //
57441cb0ef41Sopenharmony_ci  //   -- STORE PHASE ----------------------
57451cb0ef41Sopenharmony_ci  //   [make sure {kind} is up-to-date]
57461cb0ef41Sopenharmony_ci  //   if kind == HOLEY_DOUBLE_ELEMENTS {
57471cb0ef41Sopenharmony_ci  //     if value is smi {
57481cb0ef41Sopenharmony_ci  //       float_value = convert smi to float
57491cb0ef41Sopenharmony_ci  //       Store array[index] = float_value
57501cb0ef41Sopenharmony_ci  //     } else {
57511cb0ef41Sopenharmony_ci  //       float_value = value
57521cb0ef41Sopenharmony_ci  //       Store array[index] = float_value
57531cb0ef41Sopenharmony_ci  //     }
57541cb0ef41Sopenharmony_ci  //   } else {
57551cb0ef41Sopenharmony_ci  //     // kind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS
57561cb0ef41Sopenharmony_ci  //     Store array[index] = value
57571cb0ef41Sopenharmony_ci  //   }
57581cb0ef41Sopenharmony_ci  //
57591cb0ef41Sopenharmony_ci  Node* map = __ LoadField(AccessBuilder::ForMap(), array);
57601cb0ef41Sopenharmony_ci  Node* kind;
57611cb0ef41Sopenharmony_ci  {
57621cb0ef41Sopenharmony_ci    Node* bit_field2 = __ LoadField(AccessBuilder::ForMapBitField2(), map);
57631cb0ef41Sopenharmony_ci    Node* mask = __ Int32Constant(Map::Bits2::ElementsKindBits::kMask);
57641cb0ef41Sopenharmony_ci    Node* andit = __ Word32And(bit_field2, mask);
57651cb0ef41Sopenharmony_ci    Node* shift = __ Int32Constant(Map::Bits2::ElementsKindBits::kShift);
57661cb0ef41Sopenharmony_ci    kind = __ Word32Shr(andit, shift);
57671cb0ef41Sopenharmony_ci  }
57681cb0ef41Sopenharmony_ci
57691cb0ef41Sopenharmony_ci  auto do_store = __ MakeLabel(MachineRepresentation::kWord32);
57701cb0ef41Sopenharmony_ci  // We can store a smi anywhere.
57711cb0ef41Sopenharmony_ci  __ GotoIf(ObjectIsSmi(value), &do_store, kind);
57721cb0ef41Sopenharmony_ci
57731cb0ef41Sopenharmony_ci  // {value} is a HeapObject.
57741cb0ef41Sopenharmony_ci  auto transition_smi_array = __ MakeDeferredLabel();
57751cb0ef41Sopenharmony_ci  auto transition_double_to_fast = __ MakeDeferredLabel();
57761cb0ef41Sopenharmony_ci  {
57771cb0ef41Sopenharmony_ci    __ GotoIfNot(IsElementsKindGreaterThan(kind, HOLEY_SMI_ELEMENTS),
57781cb0ef41Sopenharmony_ci                 &transition_smi_array);
57791cb0ef41Sopenharmony_ci    __ GotoIfNot(IsElementsKindGreaterThan(kind, HOLEY_ELEMENTS), &do_store,
57801cb0ef41Sopenharmony_ci                 kind);
57811cb0ef41Sopenharmony_ci
57821cb0ef41Sopenharmony_ci    // We have double elements kind. Only a HeapNumber can be stored
57831cb0ef41Sopenharmony_ci    // without effecting a transition.
57841cb0ef41Sopenharmony_ci    Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
57851cb0ef41Sopenharmony_ci    Node* heap_number_map = __ HeapNumberMapConstant();
57861cb0ef41Sopenharmony_ci    Node* check = __ TaggedEqual(value_map, heap_number_map);
57871cb0ef41Sopenharmony_ci    __ GotoIfNot(check, &transition_double_to_fast);
57881cb0ef41Sopenharmony_ci    __ Goto(&do_store, kind);
57891cb0ef41Sopenharmony_ci  }
57901cb0ef41Sopenharmony_ci
57911cb0ef41Sopenharmony_ci  __ Bind(&transition_smi_array);  // deferred code.
57921cb0ef41Sopenharmony_ci  {
57931cb0ef41Sopenharmony_ci    // Transition {array} from HOLEY_SMI_ELEMENTS to HOLEY_DOUBLE_ELEMENTS or
57941cb0ef41Sopenharmony_ci    // to HOLEY_ELEMENTS.
57951cb0ef41Sopenharmony_ci    auto if_value_not_heap_number = __ MakeLabel();
57961cb0ef41Sopenharmony_ci    Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
57971cb0ef41Sopenharmony_ci    Node* heap_number_map = __ HeapNumberMapConstant();
57981cb0ef41Sopenharmony_ci    Node* check = __ TaggedEqual(value_map, heap_number_map);
57991cb0ef41Sopenharmony_ci    __ GotoIfNot(check, &if_value_not_heap_number);
58001cb0ef41Sopenharmony_ci    {
58011cb0ef41Sopenharmony_ci      // {value} is a HeapNumber.
58021cb0ef41Sopenharmony_ci      TransitionElementsTo(node, array, HOLEY_SMI_ELEMENTS,
58031cb0ef41Sopenharmony_ci                           HOLEY_DOUBLE_ELEMENTS);
58041cb0ef41Sopenharmony_ci      __ Goto(&do_store, __ Int32Constant(HOLEY_DOUBLE_ELEMENTS));
58051cb0ef41Sopenharmony_ci    }
58061cb0ef41Sopenharmony_ci    __ Bind(&if_value_not_heap_number);
58071cb0ef41Sopenharmony_ci    {
58081cb0ef41Sopenharmony_ci      TransitionElementsTo(node, array, HOLEY_SMI_ELEMENTS, HOLEY_ELEMENTS);
58091cb0ef41Sopenharmony_ci      __ Goto(&do_store, __ Int32Constant(HOLEY_ELEMENTS));
58101cb0ef41Sopenharmony_ci    }
58111cb0ef41Sopenharmony_ci  }
58121cb0ef41Sopenharmony_ci
58131cb0ef41Sopenharmony_ci  __ Bind(&transition_double_to_fast);  // deferred code.
58141cb0ef41Sopenharmony_ci  {
58151cb0ef41Sopenharmony_ci    TransitionElementsTo(node, array, HOLEY_DOUBLE_ELEMENTS, HOLEY_ELEMENTS);
58161cb0ef41Sopenharmony_ci    __ Goto(&do_store, __ Int32Constant(HOLEY_ELEMENTS));
58171cb0ef41Sopenharmony_ci  }
58181cb0ef41Sopenharmony_ci
58191cb0ef41Sopenharmony_ci  // Make sure kind is up-to-date.
58201cb0ef41Sopenharmony_ci  __ Bind(&do_store);
58211cb0ef41Sopenharmony_ci  kind = do_store.PhiAt(0);
58221cb0ef41Sopenharmony_ci
58231cb0ef41Sopenharmony_ci  Node* elements = __ LoadField(AccessBuilder::ForJSObjectElements(), array);
58241cb0ef41Sopenharmony_ci  auto if_kind_is_double = __ MakeLabel();
58251cb0ef41Sopenharmony_ci  auto done = __ MakeLabel();
58261cb0ef41Sopenharmony_ci  __ GotoIf(IsElementsKindGreaterThan(kind, HOLEY_ELEMENTS),
58271cb0ef41Sopenharmony_ci            &if_kind_is_double);
58281cb0ef41Sopenharmony_ci  {
58291cb0ef41Sopenharmony_ci    // Our ElementsKind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS.
58301cb0ef41Sopenharmony_ci    __ StoreElement(AccessBuilder::ForFixedArrayElement(HOLEY_ELEMENTS),
58311cb0ef41Sopenharmony_ci                    elements, index, value);
58321cb0ef41Sopenharmony_ci    __ Goto(&done);
58331cb0ef41Sopenharmony_ci  }
58341cb0ef41Sopenharmony_ci  __ Bind(&if_kind_is_double);
58351cb0ef41Sopenharmony_ci  {
58361cb0ef41Sopenharmony_ci    // Our ElementsKind is HOLEY_DOUBLE_ELEMENTS.
58371cb0ef41Sopenharmony_ci    auto do_double_store = __ MakeLabel();
58381cb0ef41Sopenharmony_ci    __ GotoIfNot(ObjectIsSmi(value), &do_double_store);
58391cb0ef41Sopenharmony_ci    {
58401cb0ef41Sopenharmony_ci      Node* int_value = ChangeSmiToInt32(value);
58411cb0ef41Sopenharmony_ci      Node* float_value = __ ChangeInt32ToFloat64(int_value);
58421cb0ef41Sopenharmony_ci      __ StoreElement(AccessBuilder::ForFixedDoubleArrayElement(), elements,
58431cb0ef41Sopenharmony_ci                      index, float_value);
58441cb0ef41Sopenharmony_ci      __ Goto(&done);
58451cb0ef41Sopenharmony_ci    }
58461cb0ef41Sopenharmony_ci    __ Bind(&do_double_store);
58471cb0ef41Sopenharmony_ci    {
58481cb0ef41Sopenharmony_ci      Node* float_value =
58491cb0ef41Sopenharmony_ci          __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
58501cb0ef41Sopenharmony_ci      __ StoreElement(AccessBuilder::ForFixedDoubleArrayElement(), elements,
58511cb0ef41Sopenharmony_ci                      index, __ Float64SilenceNaN(float_value));
58521cb0ef41Sopenharmony_ci      __ Goto(&done);
58531cb0ef41Sopenharmony_ci    }
58541cb0ef41Sopenharmony_ci  }
58551cb0ef41Sopenharmony_ci
58561cb0ef41Sopenharmony_ci  __ Bind(&done);
58571cb0ef41Sopenharmony_ci}
58581cb0ef41Sopenharmony_ci
58591cb0ef41Sopenharmony_civoid EffectControlLinearizer::LowerTransitionAndStoreNumberElement(Node* node) {
58601cb0ef41Sopenharmony_ci  Node* array = node->InputAt(0);
58611cb0ef41Sopenharmony_ci  Node* index = node->InputAt(1);
58621cb0ef41Sopenharmony_ci  Node* value = node->InputAt(2);  // This is a Float64, not tagged.
58631cb0ef41Sopenharmony_ci
58641cb0ef41Sopenharmony_ci  // Possibly transition array based on input and store.
58651cb0ef41Sopenharmony_ci  //
58661cb0ef41Sopenharmony_ci  //   -- TRANSITION PHASE -----------------
58671cb0ef41Sopenharmony_ci  //   kind = ElementsKind(array)
58681cb0ef41Sopenharmony_ci  //   if kind == HOLEY_SMI_ELEMENTS {
58691cb0ef41Sopenharmony_ci  //     Transition array to HOLEY_DOUBLE_ELEMENTS
58701cb0ef41Sopenharmony_ci  //   } else if kind != HOLEY_DOUBLE_ELEMENTS {
58711cb0ef41Sopenharmony_ci  //     This is UNREACHABLE, execute a debug break.
58721cb0ef41Sopenharmony_ci  //   }
58731cb0ef41Sopenharmony_ci  //
58741cb0ef41Sopenharmony_ci  //   -- STORE PHASE ----------------------
58751cb0ef41Sopenharmony_ci  //   Store array[index] = value (it's a float)
58761cb0ef41Sopenharmony_ci  //
58771cb0ef41Sopenharmony_ci  Node* map = __ LoadField(AccessBuilder::ForMap(), array);
58781cb0ef41Sopenharmony_ci  Node* kind;
58791cb0ef41Sopenharmony_ci  {
58801cb0ef41Sopenharmony_ci    Node* bit_field2 = __ LoadField(AccessBuilder::ForMapBitField2(), map);
58811cb0ef41Sopenharmony_ci    Node* mask = __ Int32Constant(Map::Bits2::ElementsKindBits::kMask);
58821cb0ef41Sopenharmony_ci    Node* andit = __ Word32And(bit_field2, mask);
58831cb0ef41Sopenharmony_ci    Node* shift = __ Int32Constant(Map::Bits2::ElementsKindBits::kShift);
58841cb0ef41Sopenharmony_ci    kind = __ Word32Shr(andit, shift);
58851cb0ef41Sopenharmony_ci  }
58861cb0ef41Sopenharmony_ci
58871cb0ef41Sopenharmony_ci  auto do_store = __ MakeLabel();
58881cb0ef41Sopenharmony_ci
58891cb0ef41Sopenharmony_ci  // {value} is a float64.
58901cb0ef41Sopenharmony_ci  auto transition_smi_array = __ MakeDeferredLabel();
58911cb0ef41Sopenharmony_ci  {
58921cb0ef41Sopenharmony_ci    __ GotoIfNot(IsElementsKindGreaterThan(kind, HOLEY_SMI_ELEMENTS),
58931cb0ef41Sopenharmony_ci                 &transition_smi_array);
58941cb0ef41Sopenharmony_ci    // We expect that our input array started at HOLEY_SMI_ELEMENTS, and
58951cb0ef41Sopenharmony_ci    // climbs the lattice up to HOLEY_DOUBLE_ELEMENTS. Force a debug break
58961cb0ef41Sopenharmony_ci    // if this assumption is broken. It also would be the case that
58971cb0ef41Sopenharmony_ci    // loop peeling can break this assumption.
58981cb0ef41Sopenharmony_ci    __ GotoIf(__ Word32Equal(kind, __ Int32Constant(HOLEY_DOUBLE_ELEMENTS)),
58991cb0ef41Sopenharmony_ci              &do_store);
59001cb0ef41Sopenharmony_ci    __ Unreachable(&do_store);
59011cb0ef41Sopenharmony_ci  }
59021cb0ef41Sopenharmony_ci
59031cb0ef41Sopenharmony_ci  __ Bind(&transition_smi_array);  // deferred code.
59041cb0ef41Sopenharmony_ci  {
59051cb0ef41Sopenharmony_ci    // Transition {array} from HOLEY_SMI_ELEMENTS to HOLEY_DOUBLE_ELEMENTS.
59061cb0ef41Sopenharmony_ci    TransitionElementsTo(node, array, HOLEY_SMI_ELEMENTS,
59071cb0ef41Sopenharmony_ci                         HOLEY_DOUBLE_ELEMENTS);
59081cb0ef41Sopenharmony_ci    __ Goto(&do_store);
59091cb0ef41Sopenharmony_ci  }
59101cb0ef41Sopenharmony_ci
59111cb0ef41Sopenharmony_ci  __ Bind(&do_store);
59121cb0ef41Sopenharmony_ci
59131cb0ef41Sopenharmony_ci  Node* elements = __ LoadField(AccessBuilder::ForJSObjectElements(), array);
59141cb0ef41Sopenharmony_ci  __ StoreElement(AccessBuilder::ForFixedDoubleArrayElement(), elements, index,
59151cb0ef41Sopenharmony_ci                  __ Float64SilenceNaN(value));
59161cb0ef41Sopenharmony_ci}
59171cb0ef41Sopenharmony_ci
59181cb0ef41Sopenharmony_civoid EffectControlLinearizer::LowerTransitionAndStoreNonNumberElement(
59191cb0ef41Sopenharmony_ci    Node* node) {
59201cb0ef41Sopenharmony_ci  Node* array = node->InputAt(0);
59211cb0ef41Sopenharmony_ci  Node* index = node->InputAt(1);
59221cb0ef41Sopenharmony_ci  Node* value = node->InputAt(2);
59231cb0ef41Sopenharmony_ci
59241cb0ef41Sopenharmony_ci  // Possibly transition array based on input and store.
59251cb0ef41Sopenharmony_ci  //
59261cb0ef41Sopenharmony_ci  //   -- TRANSITION PHASE -----------------
59271cb0ef41Sopenharmony_ci  //   kind = ElementsKind(array)
59281cb0ef41Sopenharmony_ci  //   if kind == HOLEY_SMI_ELEMENTS {
59291cb0ef41Sopenharmony_ci  //     Transition array to HOLEY_ELEMENTS
59301cb0ef41Sopenharmony_ci  //   } else if kind == HOLEY_DOUBLE_ELEMENTS {
59311cb0ef41Sopenharmony_ci  //     Transition array to HOLEY_ELEMENTS
59321cb0ef41Sopenharmony_ci  //   }
59331cb0ef41Sopenharmony_ci  //
59341cb0ef41Sopenharmony_ci  //   -- STORE PHASE ----------------------
59351cb0ef41Sopenharmony_ci  //   // kind is HOLEY_ELEMENTS
59361cb0ef41Sopenharmony_ci  //   Store array[index] = value
59371cb0ef41Sopenharmony_ci  //
59381cb0ef41Sopenharmony_ci  Node* map = __ LoadField(AccessBuilder::ForMap(), array);
59391cb0ef41Sopenharmony_ci  Node* kind;
59401cb0ef41Sopenharmony_ci  {
59411cb0ef41Sopenharmony_ci    Node* bit_field2 = __ LoadField(AccessBuilder::ForMapBitField2(), map);
59421cb0ef41Sopenharmony_ci    Node* mask = __ Int32Constant(Map::Bits2::ElementsKindBits::kMask);
59431cb0ef41Sopenharmony_ci    Node* andit = __ Word32And(bit_field2, mask);
59441cb0ef41Sopenharmony_ci    Node* shift = __ Int32Constant(Map::Bits2::ElementsKindBits::kShift);
59451cb0ef41Sopenharmony_ci    kind = __ Word32Shr(andit, shift);
59461cb0ef41Sopenharmony_ci  }
59471cb0ef41Sopenharmony_ci
59481cb0ef41Sopenharmony_ci  auto do_store = __ MakeLabel();
59491cb0ef41Sopenharmony_ci
59501cb0ef41Sopenharmony_ci  auto transition_smi_array = __ MakeDeferredLabel();
59511cb0ef41Sopenharmony_ci  auto transition_double_to_fast = __ MakeDeferredLabel();
59521cb0ef41Sopenharmony_ci  {
59531cb0ef41Sopenharmony_ci    __ GotoIfNot(IsElementsKindGreaterThan(kind, HOLEY_SMI_ELEMENTS),
59541cb0ef41Sopenharmony_ci                 &transition_smi_array);
59551cb0ef41Sopenharmony_ci    __ GotoIf(IsElementsKindGreaterThan(kind, HOLEY_ELEMENTS),
59561cb0ef41Sopenharmony_ci              &transition_double_to_fast);
59571cb0ef41Sopenharmony_ci    __ Goto(&do_store);
59581cb0ef41Sopenharmony_ci  }
59591cb0ef41Sopenharmony_ci
59601cb0ef41Sopenharmony_ci  __ Bind(&transition_smi_array);  // deferred code.
59611cb0ef41Sopenharmony_ci  {
59621cb0ef41Sopenharmony_ci    // Transition {array} from HOLEY_SMI_ELEMENTS to HOLEY_ELEMENTS.
59631cb0ef41Sopenharmony_ci    TransitionElementsTo(node, array, HOLEY_SMI_ELEMENTS, HOLEY_ELEMENTS);
59641cb0ef41Sopenharmony_ci    __ Goto(&do_store);
59651cb0ef41Sopenharmony_ci  }
59661cb0ef41Sopenharmony_ci
59671cb0ef41Sopenharmony_ci  __ Bind(&transition_double_to_fast);  // deferred code.
59681cb0ef41Sopenharmony_ci  {
59691cb0ef41Sopenharmony_ci    TransitionElementsTo(node, array, HOLEY_DOUBLE_ELEMENTS, HOLEY_ELEMENTS);
59701cb0ef41Sopenharmony_ci    __ Goto(&do_store);
59711cb0ef41Sopenharmony_ci  }
59721cb0ef41Sopenharmony_ci
59731cb0ef41Sopenharmony_ci  __ Bind(&do_store);
59741cb0ef41Sopenharmony_ci
59751cb0ef41Sopenharmony_ci  Node* elements = __ LoadField(AccessBuilder::ForJSObjectElements(), array);
59761cb0ef41Sopenharmony_ci  // Our ElementsKind is HOLEY_ELEMENTS.
59771cb0ef41Sopenharmony_ci  ElementAccess access = AccessBuilder::ForFixedArrayElement(HOLEY_ELEMENTS);
59781cb0ef41Sopenharmony_ci  Type value_type = ValueTypeParameterOf(node->op());
59791cb0ef41Sopenharmony_ci  if (value_type.Is(Type::BooleanOrNullOrUndefined())) {
59801cb0ef41Sopenharmony_ci    access.type = value_type;
59811cb0ef41Sopenharmony_ci    access.write_barrier_kind = kNoWriteBarrier;
59821cb0ef41Sopenharmony_ci  }
59831cb0ef41Sopenharmony_ci  __ StoreElement(access, elements, index, value);
59841cb0ef41Sopenharmony_ci}
59851cb0ef41Sopenharmony_ci
59861cb0ef41Sopenharmony_civoid EffectControlLinearizer::LowerStoreSignedSmallElement(Node* node) {
59871cb0ef41Sopenharmony_ci  Node* array = node->InputAt(0);
59881cb0ef41Sopenharmony_ci  Node* index = node->InputAt(1);
59891cb0ef41Sopenharmony_ci  Node* value = node->InputAt(2);  // int32
59901cb0ef41Sopenharmony_ci
59911cb0ef41Sopenharmony_ci  // Store a signed small in an output array.
59921cb0ef41Sopenharmony_ci  //
59931cb0ef41Sopenharmony_ci  //   kind = ElementsKind(array)
59941cb0ef41Sopenharmony_ci  //
59951cb0ef41Sopenharmony_ci  //   -- STORE PHASE ----------------------
59961cb0ef41Sopenharmony_ci  //   if kind == HOLEY_DOUBLE_ELEMENTS {
59971cb0ef41Sopenharmony_ci  //     float_value = convert int32 to float
59981cb0ef41Sopenharmony_ci  //     Store array[index] = float_value
59991cb0ef41Sopenharmony_ci  //   } else {
60001cb0ef41Sopenharmony_ci  //     // kind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS
60011cb0ef41Sopenharmony_ci  //     smi_value = convert int32 to smi
60021cb0ef41Sopenharmony_ci  //     Store array[index] = smi_value
60031cb0ef41Sopenharmony_ci  //   }
60041cb0ef41Sopenharmony_ci  //
60051cb0ef41Sopenharmony_ci  Node* map = __ LoadField(AccessBuilder::ForMap(), array);
60061cb0ef41Sopenharmony_ci  Node* kind;
60071cb0ef41Sopenharmony_ci  {
60081cb0ef41Sopenharmony_ci    Node* bit_field2 = __ LoadField(AccessBuilder::ForMapBitField2(), map);
60091cb0ef41Sopenharmony_ci    Node* mask = __ Int32Constant(Map::Bits2::ElementsKindBits::kMask);
60101cb0ef41Sopenharmony_ci    Node* andit = __ Word32And(bit_field2, mask);
60111cb0ef41Sopenharmony_ci    Node* shift = __ Int32Constant(Map::Bits2::ElementsKindBits::kShift);
60121cb0ef41Sopenharmony_ci    kind = __ Word32Shr(andit, shift);
60131cb0ef41Sopenharmony_ci  }
60141cb0ef41Sopenharmony_ci
60151cb0ef41Sopenharmony_ci  Node* elements = __ LoadField(AccessBuilder::ForJSObjectElements(), array);
60161cb0ef41Sopenharmony_ci  auto if_kind_is_double = __ MakeLabel();
60171cb0ef41Sopenharmony_ci  auto done = __ MakeLabel();
60181cb0ef41Sopenharmony_ci  __ GotoIf(IsElementsKindGreaterThan(kind, HOLEY_ELEMENTS),
60191cb0ef41Sopenharmony_ci            &if_kind_is_double);
60201cb0ef41Sopenharmony_ci  {
60211cb0ef41Sopenharmony_ci    // Our ElementsKind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS.
60221cb0ef41Sopenharmony_ci    // In this case, we know our value is a signed small, and we can optimize
60231cb0ef41Sopenharmony_ci    // the ElementAccess information.
60241cb0ef41Sopenharmony_ci    ElementAccess access = AccessBuilder::ForFixedArrayElement();
60251cb0ef41Sopenharmony_ci    access.type = Type::SignedSmall();
60261cb0ef41Sopenharmony_ci    access.machine_type = MachineType::TaggedSigned();
60271cb0ef41Sopenharmony_ci    access.write_barrier_kind = kNoWriteBarrier;
60281cb0ef41Sopenharmony_ci    Node* smi_value = ChangeInt32ToSmi(value);
60291cb0ef41Sopenharmony_ci    __ StoreElement(access, elements, index, smi_value);
60301cb0ef41Sopenharmony_ci    __ Goto(&done);
60311cb0ef41Sopenharmony_ci  }
60321cb0ef41Sopenharmony_ci  __ Bind(&if_kind_is_double);
60331cb0ef41Sopenharmony_ci  {
60341cb0ef41Sopenharmony_ci    // Our ElementsKind is HOLEY_DOUBLE_ELEMENTS.
60351cb0ef41Sopenharmony_ci    Node* float_value = __ ChangeInt32ToFloat64(value);
60361cb0ef41Sopenharmony_ci    __ StoreElement(AccessBuilder::ForFixedDoubleArrayElement(), elements,
60371cb0ef41Sopenharmony_ci                    index, float_value);
60381cb0ef41Sopenharmony_ci    __ Goto(&done);
60391cb0ef41Sopenharmony_ci  }
60401cb0ef41Sopenharmony_ci
60411cb0ef41Sopenharmony_ci  __ Bind(&done);
60421cb0ef41Sopenharmony_ci}
60431cb0ef41Sopenharmony_ci
60441cb0ef41Sopenharmony_civoid EffectControlLinearizer::LowerRuntimeAbort(Node* node) {
60451cb0ef41Sopenharmony_ci  AbortReason reason = AbortReasonOf(node->op());
60461cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
60471cb0ef41Sopenharmony_ci  Runtime::FunctionId id = Runtime::kAbort;
60481cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
60491cb0ef41Sopenharmony_ci      graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
60501cb0ef41Sopenharmony_ci  __ Call(call_descriptor, __ CEntryStubConstant(1),
60511cb0ef41Sopenharmony_ci          __ SmiConstant(static_cast<int>(reason)),
60521cb0ef41Sopenharmony_ci          __ ExternalConstant(ExternalReference::Create(id)),
60531cb0ef41Sopenharmony_ci          __ Int32Constant(1), __ NoContextConstant());
60541cb0ef41Sopenharmony_ci}
60551cb0ef41Sopenharmony_ci
60561cb0ef41Sopenharmony_citemplate <typename... Args>
60571cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::CallBuiltin(Builtin builtin,
60581cb0ef41Sopenharmony_ci                                           Operator::Properties properties,
60591cb0ef41Sopenharmony_ci                                           Args... args) {
60601cb0ef41Sopenharmony_ci  Callable const callable = Builtins::CallableFor(isolate(), builtin);
60611cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
60621cb0ef41Sopenharmony_ci      graph()->zone(), callable.descriptor(),
60631cb0ef41Sopenharmony_ci      callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags,
60641cb0ef41Sopenharmony_ci      properties);
60651cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ HeapConstant(callable.code()), args...,
60661cb0ef41Sopenharmony_ci                 __ NoContextConstant());
60671cb0ef41Sopenharmony_ci}
60681cb0ef41Sopenharmony_ci
60691cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerAssertType(Node* node) {
60701cb0ef41Sopenharmony_ci  DCHECK_EQ(node->opcode(), IrOpcode::kAssertType);
60711cb0ef41Sopenharmony_ci  Type type = OpParameter<Type>(node->op());
60721cb0ef41Sopenharmony_ci  CHECK(type.CanBeAsserted());
60731cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
60741cb0ef41Sopenharmony_ci  Node* allocated_type;
60751cb0ef41Sopenharmony_ci  {
60761cb0ef41Sopenharmony_ci    DCHECK(isolate()->CurrentLocalHeap()->is_main_thread());
60771cb0ef41Sopenharmony_ci    base::Optional<UnparkedScope> unparked_scope;
60781cb0ef41Sopenharmony_ci    if (isolate()->CurrentLocalHeap()->IsParked()) {
60791cb0ef41Sopenharmony_ci      unparked_scope.emplace(isolate()->main_thread_local_isolate());
60801cb0ef41Sopenharmony_ci    }
60811cb0ef41Sopenharmony_ci    allocated_type = __ HeapConstant(type.AllocateOnHeap(factory()));
60821cb0ef41Sopenharmony_ci  }
60831cb0ef41Sopenharmony_ci  CallBuiltin(Builtin::kCheckTurbofanType, node->op()->properties(), input,
60841cb0ef41Sopenharmony_ci              allocated_type, __ SmiConstant(node->id()));
60851cb0ef41Sopenharmony_ci  return input;
60861cb0ef41Sopenharmony_ci}
60871cb0ef41Sopenharmony_ci
60881cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerFoldConstant(Node* node) {
60891cb0ef41Sopenharmony_ci  DCHECK_EQ(node->opcode(), IrOpcode::kFoldConstant);
60901cb0ef41Sopenharmony_ci  Node* original = node->InputAt(0);
60911cb0ef41Sopenharmony_ci  Node* constant = node->InputAt(1);
60921cb0ef41Sopenharmony_ci  CallBuiltin(Builtin::kCheckSameObject, node->op()->properties(), original,
60931cb0ef41Sopenharmony_ci              constant);
60941cb0ef41Sopenharmony_ci  return constant;
60951cb0ef41Sopenharmony_ci}
60961cb0ef41Sopenharmony_ci
60971cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerConvertReceiver(Node* node) {
60981cb0ef41Sopenharmony_ci  ConvertReceiverMode const mode = ConvertReceiverModeOf(node->op());
60991cb0ef41Sopenharmony_ci  Node* value = node->InputAt(0);
61001cb0ef41Sopenharmony_ci  Node* global_proxy = node->InputAt(1);
61011cb0ef41Sopenharmony_ci
61021cb0ef41Sopenharmony_ci  switch (mode) {
61031cb0ef41Sopenharmony_ci    case ConvertReceiverMode::kNullOrUndefined: {
61041cb0ef41Sopenharmony_ci      return global_proxy;
61051cb0ef41Sopenharmony_ci    }
61061cb0ef41Sopenharmony_ci    case ConvertReceiverMode::kNotNullOrUndefined: {
61071cb0ef41Sopenharmony_ci      auto convert_to_object = __ MakeDeferredLabel();
61081cb0ef41Sopenharmony_ci      auto done_convert = __ MakeLabel(MachineRepresentation::kTagged);
61091cb0ef41Sopenharmony_ci
61101cb0ef41Sopenharmony_ci      // Check if {value} is already a JSReceiver.
61111cb0ef41Sopenharmony_ci      __ GotoIf(ObjectIsSmi(value), &convert_to_object);
61121cb0ef41Sopenharmony_ci      STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
61131cb0ef41Sopenharmony_ci      Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
61141cb0ef41Sopenharmony_ci      Node* value_instance_type =
61151cb0ef41Sopenharmony_ci          __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
61161cb0ef41Sopenharmony_ci      Node* check = __ Uint32LessThan(
61171cb0ef41Sopenharmony_ci          value_instance_type, __ Uint32Constant(FIRST_JS_RECEIVER_TYPE));
61181cb0ef41Sopenharmony_ci      __ GotoIf(check, &convert_to_object);
61191cb0ef41Sopenharmony_ci      __ Goto(&done_convert, value);
61201cb0ef41Sopenharmony_ci
61211cb0ef41Sopenharmony_ci      // Wrap the primitive {value} into a JSPrimitiveWrapper.
61221cb0ef41Sopenharmony_ci      __ Bind(&convert_to_object);
61231cb0ef41Sopenharmony_ci      Operator::Properties properties = Operator::kEliminatable;
61241cb0ef41Sopenharmony_ci      Callable callable = Builtins::CallableFor(isolate(), Builtin::kToObject);
61251cb0ef41Sopenharmony_ci      CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
61261cb0ef41Sopenharmony_ci      auto call_descriptor = Linkage::GetStubCallDescriptor(
61271cb0ef41Sopenharmony_ci          graph()->zone(), callable.descriptor(),
61281cb0ef41Sopenharmony_ci          callable.descriptor().GetStackParameterCount(), flags, properties);
61291cb0ef41Sopenharmony_ci      Node* native_context = __ LoadField(
61301cb0ef41Sopenharmony_ci          AccessBuilder::ForJSGlobalProxyNativeContext(), global_proxy);
61311cb0ef41Sopenharmony_ci      Node* result = __ Call(call_descriptor, __ HeapConstant(callable.code()),
61321cb0ef41Sopenharmony_ci                             value, native_context);
61331cb0ef41Sopenharmony_ci      __ Goto(&done_convert, result);
61341cb0ef41Sopenharmony_ci
61351cb0ef41Sopenharmony_ci      __ Bind(&done_convert);
61361cb0ef41Sopenharmony_ci      return done_convert.PhiAt(0);
61371cb0ef41Sopenharmony_ci    }
61381cb0ef41Sopenharmony_ci    case ConvertReceiverMode::kAny: {
61391cb0ef41Sopenharmony_ci      auto convert_to_object = __ MakeDeferredLabel();
61401cb0ef41Sopenharmony_ci      auto convert_global_proxy = __ MakeDeferredLabel();
61411cb0ef41Sopenharmony_ci      auto done_convert = __ MakeLabel(MachineRepresentation::kTagged);
61421cb0ef41Sopenharmony_ci
61431cb0ef41Sopenharmony_ci      // Check if {value} is already a JSReceiver, or null/undefined.
61441cb0ef41Sopenharmony_ci      __ GotoIf(ObjectIsSmi(value), &convert_to_object);
61451cb0ef41Sopenharmony_ci      STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
61461cb0ef41Sopenharmony_ci      Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
61471cb0ef41Sopenharmony_ci      Node* value_instance_type =
61481cb0ef41Sopenharmony_ci          __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
61491cb0ef41Sopenharmony_ci      Node* check = __ Uint32LessThan(
61501cb0ef41Sopenharmony_ci          value_instance_type, __ Uint32Constant(FIRST_JS_RECEIVER_TYPE));
61511cb0ef41Sopenharmony_ci      __ GotoIf(check, &convert_to_object);
61521cb0ef41Sopenharmony_ci      __ Goto(&done_convert, value);
61531cb0ef41Sopenharmony_ci
61541cb0ef41Sopenharmony_ci      // Wrap the primitive {value} into a JSPrimitiveWrapper.
61551cb0ef41Sopenharmony_ci      __ Bind(&convert_to_object);
61561cb0ef41Sopenharmony_ci      __ GotoIf(__ TaggedEqual(value, __ UndefinedConstant()),
61571cb0ef41Sopenharmony_ci                &convert_global_proxy);
61581cb0ef41Sopenharmony_ci      __ GotoIf(__ TaggedEqual(value, __ NullConstant()),
61591cb0ef41Sopenharmony_ci                &convert_global_proxy);
61601cb0ef41Sopenharmony_ci      Operator::Properties properties = Operator::kEliminatable;
61611cb0ef41Sopenharmony_ci      Callable callable = Builtins::CallableFor(isolate(), Builtin::kToObject);
61621cb0ef41Sopenharmony_ci      CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
61631cb0ef41Sopenharmony_ci      auto call_descriptor = Linkage::GetStubCallDescriptor(
61641cb0ef41Sopenharmony_ci          graph()->zone(), callable.descriptor(),
61651cb0ef41Sopenharmony_ci          callable.descriptor().GetStackParameterCount(), flags, properties);
61661cb0ef41Sopenharmony_ci      Node* native_context = __ LoadField(
61671cb0ef41Sopenharmony_ci          AccessBuilder::ForJSGlobalProxyNativeContext(), global_proxy);
61681cb0ef41Sopenharmony_ci      Node* result = __ Call(call_descriptor, __ HeapConstant(callable.code()),
61691cb0ef41Sopenharmony_ci                             value, native_context);
61701cb0ef41Sopenharmony_ci      __ Goto(&done_convert, result);
61711cb0ef41Sopenharmony_ci
61721cb0ef41Sopenharmony_ci      // Replace the {value} with the {global_proxy}.
61731cb0ef41Sopenharmony_ci      __ Bind(&convert_global_proxy);
61741cb0ef41Sopenharmony_ci      __ Goto(&done_convert, global_proxy);
61751cb0ef41Sopenharmony_ci
61761cb0ef41Sopenharmony_ci      __ Bind(&done_convert);
61771cb0ef41Sopenharmony_ci      return done_convert.PhiAt(0);
61781cb0ef41Sopenharmony_ci    }
61791cb0ef41Sopenharmony_ci  }
61801cb0ef41Sopenharmony_ci
61811cb0ef41Sopenharmony_ci  UNREACHABLE();
61821cb0ef41Sopenharmony_ci}
61831cb0ef41Sopenharmony_ci
61841cb0ef41Sopenharmony_ciMaybe<Node*> EffectControlLinearizer::LowerFloat64RoundUp(Node* node) {
61851cb0ef41Sopenharmony_ci  // Nothing to be done if a fast hardware instruction is available.
61861cb0ef41Sopenharmony_ci  if (machine()->Float64RoundUp().IsSupported()) {
61871cb0ef41Sopenharmony_ci    return Nothing<Node*>();
61881cb0ef41Sopenharmony_ci  }
61891cb0ef41Sopenharmony_ci
61901cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
61911cb0ef41Sopenharmony_ci
61921cb0ef41Sopenharmony_ci  // General case for ceil.
61931cb0ef41Sopenharmony_ci  //
61941cb0ef41Sopenharmony_ci  //   if 0.0 < input then
61951cb0ef41Sopenharmony_ci  //     if 2^52 <= input then
61961cb0ef41Sopenharmony_ci  //       input
61971cb0ef41Sopenharmony_ci  //     else
61981cb0ef41Sopenharmony_ci  //       let temp1 = (2^52 + input) - 2^52 in
61991cb0ef41Sopenharmony_ci  //       if temp1 < input then
62001cb0ef41Sopenharmony_ci  //         temp1 + 1
62011cb0ef41Sopenharmony_ci  //       else
62021cb0ef41Sopenharmony_ci  //         temp1
62031cb0ef41Sopenharmony_ci  //   else
62041cb0ef41Sopenharmony_ci  //     if input == 0 then
62051cb0ef41Sopenharmony_ci  //       input
62061cb0ef41Sopenharmony_ci  //     else
62071cb0ef41Sopenharmony_ci  //       if input <= -2^52 then
62081cb0ef41Sopenharmony_ci  //         input
62091cb0ef41Sopenharmony_ci  //       else
62101cb0ef41Sopenharmony_ci  //         let temp1 = -0 - input in
62111cb0ef41Sopenharmony_ci  //         let temp2 = (2^52 + temp1) - 2^52 in
62121cb0ef41Sopenharmony_ci  //         let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
62131cb0ef41Sopenharmony_ci  //         -0 - temp3
62141cb0ef41Sopenharmony_ci
62151cb0ef41Sopenharmony_ci  auto if_not_positive = __ MakeDeferredLabel();
62161cb0ef41Sopenharmony_ci  auto if_greater_than_two_52 = __ MakeDeferredLabel();
62171cb0ef41Sopenharmony_ci  auto if_less_than_minus_two_52 = __ MakeDeferredLabel();
62181cb0ef41Sopenharmony_ci  auto if_zero = __ MakeDeferredLabel();
62191cb0ef41Sopenharmony_ci  auto done_temp3 = __ MakeLabel(MachineRepresentation::kFloat64);
62201cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kFloat64);
62211cb0ef41Sopenharmony_ci
62221cb0ef41Sopenharmony_ci  Node* const zero = __ Float64Constant(0.0);
62231cb0ef41Sopenharmony_ci  Node* const two_52 = __ Float64Constant(4503599627370496.0E0);
62241cb0ef41Sopenharmony_ci  Node* const one = __ Float64Constant(1.0);
62251cb0ef41Sopenharmony_ci
62261cb0ef41Sopenharmony_ci  Node* check0 = __ Float64LessThan(zero, input);
62271cb0ef41Sopenharmony_ci  __ GotoIfNot(check0, &if_not_positive);
62281cb0ef41Sopenharmony_ci  {
62291cb0ef41Sopenharmony_ci    Node* check1 = __ Float64LessThanOrEqual(two_52, input);
62301cb0ef41Sopenharmony_ci    __ GotoIf(check1, &if_greater_than_two_52);
62311cb0ef41Sopenharmony_ci    {
62321cb0ef41Sopenharmony_ci      Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52);
62331cb0ef41Sopenharmony_ci      __ GotoIfNot(__ Float64LessThan(temp1, input), &done, temp1);
62341cb0ef41Sopenharmony_ci      __ Goto(&done, __ Float64Add(temp1, one));
62351cb0ef41Sopenharmony_ci    }
62361cb0ef41Sopenharmony_ci
62371cb0ef41Sopenharmony_ci    __ Bind(&if_greater_than_two_52);
62381cb0ef41Sopenharmony_ci    __ Goto(&done, input);
62391cb0ef41Sopenharmony_ci  }
62401cb0ef41Sopenharmony_ci
62411cb0ef41Sopenharmony_ci  __ Bind(&if_not_positive);
62421cb0ef41Sopenharmony_ci  {
62431cb0ef41Sopenharmony_ci    Node* check1 = __ Float64Equal(input, zero);
62441cb0ef41Sopenharmony_ci    __ GotoIf(check1, &if_zero);
62451cb0ef41Sopenharmony_ci
62461cb0ef41Sopenharmony_ci    Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0);
62471cb0ef41Sopenharmony_ci    Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52);
62481cb0ef41Sopenharmony_ci    __ GotoIf(check2, &if_less_than_minus_two_52);
62491cb0ef41Sopenharmony_ci
62501cb0ef41Sopenharmony_ci    {
62511cb0ef41Sopenharmony_ci      Node* const minus_zero = __ Float64Constant(-0.0);
62521cb0ef41Sopenharmony_ci      Node* temp1 = __ Float64Sub(minus_zero, input);
62531cb0ef41Sopenharmony_ci      Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52);
62541cb0ef41Sopenharmony_ci      Node* check3 = __ Float64LessThan(temp1, temp2);
62551cb0ef41Sopenharmony_ci      __ GotoIfNot(check3, &done_temp3, temp2);
62561cb0ef41Sopenharmony_ci      __ Goto(&done_temp3, __ Float64Sub(temp2, one));
62571cb0ef41Sopenharmony_ci
62581cb0ef41Sopenharmony_ci      __ Bind(&done_temp3);
62591cb0ef41Sopenharmony_ci      Node* temp3 = done_temp3.PhiAt(0);
62601cb0ef41Sopenharmony_ci      __ Goto(&done, __ Float64Sub(minus_zero, temp3));
62611cb0ef41Sopenharmony_ci    }
62621cb0ef41Sopenharmony_ci    __ Bind(&if_less_than_minus_two_52);
62631cb0ef41Sopenharmony_ci    __ Goto(&done, input);
62641cb0ef41Sopenharmony_ci
62651cb0ef41Sopenharmony_ci    __ Bind(&if_zero);
62661cb0ef41Sopenharmony_ci    __ Goto(&done, input);
62671cb0ef41Sopenharmony_ci  }
62681cb0ef41Sopenharmony_ci  __ Bind(&done);
62691cb0ef41Sopenharmony_ci  return Just(done.PhiAt(0));
62701cb0ef41Sopenharmony_ci}
62711cb0ef41Sopenharmony_ci
62721cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildFloat64RoundDown(Node* value) {
62731cb0ef41Sopenharmony_ci  if (machine()->Float64RoundDown().IsSupported()) {
62741cb0ef41Sopenharmony_ci    return __ Float64RoundDown(value);
62751cb0ef41Sopenharmony_ci  }
62761cb0ef41Sopenharmony_ci
62771cb0ef41Sopenharmony_ci  Node* const input = value;
62781cb0ef41Sopenharmony_ci
62791cb0ef41Sopenharmony_ci  // General case for floor.
62801cb0ef41Sopenharmony_ci  //
62811cb0ef41Sopenharmony_ci  //   if 0.0 < input then
62821cb0ef41Sopenharmony_ci  //     if 2^52 <= input then
62831cb0ef41Sopenharmony_ci  //       input
62841cb0ef41Sopenharmony_ci  //     else
62851cb0ef41Sopenharmony_ci  //       let temp1 = (2^52 + input) - 2^52 in
62861cb0ef41Sopenharmony_ci  //       if input < temp1 then
62871cb0ef41Sopenharmony_ci  //         temp1 - 1
62881cb0ef41Sopenharmony_ci  //       else
62891cb0ef41Sopenharmony_ci  //         temp1
62901cb0ef41Sopenharmony_ci  //   else
62911cb0ef41Sopenharmony_ci  //     if input == 0 then
62921cb0ef41Sopenharmony_ci  //       input
62931cb0ef41Sopenharmony_ci  //     else
62941cb0ef41Sopenharmony_ci  //       if input <= -2^52 then
62951cb0ef41Sopenharmony_ci  //         input
62961cb0ef41Sopenharmony_ci  //       else
62971cb0ef41Sopenharmony_ci  //         let temp1 = -0 - input in
62981cb0ef41Sopenharmony_ci  //         let temp2 = (2^52 + temp1) - 2^52 in
62991cb0ef41Sopenharmony_ci  //         if temp2 < temp1 then
63001cb0ef41Sopenharmony_ci  //           -1 - temp2
63011cb0ef41Sopenharmony_ci  //         else
63021cb0ef41Sopenharmony_ci  //           -0 - temp2
63031cb0ef41Sopenharmony_ci
63041cb0ef41Sopenharmony_ci  auto if_not_positive = __ MakeDeferredLabel();
63051cb0ef41Sopenharmony_ci  auto if_greater_than_two_52 = __ MakeDeferredLabel();
63061cb0ef41Sopenharmony_ci  auto if_less_than_minus_two_52 = __ MakeDeferredLabel();
63071cb0ef41Sopenharmony_ci  auto if_temp2_lt_temp1 = __ MakeLabel();
63081cb0ef41Sopenharmony_ci  auto if_zero = __ MakeDeferredLabel();
63091cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kFloat64);
63101cb0ef41Sopenharmony_ci
63111cb0ef41Sopenharmony_ci  Node* const zero = __ Float64Constant(0.0);
63121cb0ef41Sopenharmony_ci  Node* const two_52 = __ Float64Constant(4503599627370496.0E0);
63131cb0ef41Sopenharmony_ci
63141cb0ef41Sopenharmony_ci  Node* check0 = __ Float64LessThan(zero, input);
63151cb0ef41Sopenharmony_ci  __ GotoIfNot(check0, &if_not_positive);
63161cb0ef41Sopenharmony_ci  {
63171cb0ef41Sopenharmony_ci    Node* check1 = __ Float64LessThanOrEqual(two_52, input);
63181cb0ef41Sopenharmony_ci    __ GotoIf(check1, &if_greater_than_two_52);
63191cb0ef41Sopenharmony_ci    {
63201cb0ef41Sopenharmony_ci      Node* const one = __ Float64Constant(1.0);
63211cb0ef41Sopenharmony_ci      Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52);
63221cb0ef41Sopenharmony_ci      __ GotoIfNot(__ Float64LessThan(input, temp1), &done, temp1);
63231cb0ef41Sopenharmony_ci      __ Goto(&done, __ Float64Sub(temp1, one));
63241cb0ef41Sopenharmony_ci    }
63251cb0ef41Sopenharmony_ci
63261cb0ef41Sopenharmony_ci    __ Bind(&if_greater_than_two_52);
63271cb0ef41Sopenharmony_ci    __ Goto(&done, input);
63281cb0ef41Sopenharmony_ci  }
63291cb0ef41Sopenharmony_ci
63301cb0ef41Sopenharmony_ci  __ Bind(&if_not_positive);
63311cb0ef41Sopenharmony_ci  {
63321cb0ef41Sopenharmony_ci    Node* check1 = __ Float64Equal(input, zero);
63331cb0ef41Sopenharmony_ci    __ GotoIf(check1, &if_zero);
63341cb0ef41Sopenharmony_ci
63351cb0ef41Sopenharmony_ci    Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0);
63361cb0ef41Sopenharmony_ci    Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52);
63371cb0ef41Sopenharmony_ci    __ GotoIf(check2, &if_less_than_minus_two_52);
63381cb0ef41Sopenharmony_ci
63391cb0ef41Sopenharmony_ci    {
63401cb0ef41Sopenharmony_ci      Node* const minus_zero = __ Float64Constant(-0.0);
63411cb0ef41Sopenharmony_ci      Node* temp1 = __ Float64Sub(minus_zero, input);
63421cb0ef41Sopenharmony_ci      Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52);
63431cb0ef41Sopenharmony_ci      Node* check3 = __ Float64LessThan(temp2, temp1);
63441cb0ef41Sopenharmony_ci      __ GotoIf(check3, &if_temp2_lt_temp1);
63451cb0ef41Sopenharmony_ci      __ Goto(&done, __ Float64Sub(minus_zero, temp2));
63461cb0ef41Sopenharmony_ci
63471cb0ef41Sopenharmony_ci      __ Bind(&if_temp2_lt_temp1);
63481cb0ef41Sopenharmony_ci      __ Goto(&done, __ Float64Sub(__ Float64Constant(-1.0), temp2));
63491cb0ef41Sopenharmony_ci    }
63501cb0ef41Sopenharmony_ci    __ Bind(&if_less_than_minus_two_52);
63511cb0ef41Sopenharmony_ci    __ Goto(&done, input);
63521cb0ef41Sopenharmony_ci
63531cb0ef41Sopenharmony_ci    __ Bind(&if_zero);
63541cb0ef41Sopenharmony_ci    __ Goto(&done, input);
63551cb0ef41Sopenharmony_ci  }
63561cb0ef41Sopenharmony_ci  __ Bind(&done);
63571cb0ef41Sopenharmony_ci  return done.PhiAt(0);
63581cb0ef41Sopenharmony_ci}
63591cb0ef41Sopenharmony_ci
63601cb0ef41Sopenharmony_ciMaybe<Node*> EffectControlLinearizer::LowerFloat64RoundDown(Node* node) {
63611cb0ef41Sopenharmony_ci  // Nothing to be done if a fast hardware instruction is available.
63621cb0ef41Sopenharmony_ci  if (machine()->Float64RoundDown().IsSupported()) {
63631cb0ef41Sopenharmony_ci    return Nothing<Node*>();
63641cb0ef41Sopenharmony_ci  }
63651cb0ef41Sopenharmony_ci
63661cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
63671cb0ef41Sopenharmony_ci  return Just(BuildFloat64RoundDown(input));
63681cb0ef41Sopenharmony_ci}
63691cb0ef41Sopenharmony_ci
63701cb0ef41Sopenharmony_ciMaybe<Node*> EffectControlLinearizer::LowerFloat64RoundTiesEven(Node* node) {
63711cb0ef41Sopenharmony_ci  // Nothing to be done if a fast hardware instruction is available.
63721cb0ef41Sopenharmony_ci  if (machine()->Float64RoundTiesEven().IsSupported()) {
63731cb0ef41Sopenharmony_ci    return Nothing<Node*>();
63741cb0ef41Sopenharmony_ci  }
63751cb0ef41Sopenharmony_ci
63761cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
63771cb0ef41Sopenharmony_ci
63781cb0ef41Sopenharmony_ci  // Generate case for round ties to even:
63791cb0ef41Sopenharmony_ci  //
63801cb0ef41Sopenharmony_ci  //   let value = floor(input) in
63811cb0ef41Sopenharmony_ci  //   let temp1 = input - value in
63821cb0ef41Sopenharmony_ci  //   if temp1 < 0.5 then
63831cb0ef41Sopenharmony_ci  //     value
63841cb0ef41Sopenharmony_ci  //   else if 0.5 < temp1 then
63851cb0ef41Sopenharmony_ci  //     value + 1.0
63861cb0ef41Sopenharmony_ci  //   else
63871cb0ef41Sopenharmony_ci  //     let temp2 = value % 2.0 in
63881cb0ef41Sopenharmony_ci  //     if temp2 == 0.0 then
63891cb0ef41Sopenharmony_ci  //       value
63901cb0ef41Sopenharmony_ci  //     else
63911cb0ef41Sopenharmony_ci  //       value + 1.0
63921cb0ef41Sopenharmony_ci
63931cb0ef41Sopenharmony_ci  auto if_is_half = __ MakeLabel();
63941cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kFloat64);
63951cb0ef41Sopenharmony_ci
63961cb0ef41Sopenharmony_ci  Node* value = BuildFloat64RoundDown(input);
63971cb0ef41Sopenharmony_ci  Node* temp1 = __ Float64Sub(input, value);
63981cb0ef41Sopenharmony_ci
63991cb0ef41Sopenharmony_ci  Node* const half = __ Float64Constant(0.5);
64001cb0ef41Sopenharmony_ci  Node* check0 = __ Float64LessThan(temp1, half);
64011cb0ef41Sopenharmony_ci  __ GotoIf(check0, &done, value);
64021cb0ef41Sopenharmony_ci
64031cb0ef41Sopenharmony_ci  Node* const one = __ Float64Constant(1.0);
64041cb0ef41Sopenharmony_ci  Node* check1 = __ Float64LessThan(half, temp1);
64051cb0ef41Sopenharmony_ci  __ GotoIfNot(check1, &if_is_half);
64061cb0ef41Sopenharmony_ci  __ Goto(&done, __ Float64Add(value, one));
64071cb0ef41Sopenharmony_ci
64081cb0ef41Sopenharmony_ci  __ Bind(&if_is_half);
64091cb0ef41Sopenharmony_ci  Node* temp2 = __ Float64Mod(value, __ Float64Constant(2.0));
64101cb0ef41Sopenharmony_ci  Node* check2 = __ Float64Equal(temp2, __ Float64Constant(0.0));
64111cb0ef41Sopenharmony_ci  __ GotoIf(check2, &done, value);
64121cb0ef41Sopenharmony_ci  __ Goto(&done, __ Float64Add(value, one));
64131cb0ef41Sopenharmony_ci
64141cb0ef41Sopenharmony_ci  __ Bind(&done);
64151cb0ef41Sopenharmony_ci  return Just(done.PhiAt(0));
64161cb0ef41Sopenharmony_ci}
64171cb0ef41Sopenharmony_ci
64181cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildFloat64RoundTruncate(Node* input) {
64191cb0ef41Sopenharmony_ci  if (machine()->Float64RoundTruncate().IsSupported()) {
64201cb0ef41Sopenharmony_ci    return __ Float64RoundTruncate(input);
64211cb0ef41Sopenharmony_ci  }
64221cb0ef41Sopenharmony_ci  // General case for trunc.
64231cb0ef41Sopenharmony_ci  //
64241cb0ef41Sopenharmony_ci  //   if 0.0 < input then
64251cb0ef41Sopenharmony_ci  //     if 2^52 <= input then
64261cb0ef41Sopenharmony_ci  //       input
64271cb0ef41Sopenharmony_ci  //     else
64281cb0ef41Sopenharmony_ci  //       let temp1 = (2^52 + input) - 2^52 in
64291cb0ef41Sopenharmony_ci  //       if input < temp1 then
64301cb0ef41Sopenharmony_ci  //         temp1 - 1
64311cb0ef41Sopenharmony_ci  //       else
64321cb0ef41Sopenharmony_ci  //         temp1
64331cb0ef41Sopenharmony_ci  //   else
64341cb0ef41Sopenharmony_ci  //     if input == 0 then
64351cb0ef41Sopenharmony_ci  //       input
64361cb0ef41Sopenharmony_ci  //     else
64371cb0ef41Sopenharmony_ci  //       if input <= -2^52 then
64381cb0ef41Sopenharmony_ci  //         input
64391cb0ef41Sopenharmony_ci  //       else
64401cb0ef41Sopenharmony_ci  //         let temp1 = -0 - input in
64411cb0ef41Sopenharmony_ci  //         let temp2 = (2^52 + temp1) - 2^52 in
64421cb0ef41Sopenharmony_ci  //         let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
64431cb0ef41Sopenharmony_ci  //         -0 - temp3
64441cb0ef41Sopenharmony_ci  //
64451cb0ef41Sopenharmony_ci  // Note: We do not use the Diamond helper class here, because it really hurts
64461cb0ef41Sopenharmony_ci  // readability with nested diamonds.
64471cb0ef41Sopenharmony_ci
64481cb0ef41Sopenharmony_ci  auto if_not_positive = __ MakeDeferredLabel();
64491cb0ef41Sopenharmony_ci  auto if_greater_than_two_52 = __ MakeDeferredLabel();
64501cb0ef41Sopenharmony_ci  auto if_less_than_minus_two_52 = __ MakeDeferredLabel();
64511cb0ef41Sopenharmony_ci  auto if_zero = __ MakeDeferredLabel();
64521cb0ef41Sopenharmony_ci  auto done_temp3 = __ MakeLabel(MachineRepresentation::kFloat64);
64531cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineRepresentation::kFloat64);
64541cb0ef41Sopenharmony_ci
64551cb0ef41Sopenharmony_ci  Node* const zero = __ Float64Constant(0.0);
64561cb0ef41Sopenharmony_ci  Node* const two_52 = __ Float64Constant(4503599627370496.0E0);
64571cb0ef41Sopenharmony_ci  Node* const one = __ Float64Constant(1.0);
64581cb0ef41Sopenharmony_ci
64591cb0ef41Sopenharmony_ci  Node* check0 = __ Float64LessThan(zero, input);
64601cb0ef41Sopenharmony_ci  __ GotoIfNot(check0, &if_not_positive);
64611cb0ef41Sopenharmony_ci  {
64621cb0ef41Sopenharmony_ci    Node* check1 = __ Float64LessThanOrEqual(two_52, input);
64631cb0ef41Sopenharmony_ci    __ GotoIf(check1, &if_greater_than_two_52);
64641cb0ef41Sopenharmony_ci    {
64651cb0ef41Sopenharmony_ci      Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52);
64661cb0ef41Sopenharmony_ci      __ GotoIfNot(__ Float64LessThan(input, temp1), &done, temp1);
64671cb0ef41Sopenharmony_ci      __ Goto(&done, __ Float64Sub(temp1, one));
64681cb0ef41Sopenharmony_ci    }
64691cb0ef41Sopenharmony_ci
64701cb0ef41Sopenharmony_ci    __ Bind(&if_greater_than_two_52);
64711cb0ef41Sopenharmony_ci    __ Goto(&done, input);
64721cb0ef41Sopenharmony_ci  }
64731cb0ef41Sopenharmony_ci
64741cb0ef41Sopenharmony_ci  __ Bind(&if_not_positive);
64751cb0ef41Sopenharmony_ci  {
64761cb0ef41Sopenharmony_ci    Node* check1 = __ Float64Equal(input, zero);
64771cb0ef41Sopenharmony_ci    __ GotoIf(check1, &if_zero);
64781cb0ef41Sopenharmony_ci
64791cb0ef41Sopenharmony_ci    Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0);
64801cb0ef41Sopenharmony_ci    Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52);
64811cb0ef41Sopenharmony_ci    __ GotoIf(check2, &if_less_than_minus_two_52);
64821cb0ef41Sopenharmony_ci
64831cb0ef41Sopenharmony_ci    {
64841cb0ef41Sopenharmony_ci      Node* const minus_zero = __ Float64Constant(-0.0);
64851cb0ef41Sopenharmony_ci      Node* temp1 = __ Float64Sub(minus_zero, input);
64861cb0ef41Sopenharmony_ci      Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52);
64871cb0ef41Sopenharmony_ci      Node* check3 = __ Float64LessThan(temp1, temp2);
64881cb0ef41Sopenharmony_ci      __ GotoIfNot(check3, &done_temp3, temp2);
64891cb0ef41Sopenharmony_ci      __ Goto(&done_temp3, __ Float64Sub(temp2, one));
64901cb0ef41Sopenharmony_ci
64911cb0ef41Sopenharmony_ci      __ Bind(&done_temp3);
64921cb0ef41Sopenharmony_ci      Node* temp3 = done_temp3.PhiAt(0);
64931cb0ef41Sopenharmony_ci      __ Goto(&done, __ Float64Sub(minus_zero, temp3));
64941cb0ef41Sopenharmony_ci    }
64951cb0ef41Sopenharmony_ci    __ Bind(&if_less_than_minus_two_52);
64961cb0ef41Sopenharmony_ci    __ Goto(&done, input);
64971cb0ef41Sopenharmony_ci
64981cb0ef41Sopenharmony_ci    __ Bind(&if_zero);
64991cb0ef41Sopenharmony_ci    __ Goto(&done, input);
65001cb0ef41Sopenharmony_ci  }
65011cb0ef41Sopenharmony_ci  __ Bind(&done);
65021cb0ef41Sopenharmony_ci  return done.PhiAt(0);
65031cb0ef41Sopenharmony_ci}
65041cb0ef41Sopenharmony_ci
65051cb0ef41Sopenharmony_ciMaybe<Node*> EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node) {
65061cb0ef41Sopenharmony_ci  // Nothing to be done if a fast hardware instruction is available.
65071cb0ef41Sopenharmony_ci  if (machine()->Float64RoundTruncate().IsSupported()) {
65081cb0ef41Sopenharmony_ci    return Nothing<Node*>();
65091cb0ef41Sopenharmony_ci  }
65101cb0ef41Sopenharmony_ci
65111cb0ef41Sopenharmony_ci  Node* const input = node->InputAt(0);
65121cb0ef41Sopenharmony_ci  return Just(BuildFloat64RoundTruncate(input));
65131cb0ef41Sopenharmony_ci}
65141cb0ef41Sopenharmony_ci
65151cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerFindOrderedHashMapEntry(Node* node) {
65161cb0ef41Sopenharmony_ci  Node* table = NodeProperties::GetValueInput(node, 0);
65171cb0ef41Sopenharmony_ci  Node* key = NodeProperties::GetValueInput(node, 1);
65181cb0ef41Sopenharmony_ci
65191cb0ef41Sopenharmony_ci  {
65201cb0ef41Sopenharmony_ci    Callable const callable =
65211cb0ef41Sopenharmony_ci        Builtins::CallableFor(isolate(), Builtin::kFindOrderedHashMapEntry);
65221cb0ef41Sopenharmony_ci    Operator::Properties const properties = node->op()->properties();
65231cb0ef41Sopenharmony_ci    CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
65241cb0ef41Sopenharmony_ci    auto call_descriptor = Linkage::GetStubCallDescriptor(
65251cb0ef41Sopenharmony_ci        graph()->zone(), callable.descriptor(),
65261cb0ef41Sopenharmony_ci        callable.descriptor().GetStackParameterCount(), flags, properties);
65271cb0ef41Sopenharmony_ci    return __ Call(call_descriptor, __ HeapConstant(callable.code()), table,
65281cb0ef41Sopenharmony_ci                   key, __ NoContextConstant());
65291cb0ef41Sopenharmony_ci  }
65301cb0ef41Sopenharmony_ci}
65311cb0ef41Sopenharmony_ci
65321cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::ComputeUnseededHash(Node* value) {
65331cb0ef41Sopenharmony_ci  // See v8::internal::ComputeUnseededHash()
65341cb0ef41Sopenharmony_ci  value = __ Int32Add(__ Word32Xor(value, __ Int32Constant(0xFFFFFFFF)),
65351cb0ef41Sopenharmony_ci                      __ Word32Shl(value, __ Int32Constant(15)));
65361cb0ef41Sopenharmony_ci  value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(12)));
65371cb0ef41Sopenharmony_ci  value = __ Int32Add(value, __ Word32Shl(value, __ Int32Constant(2)));
65381cb0ef41Sopenharmony_ci  value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(4)));
65391cb0ef41Sopenharmony_ci  value = __ Int32Mul(value, __ Int32Constant(2057));
65401cb0ef41Sopenharmony_ci  value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(16)));
65411cb0ef41Sopenharmony_ci  value = __ Word32And(value, __ Int32Constant(0x3FFFFFFF));
65421cb0ef41Sopenharmony_ci  return value;
65431cb0ef41Sopenharmony_ci}
65441cb0ef41Sopenharmony_ci
65451cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerFindOrderedHashMapEntryForInt32Key(
65461cb0ef41Sopenharmony_ci    Node* node) {
65471cb0ef41Sopenharmony_ci  Node* table = NodeProperties::GetValueInput(node, 0);
65481cb0ef41Sopenharmony_ci  Node* key = NodeProperties::GetValueInput(node, 1);
65491cb0ef41Sopenharmony_ci
65501cb0ef41Sopenharmony_ci  // Compute the integer hash code.
65511cb0ef41Sopenharmony_ci  Node* hash = ChangeUint32ToUintPtr(ComputeUnseededHash(key));
65521cb0ef41Sopenharmony_ci
65531cb0ef41Sopenharmony_ci  Node* number_of_buckets = ChangeSmiToIntPtr(__ LoadField(
65541cb0ef41Sopenharmony_ci      AccessBuilder::ForOrderedHashMapOrSetNumberOfBuckets(), table));
65551cb0ef41Sopenharmony_ci  hash = __ WordAnd(hash, __ IntSub(number_of_buckets, __ IntPtrConstant(1)));
65561cb0ef41Sopenharmony_ci  Node* first_entry = ChangeSmiToIntPtr(__ Load(
65571cb0ef41Sopenharmony_ci      MachineType::TaggedSigned(), table,
65581cb0ef41Sopenharmony_ci      __ IntAdd(__ WordShl(hash, __ IntPtrConstant(kTaggedSizeLog2)),
65591cb0ef41Sopenharmony_ci                __ IntPtrConstant(OrderedHashMap::HashTableStartOffset() -
65601cb0ef41Sopenharmony_ci                                  kHeapObjectTag))));
65611cb0ef41Sopenharmony_ci
65621cb0ef41Sopenharmony_ci  auto loop = __ MakeLoopLabel(MachineType::PointerRepresentation());
65631cb0ef41Sopenharmony_ci  auto done = __ MakeLabel(MachineType::PointerRepresentation());
65641cb0ef41Sopenharmony_ci  __ Goto(&loop, first_entry);
65651cb0ef41Sopenharmony_ci  __ Bind(&loop);
65661cb0ef41Sopenharmony_ci  {
65671cb0ef41Sopenharmony_ci    Node* entry = loop.PhiAt(0);
65681cb0ef41Sopenharmony_ci    Node* check =
65691cb0ef41Sopenharmony_ci        __ IntPtrEqual(entry, __ IntPtrConstant(OrderedHashMap::kNotFound));
65701cb0ef41Sopenharmony_ci    __ GotoIf(check, &done, entry);
65711cb0ef41Sopenharmony_ci    entry = __ IntAdd(
65721cb0ef41Sopenharmony_ci        __ IntMul(entry, __ IntPtrConstant(OrderedHashMap::kEntrySize)),
65731cb0ef41Sopenharmony_ci        number_of_buckets);
65741cb0ef41Sopenharmony_ci
65751cb0ef41Sopenharmony_ci    Node* candidate_key = __ Load(
65761cb0ef41Sopenharmony_ci        MachineType::AnyTagged(), table,
65771cb0ef41Sopenharmony_ci        __ IntAdd(__ WordShl(entry, __ IntPtrConstant(kTaggedSizeLog2)),
65781cb0ef41Sopenharmony_ci                  __ IntPtrConstant(OrderedHashMap::HashTableStartOffset() -
65791cb0ef41Sopenharmony_ci                                    kHeapObjectTag)));
65801cb0ef41Sopenharmony_ci
65811cb0ef41Sopenharmony_ci    auto if_match = __ MakeLabel();
65821cb0ef41Sopenharmony_ci    auto if_notmatch = __ MakeLabel();
65831cb0ef41Sopenharmony_ci    auto if_notsmi = __ MakeDeferredLabel();
65841cb0ef41Sopenharmony_ci    __ GotoIfNot(ObjectIsSmi(candidate_key), &if_notsmi);
65851cb0ef41Sopenharmony_ci    __ Branch(__ Word32Equal(ChangeSmiToInt32(candidate_key), key), &if_match,
65861cb0ef41Sopenharmony_ci              &if_notmatch);
65871cb0ef41Sopenharmony_ci
65881cb0ef41Sopenharmony_ci    __ Bind(&if_notsmi);
65891cb0ef41Sopenharmony_ci    __ GotoIfNot(
65901cb0ef41Sopenharmony_ci        __ TaggedEqual(__ LoadField(AccessBuilder::ForMap(), candidate_key),
65911cb0ef41Sopenharmony_ci                       __ HeapNumberMapConstant()),
65921cb0ef41Sopenharmony_ci        &if_notmatch);
65931cb0ef41Sopenharmony_ci    __ Branch(__ Float64Equal(__ LoadField(AccessBuilder::ForHeapNumberValue(),
65941cb0ef41Sopenharmony_ci                                           candidate_key),
65951cb0ef41Sopenharmony_ci                              __ ChangeInt32ToFloat64(key)),
65961cb0ef41Sopenharmony_ci              &if_match, &if_notmatch);
65971cb0ef41Sopenharmony_ci
65981cb0ef41Sopenharmony_ci    __ Bind(&if_match);
65991cb0ef41Sopenharmony_ci    __ Goto(&done, entry);
66001cb0ef41Sopenharmony_ci
66011cb0ef41Sopenharmony_ci    __ Bind(&if_notmatch);
66021cb0ef41Sopenharmony_ci    {
66031cb0ef41Sopenharmony_ci      Node* next_entry = ChangeSmiToIntPtr(__ Load(
66041cb0ef41Sopenharmony_ci          MachineType::TaggedSigned(), table,
66051cb0ef41Sopenharmony_ci          __ IntAdd(
66061cb0ef41Sopenharmony_ci              __ WordShl(entry, __ IntPtrConstant(kTaggedSizeLog2)),
66071cb0ef41Sopenharmony_ci              __ IntPtrConstant(OrderedHashMap::HashTableStartOffset() +
66081cb0ef41Sopenharmony_ci                                OrderedHashMap::kChainOffset * kTaggedSize -
66091cb0ef41Sopenharmony_ci                                kHeapObjectTag))));
66101cb0ef41Sopenharmony_ci      __ Goto(&loop, next_entry);
66111cb0ef41Sopenharmony_ci    }
66121cb0ef41Sopenharmony_ci  }
66131cb0ef41Sopenharmony_ci
66141cb0ef41Sopenharmony_ci  __ Bind(&done);
66151cb0ef41Sopenharmony_ci  return done.PhiAt(0);
66161cb0ef41Sopenharmony_ci}
66171cb0ef41Sopenharmony_ci
66181cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::LowerDateNow(Node* node) {
66191cb0ef41Sopenharmony_ci  Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
66201cb0ef41Sopenharmony_ci  Runtime::FunctionId id = Runtime::kDateCurrentTime;
66211cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
66221cb0ef41Sopenharmony_ci      graph()->zone(), id, 0, properties, CallDescriptor::kNoFlags);
66231cb0ef41Sopenharmony_ci  return __ Call(call_descriptor, __ CEntryStubConstant(1),
66241cb0ef41Sopenharmony_ci                 __ ExternalConstant(ExternalReference::Create(id)),
66251cb0ef41Sopenharmony_ci                 __ Int32Constant(0), __ NoContextConstant());
66261cb0ef41Sopenharmony_ci}
66271cb0ef41Sopenharmony_ci
66281cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::TruncateWordToInt32(Node* value) {
66291cb0ef41Sopenharmony_ci  if (machine()->Is64()) {
66301cb0ef41Sopenharmony_ci    return __ TruncateInt64ToInt32(value);
66311cb0ef41Sopenharmony_ci  }
66321cb0ef41Sopenharmony_ci  return value;
66331cb0ef41Sopenharmony_ci}
66341cb0ef41Sopenharmony_ci
66351cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildIsStrongReference(Node* value) {
66361cb0ef41Sopenharmony_ci  return __ Word32Equal(
66371cb0ef41Sopenharmony_ci      __ Word32And(
66381cb0ef41Sopenharmony_ci          TruncateWordToInt32(__ BitcastTaggedToWordForTagAndSmiBits(value)),
66391cb0ef41Sopenharmony_ci          __ Int32Constant(kHeapObjectTagMask)),
66401cb0ef41Sopenharmony_ci      __ Int32Constant(kHeapObjectTag));
66411cb0ef41Sopenharmony_ci}
66421cb0ef41Sopenharmony_ci
66431cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::MakeWeakForComparison(Node* heap_object) {
66441cb0ef41Sopenharmony_ci  // TODO(gsathya): Specialize this for pointer compression.
66451cb0ef41Sopenharmony_ci  return __ BitcastWordToTagged(
66461cb0ef41Sopenharmony_ci      __ WordOr(__ BitcastTaggedToWord(heap_object),
66471cb0ef41Sopenharmony_ci                __ IntPtrConstant(kWeakHeapObjectTag)));
66481cb0ef41Sopenharmony_ci}
66491cb0ef41Sopenharmony_ci
66501cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildStrongReferenceFromWeakReference(
66511cb0ef41Sopenharmony_ci    Node* maybe_object) {
66521cb0ef41Sopenharmony_ci  return __ BitcastWordToTagged(
66531cb0ef41Sopenharmony_ci      __ WordAnd(__ BitcastMaybeObjectToWord(maybe_object),
66541cb0ef41Sopenharmony_ci                 __ IntPtrConstant(~kWeakHeapObjectMask)));
66551cb0ef41Sopenharmony_ci}
66561cb0ef41Sopenharmony_ci
66571cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildIsWeakReferenceTo(Node* maybe_object,
66581cb0ef41Sopenharmony_ci                                                      Node* value) {
66591cb0ef41Sopenharmony_ci  if (COMPRESS_POINTERS_BOOL) {
66601cb0ef41Sopenharmony_ci    return __ Word32Equal(
66611cb0ef41Sopenharmony_ci        __ Word32And(
66621cb0ef41Sopenharmony_ci            TruncateWordToInt32(__ BitcastMaybeObjectToWord(maybe_object)),
66631cb0ef41Sopenharmony_ci            __ Uint32Constant(~static_cast<uint32_t>(kWeakHeapObjectMask))),
66641cb0ef41Sopenharmony_ci        TruncateWordToInt32(__ BitcastTaggedToWord(value)));
66651cb0ef41Sopenharmony_ci  } else {
66661cb0ef41Sopenharmony_ci    return __ WordEqual(__ WordAnd(__ BitcastMaybeObjectToWord(maybe_object),
66671cb0ef41Sopenharmony_ci                                   __ IntPtrConstant(~kWeakHeapObjectMask)),
66681cb0ef41Sopenharmony_ci                        __ BitcastTaggedToWord(value));
66691cb0ef41Sopenharmony_ci  }
66701cb0ef41Sopenharmony_ci}
66711cb0ef41Sopenharmony_ci
66721cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildIsClearedWeakReference(Node* maybe_object) {
66731cb0ef41Sopenharmony_ci  return __ Word32Equal(
66741cb0ef41Sopenharmony_ci      TruncateWordToInt32(__ BitcastMaybeObjectToWord(maybe_object)),
66751cb0ef41Sopenharmony_ci      __ Int32Constant(kClearedWeakHeapObjectLower32));
66761cb0ef41Sopenharmony_ci}
66771cb0ef41Sopenharmony_ci
66781cb0ef41Sopenharmony_ci// Pass {bitfield} = {digit} = nullptr to construct the canoncial 0n BigInt.
66791cb0ef41Sopenharmony_ciNode* EffectControlLinearizer::BuildAllocateBigInt(Node* bitfield,
66801cb0ef41Sopenharmony_ci                                                   Node* digit) {
66811cb0ef41Sopenharmony_ci  DCHECK(machine()->Is64());
66821cb0ef41Sopenharmony_ci  DCHECK_EQ(bitfield == nullptr, digit == nullptr);
66831cb0ef41Sopenharmony_ci  static constexpr auto zero_bitfield =
66841cb0ef41Sopenharmony_ci      BigInt::SignBits::update(BigInt::LengthBits::encode(0), false);
66851cb0ef41Sopenharmony_ci
66861cb0ef41Sopenharmony_ci  Node* map = __ HeapConstant(factory()->bigint_map());
66871cb0ef41Sopenharmony_ci
66881cb0ef41Sopenharmony_ci  Node* result = __ Allocate(AllocationType::kYoung,
66891cb0ef41Sopenharmony_ci                             __ IntPtrConstant(BigInt::SizeFor(digit ? 1 : 0)));
66901cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForMap(), result, map);
66911cb0ef41Sopenharmony_ci  __ StoreField(AccessBuilder::ForBigIntBitfield(), result,
66921cb0ef41Sopenharmony_ci                bitfield ? bitfield : __ Int32Constant(zero_bitfield));
66931cb0ef41Sopenharmony_ci
66941cb0ef41Sopenharmony_ci  // BigInts have no padding on 64 bit architectures with pointer compression.
66951cb0ef41Sopenharmony_ci  if (BigInt::HasOptionalPadding()) {
66961cb0ef41Sopenharmony_ci    __ StoreField(AccessBuilder::ForBigIntOptionalPadding(), result,
66971cb0ef41Sopenharmony_ci                  __ IntPtrConstant(0));
66981cb0ef41Sopenharmony_ci  }
66991cb0ef41Sopenharmony_ci  if (digit) {
67001cb0ef41Sopenharmony_ci    __ StoreField(AccessBuilder::ForBigIntLeastSignificantDigit64(), result,
67011cb0ef41Sopenharmony_ci                  digit);
67021cb0ef41Sopenharmony_ci  }
67031cb0ef41Sopenharmony_ci  return result;
67041cb0ef41Sopenharmony_ci}
67051cb0ef41Sopenharmony_ci
67061cb0ef41Sopenharmony_ci#undef __
67071cb0ef41Sopenharmony_ci
67081cb0ef41Sopenharmony_civoid LinearizeEffectControl(JSGraph* graph, Schedule* schedule, Zone* temp_zone,
67091cb0ef41Sopenharmony_ci                            SourcePositionTable* source_positions,
67101cb0ef41Sopenharmony_ci                            NodeOriginTable* node_origins,
67111cb0ef41Sopenharmony_ci                            JSHeapBroker* broker) {
67121cb0ef41Sopenharmony_ci  JSGraphAssembler graph_assembler_(graph, temp_zone);
67131cb0ef41Sopenharmony_ci  EffectControlLinearizer linearizer(graph, schedule, &graph_assembler_,
67141cb0ef41Sopenharmony_ci                                     temp_zone, source_positions, node_origins,
67151cb0ef41Sopenharmony_ci                                     MaintainSchedule::kDiscard, broker);
67161cb0ef41Sopenharmony_ci  linearizer.Run();
67171cb0ef41Sopenharmony_ci}
67181cb0ef41Sopenharmony_ci
67191cb0ef41Sopenharmony_ci}  // namespace compiler
67201cb0ef41Sopenharmony_ci}  // namespace internal
67211cb0ef41Sopenharmony_ci}  // namespace v8
6722