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