14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/compiler/lcr_circuit_builder.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit_builder-inl.h"
194514f5e3Sopenharmony_ci#include "ecmascript/compiler/rt_call_signature.h"
204514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit_builder_helper.h"
214514f5e3Sopenharmony_ci
224514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu {
234514f5e3Sopenharmony_ci
244514f5e3Sopenharmony_ciGateRef CircuitBuilder::BinaryCmp(const GateMetaData* meta, GateRef left, GateRef right, const char* comment)
254514f5e3Sopenharmony_ci{
264514f5e3Sopenharmony_ci    return GetCircuit()->NewGate(meta, MachineType::I1, { left, right }, GateType::NJSValue(), comment);
274514f5e3Sopenharmony_ci}
284514f5e3Sopenharmony_ci
294514f5e3Sopenharmony_ciMachineType CircuitBuilder::GetMachineTypeFromVariableType(VariableType type)
304514f5e3Sopenharmony_ci{
314514f5e3Sopenharmony_ci    return type.GetMachineType();
324514f5e3Sopenharmony_ci}
334514f5e3Sopenharmony_ci
344514f5e3Sopenharmony_ciGateRef CircuitBuilder::Sqrt(GateRef param)
354514f5e3Sopenharmony_ci{
364514f5e3Sopenharmony_ci    return GetCircuit()->NewGate(circuit_->Sqrt(), MachineType::F64, {param}, GateType::DoubleType());
374514f5e3Sopenharmony_ci}
384514f5e3Sopenharmony_ci
394514f5e3Sopenharmony_ciGateRef CircuitBuilder::AddWithOverflow(GateRef left, GateRef right)
404514f5e3Sopenharmony_ci{
414514f5e3Sopenharmony_ci    return GetCircuit()->NewGate(circuit_->AddWithOverflow(), MachineType::I64, {left, right}, GateType::AnyType());
424514f5e3Sopenharmony_ci}
434514f5e3Sopenharmony_ci
444514f5e3Sopenharmony_ciGateRef CircuitBuilder::SubWithOverflow(GateRef left, GateRef right)
454514f5e3Sopenharmony_ci{
464514f5e3Sopenharmony_ci    return GetCircuit()->NewGate(circuit_->SubWithOverflow(), MachineType::I64, {left, right}, GateType::AnyType());
474514f5e3Sopenharmony_ci}
484514f5e3Sopenharmony_ci
494514f5e3Sopenharmony_ciGateRef CircuitBuilder::MulWithOverflow(GateRef left, GateRef right)
504514f5e3Sopenharmony_ci{
514514f5e3Sopenharmony_ci    return GetCircuit()->NewGate(circuit_->MulWithOverflow(), MachineType::I64, {left, right}, GateType::AnyType());
524514f5e3Sopenharmony_ci}
534514f5e3Sopenharmony_ci
544514f5e3Sopenharmony_ciGateRef CircuitBuilder::ExtractValue(MachineType mt, GateRef pointer, GateRef index)
554514f5e3Sopenharmony_ci{
564514f5e3Sopenharmony_ci    ASSERT(acc_.GetOpCode(index) == OpCode::CONSTANT);
574514f5e3Sopenharmony_ci    ASSERT(acc_.GetMachineType(index) == MachineType::I32);
584514f5e3Sopenharmony_ci    return GetCircuit()->NewGate(circuit_->ExtractValue(), mt, {pointer, index}, GateType::NJSValue());
594514f5e3Sopenharmony_ci}
604514f5e3Sopenharmony_ci
614514f5e3Sopenharmony_ciGateRef CircuitBuilder::ReadSp()
624514f5e3Sopenharmony_ci{
634514f5e3Sopenharmony_ci    return circuit_->NewGate(circuit_->ReadSp(), MachineType::I64, GateType::NJSValue());
644514f5e3Sopenharmony_ci}
654514f5e3Sopenharmony_ci
664514f5e3Sopenharmony_ciMachineType CircuitBuilder::GetMachineTypeOfValueType(ValueType type)
674514f5e3Sopenharmony_ci{
684514f5e3Sopenharmony_ci    switch (type) {
694514f5e3Sopenharmony_ci        case ValueType::BOOL:
704514f5e3Sopenharmony_ci            return MachineType::I1;
714514f5e3Sopenharmony_ci        case ValueType::INT32:
724514f5e3Sopenharmony_ci        case ValueType::UINT32:
734514f5e3Sopenharmony_ci            return MachineType::I32;
744514f5e3Sopenharmony_ci        case ValueType::FLOAT64:
754514f5e3Sopenharmony_ci            return MachineType::F64;
764514f5e3Sopenharmony_ci        case ValueType::TAGGED_BOOLEAN:
774514f5e3Sopenharmony_ci        case ValueType::TAGGED_INT:
784514f5e3Sopenharmony_ci        case ValueType::TAGGED_DOUBLE:
794514f5e3Sopenharmony_ci        case ValueType::TAGGED_NUMBER:
804514f5e3Sopenharmony_ci        case ValueType::TAGGED_NULL:
814514f5e3Sopenharmony_ci        case ValueType::CHAR:
824514f5e3Sopenharmony_ci        case ValueType::ECMA_STRING:
834514f5e3Sopenharmony_ci        case ValueType::UNDEFINED:
844514f5e3Sopenharmony_ci        case ValueType::HOLE_INT:
854514f5e3Sopenharmony_ci        case ValueType::HOLE_DOUBLE:
864514f5e3Sopenharmony_ci            return MachineType::I64;
874514f5e3Sopenharmony_ci        default:
884514f5e3Sopenharmony_ci            UNREACHABLE();
894514f5e3Sopenharmony_ci            break;
904514f5e3Sopenharmony_ci    }
914514f5e3Sopenharmony_ci    return MachineType::NOVALUE;
924514f5e3Sopenharmony_ci}
934514f5e3Sopenharmony_ci
944514f5e3Sopenharmony_ciGateRef CircuitBuilder::BinaryArithmetic(const GateMetaData* meta, MachineType machineType,
954514f5e3Sopenharmony_ci                                         GateRef left, GateRef right, GateType gateType, const char* comment)
964514f5e3Sopenharmony_ci{
974514f5e3Sopenharmony_ci    auto circuit = GetCircuit();
984514f5e3Sopenharmony_ci    if (gateType == GateType::Empty()) {
994514f5e3Sopenharmony_ci        gateType = acc_.GetGateType(left);
1004514f5e3Sopenharmony_ci    }
1014514f5e3Sopenharmony_ci    return circuit->NewGate(meta, machineType, { left, right }, gateType, comment);
1024514f5e3Sopenharmony_ci}
1034514f5e3Sopenharmony_ci
1044514f5e3Sopenharmony_ciGateRef CircuitBuilder::Alloca(size_t size)
1054514f5e3Sopenharmony_ci{
1064514f5e3Sopenharmony_ci    return GetCircuit()->NewGate(circuit_->Alloca(size), MachineType::ARCH, GateType::NJSValue());
1074514f5e3Sopenharmony_ci}
1084514f5e3Sopenharmony_ci
1094514f5e3Sopenharmony_ci// memory
1104514f5e3Sopenharmony_civoid CircuitBuilder::Store(VariableType type, GateRef glue, GateRef base, GateRef offset, GateRef value,
1114514f5e3Sopenharmony_ci                           MemoryAttribute mAttr)
1124514f5e3Sopenharmony_ci{
1134514f5e3Sopenharmony_ci    auto label = GetCurrentLabel();
1144514f5e3Sopenharmony_ci    auto depend = label->GetDepend();
1154514f5e3Sopenharmony_ci    if (mAttr.GetBarrier() == MemoryAttribute::Barrier::UNKNOWN_BARRIER && acc_.IsConstant(value)) {
1164514f5e3Sopenharmony_ci        mAttr.SetBarrier(MemoryAttribute::Barrier::NO_BARRIER);
1174514f5e3Sopenharmony_ci    }
1184514f5e3Sopenharmony_ci    auto bit = LoadStoreAccessor::ToValue(mAttr);
1194514f5e3Sopenharmony_ci    GateRef result = GetCircuit()->NewGate(circuit_->Store(bit),
1204514f5e3Sopenharmony_ci        MachineType::NOVALUE, { depend, glue, base, offset, value }, type.GetGateType());
1214514f5e3Sopenharmony_ci    label->SetDepend(result);
1224514f5e3Sopenharmony_ci}
1234514f5e3Sopenharmony_ci
1244514f5e3Sopenharmony_civoid CircuitBuilder::StoreWithoutBarrier(VariableType type, GateRef addr, GateRef value, MemoryAttribute mAttr)
1254514f5e3Sopenharmony_ci{
1264514f5e3Sopenharmony_ci    auto label = GetCurrentLabel();
1274514f5e3Sopenharmony_ci    auto depend = label->GetDepend();
1284514f5e3Sopenharmony_ci    auto bit = LoadStoreAccessor::ToValue(mAttr);
1294514f5e3Sopenharmony_ci    GateRef result = GetCircuit()->NewGate(circuit_->StoreWithoutBarrier(bit),
1304514f5e3Sopenharmony_ci        MachineType::NOVALUE, { depend, addr, value }, type.GetGateType());
1314514f5e3Sopenharmony_ci    label->SetDepend(result);
1324514f5e3Sopenharmony_ci}
1334514f5e3Sopenharmony_ci
1344514f5e3Sopenharmony_ci// memory
1354514f5e3Sopenharmony_ciGateRef CircuitBuilder::Load(VariableType type, GateRef base, GateRef offset, MemoryAttribute mAttr)
1364514f5e3Sopenharmony_ci{
1374514f5e3Sopenharmony_ci    auto label = GetCurrentLabel();
1384514f5e3Sopenharmony_ci    auto depend = label->GetDepend();
1394514f5e3Sopenharmony_ci    GateRef val = PtrAdd(base, offset);
1404514f5e3Sopenharmony_ci    auto bits = LoadStoreAccessor::ToValue(mAttr);
1414514f5e3Sopenharmony_ci    GateRef result = GetCircuit()->NewGate(GetCircuit()->Load(bits), type.GetMachineType(),
1424514f5e3Sopenharmony_ci                                           { depend, val }, type.GetGateType());
1434514f5e3Sopenharmony_ci    label->SetDepend(result);
1444514f5e3Sopenharmony_ci    return result;
1454514f5e3Sopenharmony_ci}
1464514f5e3Sopenharmony_ci
1474514f5e3Sopenharmony_ciGateRef CircuitBuilder::Load(VariableType type, GateRef base, GateRef offset, GateRef depend,
1484514f5e3Sopenharmony_ci                             MemoryAttribute mAttr)
1494514f5e3Sopenharmony_ci{
1504514f5e3Sopenharmony_ci    GateRef val = PtrAdd(base, offset);
1514514f5e3Sopenharmony_ci    auto bits = LoadStoreAccessor::ToValue(mAttr);
1524514f5e3Sopenharmony_ci    GateRef result = GetCircuit()->NewGate(GetCircuit()->Load(bits), type.GetMachineType(),
1534514f5e3Sopenharmony_ci                                           { depend, val }, type.GetGateType());
1544514f5e3Sopenharmony_ci    return result;
1554514f5e3Sopenharmony_ci}
1564514f5e3Sopenharmony_ci
1574514f5e3Sopenharmony_ciGateRef CircuitBuilder::Load(VariableType type, GateRef addr, MemoryAttribute mAttr)
1584514f5e3Sopenharmony_ci{
1594514f5e3Sopenharmony_ci    auto label = GetCurrentLabel();
1604514f5e3Sopenharmony_ci    auto depend = label->GetDepend();
1614514f5e3Sopenharmony_ci    auto bits = LoadStoreAccessor::ToValue(mAttr);
1624514f5e3Sopenharmony_ci    GateRef result = GetCircuit()->NewGate(GetCircuit()->Load(bits), type.GetMachineType(),
1634514f5e3Sopenharmony_ci                                           { depend, addr }, type.GetGateType());
1644514f5e3Sopenharmony_ci    label->SetDepend(result);
1654514f5e3Sopenharmony_ci    return result;
1664514f5e3Sopenharmony_ci}
1674514f5e3Sopenharmony_ci
1684514f5e3Sopenharmony_ciGateRef CircuitBuilder::DoubleTrunc(GateRef gate, GateRef value, const char* comment)
1694514f5e3Sopenharmony_ci{
1704514f5e3Sopenharmony_ci    if (GetCompilationConfig()->IsAArch64()) {
1714514f5e3Sopenharmony_ci        return DoubleTrunc(value, comment);
1724514f5e3Sopenharmony_ci    }
1734514f5e3Sopenharmony_ci
1744514f5e3Sopenharmony_ci    GateRef glue = acc_.GetGlueFromArgList();
1754514f5e3Sopenharmony_ci    return CallNGCRuntime(glue, RTSTUB_ID(FloatTrunc), Gate::InvalidGateRef, {value}, gate, comment);
1764514f5e3Sopenharmony_ci}
1774514f5e3Sopenharmony_ci
1784514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetDoubleOfTNumber(GateRef x)
1794514f5e3Sopenharmony_ci{
1804514f5e3Sopenharmony_ci    Label subentry(env_);
1814514f5e3Sopenharmony_ci    SubCfgEntry(&subentry);
1824514f5e3Sopenharmony_ci    Label isInt(env_);
1834514f5e3Sopenharmony_ci    Label isDouble(env_);
1844514f5e3Sopenharmony_ci    Label exit(env_);
1854514f5e3Sopenharmony_ci    DEFVALUE(result, env_, VariableType::FLOAT64(), Double(0));
1864514f5e3Sopenharmony_ci    BRANCH_CIR2(TaggedIsInt(x), &isInt, &isDouble);
1874514f5e3Sopenharmony_ci    Bind(&isInt);
1884514f5e3Sopenharmony_ci    {
1894514f5e3Sopenharmony_ci        result = ChangeInt32ToFloat64(GetInt32OfTInt(x));
1904514f5e3Sopenharmony_ci        Jump(&exit);
1914514f5e3Sopenharmony_ci    }
1924514f5e3Sopenharmony_ci    Bind(&isDouble);
1934514f5e3Sopenharmony_ci    {
1944514f5e3Sopenharmony_ci        result = GetDoubleOfTDouble(x);
1954514f5e3Sopenharmony_ci        Jump(&exit);
1964514f5e3Sopenharmony_ci    }
1974514f5e3Sopenharmony_ci    Bind(&exit);
1984514f5e3Sopenharmony_ci    GateRef ret = *result;
1994514f5e3Sopenharmony_ci    SubCfgExit();
2004514f5e3Sopenharmony_ci    return ret;
2014514f5e3Sopenharmony_ci}
2024514f5e3Sopenharmony_ci
2034514f5e3Sopenharmony_ciGateRef CircuitBuilder::DoubleToInt(GateRef x, Label *exit)
2044514f5e3Sopenharmony_ci{
2054514f5e3Sopenharmony_ci    Label overflow(env_);
2064514f5e3Sopenharmony_ci
2074514f5e3Sopenharmony_ci    GateRef xInt = ChangeFloat64ToInt32(x);
2084514f5e3Sopenharmony_ci    DEFVALUE(result, env_, VariableType::INT32(), xInt);
2094514f5e3Sopenharmony_ci
2104514f5e3Sopenharmony_ci    GateRef xInt64 = CastDoubleToInt64(x);
2114514f5e3Sopenharmony_ci    // exp = (u64 & DOUBLE_EXPONENT_MASK) >> DOUBLE_SIGNIFICAND_SIZE - DOUBLE_EXPONENT_BIAS
2124514f5e3Sopenharmony_ci    GateRef exp = Int64And(xInt64, Int64(base::DOUBLE_EXPONENT_MASK));
2134514f5e3Sopenharmony_ci    exp = TruncInt64ToInt32(Int64LSR(exp, Int64(base::DOUBLE_SIGNIFICAND_SIZE)));
2144514f5e3Sopenharmony_ci    exp = Int32Sub(exp, Int32(base::DOUBLE_EXPONENT_BIAS));
2154514f5e3Sopenharmony_ci    GateRef bits = Int32(base::INT32_BITS - 1);
2164514f5e3Sopenharmony_ci    // exp < 32 - 1
2174514f5e3Sopenharmony_ci    BRANCH_CIR2(Int32LessThan(exp, bits), exit, &overflow);
2184514f5e3Sopenharmony_ci
2194514f5e3Sopenharmony_ci    Bind(&overflow);
2204514f5e3Sopenharmony_ci    {
2214514f5e3Sopenharmony_ci        result = CallNGCRuntime(acc_.GetGlueFromArgList(), RTSTUB_ID(DoubleToInt),
2224514f5e3Sopenharmony_ci                                Circuit::NullGate(), { x, IntPtr(base::INT32_BITS) }, Circuit::NullGate());
2234514f5e3Sopenharmony_ci        Jump(exit);
2244514f5e3Sopenharmony_ci    }
2254514f5e3Sopenharmony_ci    Bind(exit);
2264514f5e3Sopenharmony_ci    auto ret = *result;
2274514f5e3Sopenharmony_ci    return ret;
2284514f5e3Sopenharmony_ci}
2294514f5e3Sopenharmony_ci
2304514f5e3Sopenharmony_ciGateRef CircuitBuilder::DoubleToInt(GateRef glue, GateRef x, size_t typeBits)
2314514f5e3Sopenharmony_ci{
2324514f5e3Sopenharmony_ci    Label entry(env_);
2334514f5e3Sopenharmony_ci    env_->SubCfgEntry(&entry);
2344514f5e3Sopenharmony_ci    Label exit(env_);
2354514f5e3Sopenharmony_ci    Label overflow(env_);
2364514f5e3Sopenharmony_ci
2374514f5e3Sopenharmony_ci    GateRef xInt = ChangeFloat64ToInt32(x);
2384514f5e3Sopenharmony_ci    DEFVALUE(result, env_, VariableType::INT32(), xInt);
2394514f5e3Sopenharmony_ci
2404514f5e3Sopenharmony_ci    if (env_->IsAmd64()) {
2414514f5e3Sopenharmony_ci        // 0x80000000: amd64 overflow return value
2424514f5e3Sopenharmony_ci        BRANCH_CIR2(Int32Equal(xInt, Int32(0x80000000)), &overflow, &exit);
2434514f5e3Sopenharmony_ci    } else {
2444514f5e3Sopenharmony_ci        GateRef xInt64 = CastDoubleToInt64(x);
2454514f5e3Sopenharmony_ci        // exp = (u64 & DOUBLE_EXPONENT_MASK) >> DOUBLE_SIGNIFICAND_SIZE - DOUBLE_EXPONENT_BIAS
2464514f5e3Sopenharmony_ci        GateRef exp = Int64And(xInt64, Int64(base::DOUBLE_EXPONENT_MASK));
2474514f5e3Sopenharmony_ci        exp = TruncInt64ToInt32(Int64LSR(exp, Int64(base::DOUBLE_SIGNIFICAND_SIZE)));
2484514f5e3Sopenharmony_ci        exp = Int32Sub(exp, Int32(base::DOUBLE_EXPONENT_BIAS));
2494514f5e3Sopenharmony_ci        GateRef bits = Int32(typeBits - 1);
2504514f5e3Sopenharmony_ci        // exp < 32 - 1
2514514f5e3Sopenharmony_ci        BRANCH_CIR2(Int32LessThan(exp, bits), &exit, &overflow);
2524514f5e3Sopenharmony_ci    }
2534514f5e3Sopenharmony_ci    Bind(&overflow);
2544514f5e3Sopenharmony_ci    {
2554514f5e3Sopenharmony_ci        result = CallNGCRuntime(glue, RTSTUB_ID(DoubleToInt), Circuit::NullGate(), { x, IntPtr(typeBits) },
2564514f5e3Sopenharmony_ci                                Circuit::NullGate());
2574514f5e3Sopenharmony_ci        Jump(&exit);
2584514f5e3Sopenharmony_ci    }
2594514f5e3Sopenharmony_ci    Bind(&exit);
2604514f5e3Sopenharmony_ci    auto ret = *result;
2614514f5e3Sopenharmony_ci    env_->SubCfgExit();
2624514f5e3Sopenharmony_ci    return ret;
2634514f5e3Sopenharmony_ci}
2644514f5e3Sopenharmony_ci
2654514f5e3Sopenharmony_ciGateRef CircuitBuilder::DoubleCheckINFInRangeInt32(GateRef x)
2664514f5e3Sopenharmony_ci{
2674514f5e3Sopenharmony_ci    Label entry(env_);
2684514f5e3Sopenharmony_ci    env_->SubCfgEntry(&entry);
2694514f5e3Sopenharmony_ci    Label exit(env_);
2704514f5e3Sopenharmony_ci    Label isInfinity(env_);
2714514f5e3Sopenharmony_ci    Label positiveInf(env_);
2724514f5e3Sopenharmony_ci    Label negativeInf(env_);
2734514f5e3Sopenharmony_ci
2744514f5e3Sopenharmony_ci    DEFVALUE(result, env_, VariableType::INT32(), DoubleInRangeInt32(x));
2754514f5e3Sopenharmony_ci    GateRef Max = Double(INT32_MAX);
2764514f5e3Sopenharmony_ci    GateRef Min = Double(INT32_MIN);
2774514f5e3Sopenharmony_ci    GateRef pInfinity = Double(base::POSITIVE_INFINITY);
2784514f5e3Sopenharmony_ci    Branch(DoubleIsINF(x), &isInfinity, &exit);
2794514f5e3Sopenharmony_ci    Bind(&isInfinity);
2804514f5e3Sopenharmony_ci    {
2814514f5e3Sopenharmony_ci        Branch(DoubleEqual(x, pInfinity), &positiveInf, &negativeInf);
2824514f5e3Sopenharmony_ci        Bind(&positiveInf);
2834514f5e3Sopenharmony_ci        {
2844514f5e3Sopenharmony_ci            result = ChangeFloat64ToInt32(Max);
2854514f5e3Sopenharmony_ci            Jump(&exit);
2864514f5e3Sopenharmony_ci        }
2874514f5e3Sopenharmony_ci        Bind(&negativeInf);
2884514f5e3Sopenharmony_ci        {
2894514f5e3Sopenharmony_ci            result = ChangeFloat64ToInt32(Min);
2904514f5e3Sopenharmony_ci            Jump(&exit);
2914514f5e3Sopenharmony_ci        }
2924514f5e3Sopenharmony_ci    }
2934514f5e3Sopenharmony_ci    Bind(&exit);
2944514f5e3Sopenharmony_ci    auto ret = *result;
2954514f5e3Sopenharmony_ci    env_->SubCfgExit();
2964514f5e3Sopenharmony_ci    return ret;
2974514f5e3Sopenharmony_ci}
2984514f5e3Sopenharmony_ci
2994514f5e3Sopenharmony_ciGateRef CircuitBuilder::DoubleInRangeInt32(GateRef x)
3004514f5e3Sopenharmony_ci{
3014514f5e3Sopenharmony_ci    Label entry(env_);
3024514f5e3Sopenharmony_ci    env_->SubCfgEntry(&entry);
3034514f5e3Sopenharmony_ci    Label exit(env_);
3044514f5e3Sopenharmony_ci    Label overflow(env_);
3054514f5e3Sopenharmony_ci    Label checkUnderflow(env_);
3064514f5e3Sopenharmony_ci    Label underflow(env_);
3074514f5e3Sopenharmony_ci
3084514f5e3Sopenharmony_ci    DEFVALUE(result, env_, VariableType::INT32(), ChangeFloat64ToInt32(x));
3094514f5e3Sopenharmony_ci    GateRef Max = Double(INT32_MAX);
3104514f5e3Sopenharmony_ci    GateRef Min = Double(INT32_MIN);
3114514f5e3Sopenharmony_ci    Branch(DoubleGreaterThan(x, Max), &overflow, &checkUnderflow);
3124514f5e3Sopenharmony_ci    Bind(&overflow);
3134514f5e3Sopenharmony_ci    {
3144514f5e3Sopenharmony_ci        result = ChangeFloat64ToInt32(Max);
3154514f5e3Sopenharmony_ci        Jump(&exit);
3164514f5e3Sopenharmony_ci    }
3174514f5e3Sopenharmony_ci    Bind(&checkUnderflow);
3184514f5e3Sopenharmony_ci    {
3194514f5e3Sopenharmony_ci        Branch(DoubleLessThan(x, Min), &underflow, &exit);
3204514f5e3Sopenharmony_ci        Bind(&underflow);
3214514f5e3Sopenharmony_ci        {
3224514f5e3Sopenharmony_ci            result = ChangeFloat64ToInt32(Min);
3234514f5e3Sopenharmony_ci            Jump(&exit);
3244514f5e3Sopenharmony_ci        }
3254514f5e3Sopenharmony_ci    }
3264514f5e3Sopenharmony_ci    Bind(&exit);
3274514f5e3Sopenharmony_ci    auto ret = *result;
3284514f5e3Sopenharmony_ci    env_->SubCfgExit();
3294514f5e3Sopenharmony_ci    return ret;
3304514f5e3Sopenharmony_ci}
3314514f5e3Sopenharmony_ci}
332