14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2023 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#include "ecmascript/compiler/mcr_lowering.h" 164514f5e3Sopenharmony_ci#include "ecmascript/compiler/argument_accessor.h" 174514f5e3Sopenharmony_ci#include "ecmascript/compiler/bytecodes.h" 184514f5e3Sopenharmony_ci#include "ecmascript/compiler/share_gate_meta_data.h" 194514f5e3Sopenharmony_ci#include "ecmascript/compiler/share_opcodes.h" 204514f5e3Sopenharmony_ci#include "ecmascript/compiler/pgo_type/pgo_type_manager.h" 214514f5e3Sopenharmony_ci#include "ecmascript/global_env.h" 224514f5e3Sopenharmony_ci#include "ecmascript/js_function.h" 234514f5e3Sopenharmony_ci#include "ecmascript/js_hclass.h" 244514f5e3Sopenharmony_ci#include "ecmascript/js_thread.h" 254514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/program_object.h" 264514f5e3Sopenharmony_ci#include "ecmascript/message_string.h" 274514f5e3Sopenharmony_ci 284514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 294514f5e3Sopenharmony_ci 304514f5e3Sopenharmony_ciGateRef MCRLowering::VisitGate(GateRef gate) 314514f5e3Sopenharmony_ci{ 324514f5e3Sopenharmony_ci auto op = acc_.GetOpCode(gate); 334514f5e3Sopenharmony_ci switch (op) { 344514f5e3Sopenharmony_ci case OpCode::STATE_SPLIT: 354514f5e3Sopenharmony_ci DeleteStateSplit(gate); 364514f5e3Sopenharmony_ci break; 374514f5e3Sopenharmony_ci case OpCode::ARRAY_GUARDIAN_CHECK: 384514f5e3Sopenharmony_ci LowerArrayGuardianCheck(gate); 394514f5e3Sopenharmony_ci break; 404514f5e3Sopenharmony_ci case OpCode::HCLASS_STABLE_ARRAY_CHECK: 414514f5e3Sopenharmony_ci LowerHClassStableArrayCheck(gate); 424514f5e3Sopenharmony_ci break; 434514f5e3Sopenharmony_ci case OpCode::HEAP_OBJECT_CHECK: 444514f5e3Sopenharmony_ci LowerHeapObjectCheck(gate); 454514f5e3Sopenharmony_ci break; 464514f5e3Sopenharmony_ci case OpCode::LOAD_CONST_OFFSET: 474514f5e3Sopenharmony_ci LowerLoadConstOffset(gate); 484514f5e3Sopenharmony_ci break; 494514f5e3Sopenharmony_ci case OpCode::LOAD_HCLASS_FROM_CONSTPOOL: 504514f5e3Sopenharmony_ci LowerLoadHClassFromConstpool(gate); 514514f5e3Sopenharmony_ci break; 524514f5e3Sopenharmony_ci case OpCode::STORE_CONST_OFFSET: 534514f5e3Sopenharmony_ci LowerStoreConstOffset(gate); 544514f5e3Sopenharmony_ci break; 554514f5e3Sopenharmony_ci case OpCode::CONVERT_HOLE_AS_UNDEFINED: 564514f5e3Sopenharmony_ci LowerConvertHoleAsUndefined(gate); 574514f5e3Sopenharmony_ci break; 584514f5e3Sopenharmony_ci case OpCode::GET_GLOBAL_ENV: 594514f5e3Sopenharmony_ci LowerGetGlobalEnv(gate); 604514f5e3Sopenharmony_ci break; 614514f5e3Sopenharmony_ci case OpCode::GET_GLOBAL_ENV_OBJ: 624514f5e3Sopenharmony_ci LowerGetGlobalEnvObj(gate); 634514f5e3Sopenharmony_ci break; 644514f5e3Sopenharmony_ci case OpCode::GET_GLOBAL_ENV_OBJ_HCLASS: 654514f5e3Sopenharmony_ci LowerGetGlobalEnvObjHClass(gate); 664514f5e3Sopenharmony_ci break; 674514f5e3Sopenharmony_ci case OpCode::GET_GLOBAL_CONSTANT_VALUE: 684514f5e3Sopenharmony_ci LowerGetGlobalConstantValue(gate); 694514f5e3Sopenharmony_ci break; 704514f5e3Sopenharmony_ci case OpCode::INT32_CHECK_RIGHT_IS_ZERO: 714514f5e3Sopenharmony_ci LowerInt32CheckRightIsZero(gate); 724514f5e3Sopenharmony_ci break; 734514f5e3Sopenharmony_ci case OpCode::REMAINDER_IS_NEGATIVE_ZERO: 744514f5e3Sopenharmony_ci LowerRemainderIsNegativeZero(gate); 754514f5e3Sopenharmony_ci break; 764514f5e3Sopenharmony_ci case OpCode::FLOAT64_CHECK_RIGHT_IS_ZERO: 774514f5e3Sopenharmony_ci LowerFloat64CheckRightIsZero(gate); 784514f5e3Sopenharmony_ci break; 794514f5e3Sopenharmony_ci case OpCode::VALUE_CHECK_NEG_OVERFLOW: 804514f5e3Sopenharmony_ci LowerValueCheckNegOverflow(gate); 814514f5e3Sopenharmony_ci break; 824514f5e3Sopenharmony_ci case OpCode::OVERFLOW_CHECK: 834514f5e3Sopenharmony_ci LowerOverflowCheck(gate); 844514f5e3Sopenharmony_ci break; 854514f5e3Sopenharmony_ci case OpCode::INT32_UNSIGNED_UPPER_BOUND_CHECK: 864514f5e3Sopenharmony_ci LowerInt32UnsignedUpperBoundCheck(gate); 874514f5e3Sopenharmony_ci break; 884514f5e3Sopenharmony_ci case OpCode::INT32_DIV_WITH_CHECK: 894514f5e3Sopenharmony_ci LowerInt32DivWithCheck(gate); 904514f5e3Sopenharmony_ci break; 914514f5e3Sopenharmony_ci case OpCode::LEX_VAR_IS_HOLE_CHECK: 924514f5e3Sopenharmony_ci LowerLexVarIsHoleCheck(gate); 934514f5e3Sopenharmony_ci break; 944514f5e3Sopenharmony_ci case OpCode::IS_UNDEFINED_OR_HOLE_CHECK: 954514f5e3Sopenharmony_ci LowerIsUndefinedOrHoleCheck(gate); 964514f5e3Sopenharmony_ci break; 974514f5e3Sopenharmony_ci case OpCode::IS_NOT_UNDEFINED_OR_HOLE_CHECK: 984514f5e3Sopenharmony_ci LowerIsNotUndefinedOrHoleCheck(gate); 994514f5e3Sopenharmony_ci break; 1004514f5e3Sopenharmony_ci case OpCode::IS_DATA_VIEW_CHECK: 1014514f5e3Sopenharmony_ci LowerIsDataViewCheck(gate); 1024514f5e3Sopenharmony_ci break; 1034514f5e3Sopenharmony_ci case OpCode::STORE_MEMORY: 1044514f5e3Sopenharmony_ci LowerStoreMemory(gate); 1054514f5e3Sopenharmony_ci break; 1064514f5e3Sopenharmony_ci case OpCode::CHECK_AND_CONVERT: 1074514f5e3Sopenharmony_ci LowerCheckAndConvert(gate); 1084514f5e3Sopenharmony_ci break; 1094514f5e3Sopenharmony_ci case OpCode::TAGGED_IS_HEAP_OBJECT: 1104514f5e3Sopenharmony_ci LowerTaggedIsHeapObject(gate); 1114514f5e3Sopenharmony_ci break; 1124514f5e3Sopenharmony_ci case OpCode::IS_MARKER_CELL_VALID: 1134514f5e3Sopenharmony_ci LowerIsMarkerCellValid(gate); 1144514f5e3Sopenharmony_ci break; 1154514f5e3Sopenharmony_ci case OpCode::IS_SPECIFIC_OBJECT_TYPE: 1164514f5e3Sopenharmony_ci LowerIsSpecificObjectType(gate); 1174514f5e3Sopenharmony_ci break; 1184514f5e3Sopenharmony_ci case OpCode::MIGRATE_FROM_HEAPVALUE_TO_RAWVALUE: 1194514f5e3Sopenharmony_ci LowerMigrateFromHeapValueToRawValue(gate); 1204514f5e3Sopenharmony_ci break; 1214514f5e3Sopenharmony_ci case OpCode::MIGRATE_FROM_RAWVALUE_TO_HEAPVALUES: 1224514f5e3Sopenharmony_ci LowerMigrateFromRawValueToHeapValues(gate); 1234514f5e3Sopenharmony_ci break; 1244514f5e3Sopenharmony_ci case OpCode::MIGRATE_FROM_HOLEINT_TO_HOLENUMBER: 1254514f5e3Sopenharmony_ci LowerMigrateFromHoleIntToHoleNumber(gate); 1264514f5e3Sopenharmony_ci break; 1274514f5e3Sopenharmony_ci case OpCode::MIGRATE_FROM_HOLENUMBER_TO_HOLEINT: 1284514f5e3Sopenharmony_ci LowerMigrateFromHoleNumberToHoleInt(gate); 1294514f5e3Sopenharmony_ci break; 1304514f5e3Sopenharmony_ci case OpCode::HEAP_OBJECT_IS_ECMA_OBJECT: 1314514f5e3Sopenharmony_ci LowerHeapObjectIsEcmaObject(gate); 1324514f5e3Sopenharmony_ci break; 1334514f5e3Sopenharmony_ci case OpCode::IS_CALLABLE_CHECK: 1344514f5e3Sopenharmony_ci LowerIsCallableCheck(gate); 1354514f5e3Sopenharmony_ci break; 1364514f5e3Sopenharmony_ci default: 1374514f5e3Sopenharmony_ci break; 1384514f5e3Sopenharmony_ci } 1394514f5e3Sopenharmony_ci return Circuit::NullGate(); 1404514f5e3Sopenharmony_ci} 1414514f5e3Sopenharmony_ci 1424514f5e3Sopenharmony_civoid MCRLowering::LowerConvertHoleAsUndefined(GateRef gate) 1434514f5e3Sopenharmony_ci{ 1444514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 1454514f5e3Sopenharmony_ci 1464514f5e3Sopenharmony_ci Label returnUndefined(&builder_); 1474514f5e3Sopenharmony_ci Label exit(&builder_); 1484514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 0); 1494514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), receiver); 1504514f5e3Sopenharmony_ci 1514514f5e3Sopenharmony_ci builder_.Branch(builder_.TaggedIsHole(*result), &returnUndefined, &exit, 1, BranchWeight::DEOPT_WEIGHT, 1524514f5e3Sopenharmony_ci "holeCheck"); 1534514f5e3Sopenharmony_ci builder_.Bind(&returnUndefined); 1544514f5e3Sopenharmony_ci { 1554514f5e3Sopenharmony_ci result = builder_.UndefineConstant(); 1564514f5e3Sopenharmony_ci builder_.Jump(&exit); 1574514f5e3Sopenharmony_ci } 1584514f5e3Sopenharmony_ci builder_.Bind(&exit); 1594514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result); 1604514f5e3Sopenharmony_ci} 1614514f5e3Sopenharmony_ci 1624514f5e3Sopenharmony_civoid MCRLowering::LowerLoadConstOffset(GateRef gate) 1634514f5e3Sopenharmony_ci{ 1644514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 1654514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 0); 1664514f5e3Sopenharmony_ci GateRef offset = builder_.IntPtr(acc_.GetOffset(gate)); 1674514f5e3Sopenharmony_ci VariableType type = VariableType(acc_.GetMachineType(gate), acc_.GetGateType(gate)); 1684514f5e3Sopenharmony_ci GateRef result = builder_.Load(type, receiver, offset, acc_.GetMemoryAttribute(gate)); 1694514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, Circuit::NullGate(), builder_.GetDepend(), result); 1704514f5e3Sopenharmony_ci} 1714514f5e3Sopenharmony_ci 1724514f5e3Sopenharmony_civoid MCRLowering::LowerLoadHClassFromConstpool(GateRef gate) 1734514f5e3Sopenharmony_ci{ 1744514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 1754514f5e3Sopenharmony_ci GateRef constpool = acc_.GetValueIn(gate, 0); 1764514f5e3Sopenharmony_ci uint32_t index = acc_.GetIndex(gate); 1774514f5e3Sopenharmony_ci if (!env_->IsJitCompiler()) { 1784514f5e3Sopenharmony_ci GateRef constPoolSize = builder_.GetLengthOfTaggedArray(constpool); 1794514f5e3Sopenharmony_ci GateRef valVecIndex = builder_.Int32Sub(constPoolSize, builder_.Int32(ConstantPool::AOT_HCLASS_INFO_INDEX)); 1804514f5e3Sopenharmony_ci GateRef valVec = builder_.GetValueFromTaggedArray(constpool, valVecIndex); 1814514f5e3Sopenharmony_ci GateRef hclass = builder_.GetValueFromTaggedArray(valVec, builder_.Int32(index)); 1824514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, Circuit::NullGate(), builder_.GetDepend(), hclass); 1834514f5e3Sopenharmony_ci } else { 1844514f5e3Sopenharmony_ci JSTaggedValue hclass = env_->GetPTManager()->QueryHClassByIndexForJIT(index); 1854514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, Circuit::NullGate(), builder_.GetDepend(), builder_.TaggedValueConstant(hclass)); 1864514f5e3Sopenharmony_ci } 1874514f5e3Sopenharmony_ci} 1884514f5e3Sopenharmony_ci 1894514f5e3Sopenharmony_civoid MCRLowering::LowerStoreConstOffset(GateRef gate) 1904514f5e3Sopenharmony_ci{ 1914514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 1924514f5e3Sopenharmony_ci 1934514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 0); 1944514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 1); 1954514f5e3Sopenharmony_ci GateRef offset = builder_.IntPtr(acc_.GetOffset(gate)); 1964514f5e3Sopenharmony_ci VariableType type = VariableType(acc_.GetMachineType(gate), acc_.GetGateType(gate)); 1974514f5e3Sopenharmony_ci builder_.Store(type, glue_, receiver, offset, value, acc_.GetMemoryAttribute(gate)); 1984514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 1994514f5e3Sopenharmony_ci} 2004514f5e3Sopenharmony_ci 2014514f5e3Sopenharmony_civoid MCRLowering::LowerHeapObjectCheck(GateRef gate) 2024514f5e3Sopenharmony_ci{ 2034514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 2044514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 2054514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 0); 2064514f5e3Sopenharmony_ci 2074514f5e3Sopenharmony_ci GateRef heapObjectCheck = builder_.TaggedIsHeapObject(receiver); 2084514f5e3Sopenharmony_ci builder_.DeoptCheck(heapObjectCheck, frameState, DeoptType::NOTHEAPOBJECT1); 2094514f5e3Sopenharmony_ci 2104514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 2114514f5e3Sopenharmony_ci} 2124514f5e3Sopenharmony_ci 2134514f5e3Sopenharmony_civoid MCRLowering::LowerTaggedIsHeapObject(GateRef gate) 2144514f5e3Sopenharmony_ci{ 2154514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 2164514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 0); 2174514f5e3Sopenharmony_ci GateRef result = builder_.TaggedIsHeapObject(receiver); 2184514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 2194514f5e3Sopenharmony_ci} 2204514f5e3Sopenharmony_ci 2214514f5e3Sopenharmony_civoid MCRLowering::LowerIsMarkerCellValid(GateRef gate) 2224514f5e3Sopenharmony_ci{ 2234514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 2244514f5e3Sopenharmony_ci GateRef cell = acc_.GetValueIn(gate, 0); 2254514f5e3Sopenharmony_ci GateRef result = builder_.IsMarkerCellValid(cell); 2264514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 2274514f5e3Sopenharmony_ci} 2284514f5e3Sopenharmony_ci 2294514f5e3Sopenharmony_civoid MCRLowering::LowerIsSpecificObjectType(GateRef gate) 2304514f5e3Sopenharmony_ci{ 2314514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 2324514f5e3Sopenharmony_ci JSType expectType = static_cast<JSType>(acc_.GetJSType(gate)); 2334514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 0); 2344514f5e3Sopenharmony_ci GateRef result; 2354514f5e3Sopenharmony_ci switch (expectType) { 2364514f5e3Sopenharmony_ci case JSType::JS_MAP: { 2374514f5e3Sopenharmony_ci result = builder_.TaggedObjectIsJSMap(obj); 2384514f5e3Sopenharmony_ci break; 2394514f5e3Sopenharmony_ci } 2404514f5e3Sopenharmony_ci case JSType::JS_SET: { 2414514f5e3Sopenharmony_ci result = builder_.TaggedObjectIsJSSet(obj); 2424514f5e3Sopenharmony_ci break; 2434514f5e3Sopenharmony_ci } 2444514f5e3Sopenharmony_ci case JSType::JS_DATE: { 2454514f5e3Sopenharmony_ci result = builder_.TaggedObjectIsJSDate(obj); 2464514f5e3Sopenharmony_ci break; 2474514f5e3Sopenharmony_ci } 2484514f5e3Sopenharmony_ci case JSType::JS_ARRAY: { 2494514f5e3Sopenharmony_ci result = builder_.TaggedObjectIsJSArray(obj); 2504514f5e3Sopenharmony_ci break; 2514514f5e3Sopenharmony_ci } 2524514f5e3Sopenharmony_ci case JSType::STRING_FIRST: { 2534514f5e3Sopenharmony_ci result = builder_.TaggedObjectIsString(obj); 2544514f5e3Sopenharmony_ci break; 2554514f5e3Sopenharmony_ci } 2564514f5e3Sopenharmony_ci case JSType::JS_TYPED_ARRAY_FIRST: { 2574514f5e3Sopenharmony_ci result = builder_.TaggedObjectIsTypedArray(obj); 2584514f5e3Sopenharmony_ci break; 2594514f5e3Sopenharmony_ci } 2604514f5e3Sopenharmony_ci default: { 2614514f5e3Sopenharmony_ci LOG_COMPILER(FATAL) << "this branch is unreachable"; 2624514f5e3Sopenharmony_ci UNREACHABLE(); 2634514f5e3Sopenharmony_ci } 2644514f5e3Sopenharmony_ci } 2654514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 2664514f5e3Sopenharmony_ci} 2674514f5e3Sopenharmony_ci 2684514f5e3Sopenharmony_civoid MCRLowering::DeleteStateSplit(GateRef gate) 2694514f5e3Sopenharmony_ci{ 2704514f5e3Sopenharmony_ci auto depend = acc_.GetDep(gate); 2714514f5e3Sopenharmony_ci auto frameState = acc_.GetFrameState(gate); 2724514f5e3Sopenharmony_ci acc_.DeleteGateIfNoUse(frameState); 2734514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, Circuit::NullGate(), depend, Circuit::NullGate()); 2744514f5e3Sopenharmony_ci} 2754514f5e3Sopenharmony_ci 2764514f5e3Sopenharmony_civoid MCRLowering::LowerArrayGuardianCheck(GateRef gate) 2774514f5e3Sopenharmony_ci{ 2784514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 2794514f5e3Sopenharmony_ci 2804514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 2814514f5e3Sopenharmony_ci GateRef guardiansOffset = builder_.IntPtr(JSThread::GlueData::GetStableArrayElementsGuardiansOffset(false)); 2824514f5e3Sopenharmony_ci GateRef check = builder_.Load(VariableType::BOOL(), glue_, guardiansOffset); 2834514f5e3Sopenharmony_ci builder_.DeoptCheck(check, frameState, DeoptType::NOTSARRAY1); 2844514f5e3Sopenharmony_ci 2854514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 2864514f5e3Sopenharmony_ci} 2874514f5e3Sopenharmony_ci 2884514f5e3Sopenharmony_civoid MCRLowering::LowerHClassStableArrayCheck(GateRef gate) 2894514f5e3Sopenharmony_ci{ 2904514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 2914514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 2924514f5e3Sopenharmony_ci GateRef hclass = acc_.GetValueIn(gate, 0); 2934514f5e3Sopenharmony_ci 2944514f5e3Sopenharmony_ci GateRef check = builder_.IsStableElements(hclass); 2954514f5e3Sopenharmony_ci builder_.DeoptCheck(check, frameState, DeoptType::NOTSARRAY2); 2964514f5e3Sopenharmony_ci 2974514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 2984514f5e3Sopenharmony_ci} 2994514f5e3Sopenharmony_ci 3004514f5e3Sopenharmony_ciStateDepend MCRLowering::LowerConvert(StateDepend stateDepend, GateRef gate) 3014514f5e3Sopenharmony_ci{ 3024514f5e3Sopenharmony_ci Environment env(stateDepend.State(), stateDepend.Depend(), {}, circuit_, &builder_); 3034514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate); 3044514f5e3Sopenharmony_ci ValueType dstType = acc_.GetDstType(gate); 3054514f5e3Sopenharmony_ci GateRef result = Circuit::NullGate(); 3064514f5e3Sopenharmony_ci Label exit(&builder_); 3074514f5e3Sopenharmony_ci switch (acc_.GetSrcType(gate)) { 3084514f5e3Sopenharmony_ci case ValueType::BOOL: 3094514f5e3Sopenharmony_ci ASSERT(dstType == ValueType::TAGGED_BOOLEAN); 3104514f5e3Sopenharmony_ci result = ConvertBoolToTaggedBoolean(value); 3114514f5e3Sopenharmony_ci break; 3124514f5e3Sopenharmony_ci case ValueType::INT32: 3134514f5e3Sopenharmony_ci if (dstType == ValueType::TAGGED_INT) { 3144514f5e3Sopenharmony_ci result = ConvertInt32ToTaggedInt(value); 3154514f5e3Sopenharmony_ci } else if (dstType == ValueType::FLOAT64) { 3164514f5e3Sopenharmony_ci result = ConvertInt32ToFloat64(value); 3174514f5e3Sopenharmony_ci } else { 3184514f5e3Sopenharmony_ci ASSERT(dstType == ValueType::BOOL); 3194514f5e3Sopenharmony_ci result = builder_.NotEqual(value, builder_.Int32(0)); 3204514f5e3Sopenharmony_ci } 3214514f5e3Sopenharmony_ci break; 3224514f5e3Sopenharmony_ci case ValueType::UINT32: 3234514f5e3Sopenharmony_ci if (dstType == ValueType::TAGGED_NUMBER) { 3244514f5e3Sopenharmony_ci result = ConvertUInt32ToTaggedNumber(value, &exit); 3254514f5e3Sopenharmony_ci } else if (dstType == ValueType::FLOAT64) { 3264514f5e3Sopenharmony_ci result = ConvertUInt32ToFloat64(value); 3274514f5e3Sopenharmony_ci } else { 3284514f5e3Sopenharmony_ci ASSERT(dstType == ValueType::BOOL); 3294514f5e3Sopenharmony_ci result = builder_.NotEqual(value, builder_.Int32(0)); 3304514f5e3Sopenharmony_ci } 3314514f5e3Sopenharmony_ci break; 3324514f5e3Sopenharmony_ci case ValueType::FLOAT64: 3334514f5e3Sopenharmony_ci if (dstType == ValueType::TAGGED_DOUBLE) { 3344514f5e3Sopenharmony_ci result = ConvertFloat64ToTaggedDouble(value); 3354514f5e3Sopenharmony_ci } else if (dstType == ValueType::INT32) { 3364514f5e3Sopenharmony_ci result = ConvertFloat64ToInt32(value, &exit); 3374514f5e3Sopenharmony_ci } else { 3384514f5e3Sopenharmony_ci ASSERT(dstType == ValueType::BOOL); 3394514f5e3Sopenharmony_ci result = ConvertFloat64ToBool(value); 3404514f5e3Sopenharmony_ci } 3414514f5e3Sopenharmony_ci break; 3424514f5e3Sopenharmony_ci case ValueType::TAGGED_BOOLEAN: 3434514f5e3Sopenharmony_ci ASSERT((dstType == ValueType::BOOL)); 3444514f5e3Sopenharmony_ci result = ConvertTaggedBooleanToBool(value); 3454514f5e3Sopenharmony_ci break; 3464514f5e3Sopenharmony_ci case ValueType::TAGGED_INT: 3474514f5e3Sopenharmony_ci ASSERT((dstType == ValueType::INT32)); 3484514f5e3Sopenharmony_ci result = ConvertTaggedIntToInt32(value); 3494514f5e3Sopenharmony_ci break; 3504514f5e3Sopenharmony_ci case ValueType::TAGGED_DOUBLE: 3514514f5e3Sopenharmony_ci ASSERT((dstType == ValueType::FLOAT64)); 3524514f5e3Sopenharmony_ci result = ConvertTaggedDoubleToFloat64(value); 3534514f5e3Sopenharmony_ci break; 3544514f5e3Sopenharmony_ci case ValueType::CHAR: { 3554514f5e3Sopenharmony_ci GateRef glue = acc_.GetGlueFromArgList(); 3564514f5e3Sopenharmony_ci if (dstType == ValueType::ECMA_STRING) { 3574514f5e3Sopenharmony_ci result = builder_.CallStub(glue, gate, CommonStubCSigns::CreateStringBySingleCharCode, { glue, value }); 3584514f5e3Sopenharmony_ci } else if (dstType == ValueType::INT32) { 3594514f5e3Sopenharmony_ci result = builder_.CallStub(glue, gate, CommonStubCSigns::ConvertCharToInt32, { glue, value }); 3604514f5e3Sopenharmony_ci } else { 3614514f5e3Sopenharmony_ci ASSERT((dstType == ValueType::FLOAT64)); 3624514f5e3Sopenharmony_ci result = builder_.CallStub(glue, gate, CommonStubCSigns::ConvertCharToDouble, { glue, value }); 3634514f5e3Sopenharmony_ci } 3644514f5e3Sopenharmony_ci break; 3654514f5e3Sopenharmony_ci } 3664514f5e3Sopenharmony_ci case ValueType::HOLE_INT: 3674514f5e3Sopenharmony_ci if (dstType == ValueType::TAGGED_INT) { 3684514f5e3Sopenharmony_ci result = ConvertSpecialHoleIntToTagged(value, &exit); 3694514f5e3Sopenharmony_ci } 3704514f5e3Sopenharmony_ci break; 3714514f5e3Sopenharmony_ci case ValueType::HOLE_DOUBLE: 3724514f5e3Sopenharmony_ci if (dstType == ValueType::TAGGED_DOUBLE) { 3734514f5e3Sopenharmony_ci result = ConvertSpecialHoleDoubleToTagged(value, &exit); 3744514f5e3Sopenharmony_ci } 3754514f5e3Sopenharmony_ci break; 3764514f5e3Sopenharmony_ci default: 3774514f5e3Sopenharmony_ci LOG_COMPILER(FATAL) << "this branch is unreachable"; 3784514f5e3Sopenharmony_ci break; 3794514f5e3Sopenharmony_ci } 3804514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, Circuit::NullGate(), Circuit::NullGate(), result); 3814514f5e3Sopenharmony_ci return builder_.GetStateDepend(); 3824514f5e3Sopenharmony_ci} 3834514f5e3Sopenharmony_ci 3844514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertSpecialHoleIntToTagged(GateRef gate, Label* exit) 3854514f5e3Sopenharmony_ci{ 3864514f5e3Sopenharmony_ci Label returnUndefined(&builder_); 3874514f5e3Sopenharmony_ci Label returnTaggedInt(&builder_); 3884514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant()); 3894514f5e3Sopenharmony_ci 3904514f5e3Sopenharmony_ci builder_.Branch(builder_.IsSpecialHole(gate), &returnUndefined, &returnTaggedInt, 1, BranchWeight::DEOPT_WEIGHT, 3914514f5e3Sopenharmony_ci "specialHoleCheck"); 3924514f5e3Sopenharmony_ci builder_.Bind(&returnUndefined); 3934514f5e3Sopenharmony_ci { 3944514f5e3Sopenharmony_ci result = builder_.UndefineConstant(); 3954514f5e3Sopenharmony_ci builder_.Jump(exit); 3964514f5e3Sopenharmony_ci } 3974514f5e3Sopenharmony_ci builder_.Bind(&returnTaggedInt); 3984514f5e3Sopenharmony_ci { 3994514f5e3Sopenharmony_ci GateRef rawInt = builder_.TruncInt64ToInt32(gate); 4004514f5e3Sopenharmony_ci result = ConvertInt32ToTaggedInt(rawInt); 4014514f5e3Sopenharmony_ci builder_.Jump(exit); 4024514f5e3Sopenharmony_ci } 4034514f5e3Sopenharmony_ci builder_.Bind(exit); 4044514f5e3Sopenharmony_ci return *result; 4054514f5e3Sopenharmony_ci} 4064514f5e3Sopenharmony_ci 4074514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertSpecialHoleDoubleToTagged(GateRef gate, Label* exit) 4084514f5e3Sopenharmony_ci{ 4094514f5e3Sopenharmony_ci Label returnUndefined(&builder_); 4104514f5e3Sopenharmony_ci Label returnTaggedDouble(&builder_); 4114514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant()); 4124514f5e3Sopenharmony_ci 4134514f5e3Sopenharmony_ci builder_.Branch(builder_.IsSpecialHole(gate), &returnUndefined, &returnTaggedDouble, 1, BranchWeight::DEOPT_WEIGHT, 4144514f5e3Sopenharmony_ci "specialHoleCheck"); 4154514f5e3Sopenharmony_ci builder_.Bind(&returnUndefined); 4164514f5e3Sopenharmony_ci { 4174514f5e3Sopenharmony_ci result = builder_.UndefineConstant(); 4184514f5e3Sopenharmony_ci builder_.Jump(exit); 4194514f5e3Sopenharmony_ci } 4204514f5e3Sopenharmony_ci builder_.Bind(&returnTaggedDouble); 4214514f5e3Sopenharmony_ci { 4224514f5e3Sopenharmony_ci GateRef rawDouble = builder_.CastInt64ToFloat64(gate); 4234514f5e3Sopenharmony_ci result = ConvertFloat64ToTaggedDouble(rawDouble); 4244514f5e3Sopenharmony_ci builder_.Jump(exit); 4254514f5e3Sopenharmony_ci } 4264514f5e3Sopenharmony_ci builder_.Bind(exit); 4274514f5e3Sopenharmony_ci return *result; 4284514f5e3Sopenharmony_ci} 4294514f5e3Sopenharmony_ci 4304514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertTaggedNumberToBool(GateRef gate, Label *exit) 4314514f5e3Sopenharmony_ci{ 4324514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::BOOL(), builder_.Boolean(false)); 4334514f5e3Sopenharmony_ci Label isInt(&builder_); 4344514f5e3Sopenharmony_ci Label isDouble(&builder_); 4354514f5e3Sopenharmony_ci Label toInt32(&builder_); 4364514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsInt(gate), &isInt, &isDouble); 4374514f5e3Sopenharmony_ci builder_.Bind(&isInt); 4384514f5e3Sopenharmony_ci { 4394514f5e3Sopenharmony_ci GateRef intVal = builder_.GetInt64OfTInt(gate); 4404514f5e3Sopenharmony_ci result = builder_.NotEqual(intVal, builder_.Int64(0)); 4414514f5e3Sopenharmony_ci } 4424514f5e3Sopenharmony_ci builder_.Jump(exit); 4434514f5e3Sopenharmony_ci builder_.Bind(&isDouble); 4444514f5e3Sopenharmony_ci { 4454514f5e3Sopenharmony_ci GateRef doubleVal = builder_.GetDoubleOfTDouble(gate); 4464514f5e3Sopenharmony_ci result = ConvertFloat64ToBool(doubleVal); 4474514f5e3Sopenharmony_ci } 4484514f5e3Sopenharmony_ci builder_.Jump(exit); 4494514f5e3Sopenharmony_ci builder_.Bind(exit); 4504514f5e3Sopenharmony_ci return *result; 4514514f5e3Sopenharmony_ci} 4524514f5e3Sopenharmony_ci 4534514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertTaggedNumberToInt32(GateRef gate, Label *exit) 4544514f5e3Sopenharmony_ci{ 4554514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::INT32(), builder_.Int32(0)); 4564514f5e3Sopenharmony_ci Label isInt(&builder_); 4574514f5e3Sopenharmony_ci Label isDouble(&builder_); 4584514f5e3Sopenharmony_ci Label toInt32(&builder_); 4594514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsInt(gate), &isInt, &isDouble); 4604514f5e3Sopenharmony_ci builder_.Bind(&isInt); 4614514f5e3Sopenharmony_ci result = ConvertTaggedIntToInt32(gate); 4624514f5e3Sopenharmony_ci builder_.Jump(exit); 4634514f5e3Sopenharmony_ci builder_.Bind(&isDouble); 4644514f5e3Sopenharmony_ci result = ConvertFloat64ToInt32(ConvertTaggedDoubleToFloat64(gate), &toInt32); 4654514f5e3Sopenharmony_ci builder_.Jump(exit); 4664514f5e3Sopenharmony_ci builder_.Bind(exit); 4674514f5e3Sopenharmony_ci return *result; 4684514f5e3Sopenharmony_ci} 4694514f5e3Sopenharmony_ci 4704514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertTaggedNumberToFloat64(GateRef gate, Label *exit) 4714514f5e3Sopenharmony_ci{ 4724514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::FLOAT64(), builder_.Double(0)); 4734514f5e3Sopenharmony_ci Label isInt(&builder_); 4744514f5e3Sopenharmony_ci Label isDouble(&builder_); 4754514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsInt(gate), &isInt, &isDouble); 4764514f5e3Sopenharmony_ci builder_.Bind(&isInt); 4774514f5e3Sopenharmony_ci result = ConvertInt32ToFloat64(ConvertTaggedIntToInt32(gate)); 4784514f5e3Sopenharmony_ci builder_.Jump(exit); 4794514f5e3Sopenharmony_ci builder_.Bind(&isDouble); 4804514f5e3Sopenharmony_ci result = ConvertTaggedDoubleToFloat64(gate); 4814514f5e3Sopenharmony_ci builder_.Jump(exit); 4824514f5e3Sopenharmony_ci builder_.Bind(exit); 4834514f5e3Sopenharmony_ci return *result; 4844514f5e3Sopenharmony_ci} 4854514f5e3Sopenharmony_ci 4864514f5e3Sopenharmony_civoid MCRLowering::LowerCheckAndConvert(GateRef gate) 4874514f5e3Sopenharmony_ci{ 4884514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 4894514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 4904514f5e3Sopenharmony_ci ValueType srcType = acc_.GetSrcType(gate); 4914514f5e3Sopenharmony_ci Label exit(&builder_); 4924514f5e3Sopenharmony_ci switch (srcType) { 4934514f5e3Sopenharmony_ci case ValueType::UINT32: 4944514f5e3Sopenharmony_ci LowerCheckUInt32AndConvert(gate, frameState); 4954514f5e3Sopenharmony_ci break; 4964514f5e3Sopenharmony_ci case ValueType::TAGGED_INT: 4974514f5e3Sopenharmony_ci LowerCheckTaggedIntAndConvert(gate, frameState); 4984514f5e3Sopenharmony_ci break; 4994514f5e3Sopenharmony_ci case ValueType::TAGGED_DOUBLE: 5004514f5e3Sopenharmony_ci LowerCheckTaggedDoubleAndConvert(gate, frameState, &exit); 5014514f5e3Sopenharmony_ci break; 5024514f5e3Sopenharmony_ci case ValueType::TAGGED_BOOLEAN: 5034514f5e3Sopenharmony_ci LowerCheckTaggedBoolAndConvert(gate, frameState); 5044514f5e3Sopenharmony_ci break; 5054514f5e3Sopenharmony_ci case ValueType::TAGGED_NUMBER: 5064514f5e3Sopenharmony_ci LowerCheckTaggedNumberAndConvert(gate, frameState, &exit); 5074514f5e3Sopenharmony_ci break; 5084514f5e3Sopenharmony_ci case ValueType::BOOL: 5094514f5e3Sopenharmony_ci LowerCheckSupportAndConvert(gate, frameState); 5104514f5e3Sopenharmony_ci break; 5114514f5e3Sopenharmony_ci case ValueType::TAGGED_NULL: 5124514f5e3Sopenharmony_ci LowerCheckNullAndConvert(gate, frameState); 5134514f5e3Sopenharmony_ci break; 5144514f5e3Sopenharmony_ci case ValueType::UNDEFINED: 5154514f5e3Sopenharmony_ci LowerUndefinedAndConvert(gate, frameState); 5164514f5e3Sopenharmony_ci break; 5174514f5e3Sopenharmony_ci case ValueType::HOLE_INT: 5184514f5e3Sopenharmony_ci LowerCheckSpecialHoleAndConvert(gate, frameState); 5194514f5e3Sopenharmony_ci break; 5204514f5e3Sopenharmony_ci case ValueType::HOLE_DOUBLE: 5214514f5e3Sopenharmony_ci LowerCheckSpecialHoleAndConvert(gate, frameState); 5224514f5e3Sopenharmony_ci break; 5234514f5e3Sopenharmony_ci case ValueType::FLOAT64: 5244514f5e3Sopenharmony_ci LowerCheckFloat64AndConvert(gate, frameState, &exit); 5254514f5e3Sopenharmony_ci break; 5264514f5e3Sopenharmony_ci default: 5274514f5e3Sopenharmony_ci UNREACHABLE(); 5284514f5e3Sopenharmony_ci } 5294514f5e3Sopenharmony_ci} 5304514f5e3Sopenharmony_ci 5314514f5e3Sopenharmony_civoid MCRLowering::LowerCheckFloat64AndConvert(GateRef gate, GateRef frameState, Label *exit) 5324514f5e3Sopenharmony_ci{ 5334514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 5344514f5e3Sopenharmony_ci 5354514f5e3Sopenharmony_ci GateRef result = ConvertFloat64ToInt32(value, exit); 5364514f5e3Sopenharmony_ci GateRef check = builder_.DoubleEqual(builder_.ChangeInt32ToFloat64(result), value); 5374514f5e3Sopenharmony_ci builder_.DeoptCheck(check, frameState, DeoptType::INT32OVERFLOW1); 5384514f5e3Sopenharmony_ci 5394514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 5404514f5e3Sopenharmony_ci} 5414514f5e3Sopenharmony_ci 5424514f5e3Sopenharmony_civoid MCRLowering::LowerCheckSpecialHoleAndConvert(GateRef gate, GateRef frameState) 5434514f5e3Sopenharmony_ci{ 5444514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 5454514f5e3Sopenharmony_ci GateRef typeCheck = builder_.IsNotSpecialHole(value); 5464514f5e3Sopenharmony_ci builder_.DeoptCheck(typeCheck, frameState, DeoptType::CANNOTSTORESPECAILHOLE); 5474514f5e3Sopenharmony_ci GateRef result = Circuit::NullGate(); 5484514f5e3Sopenharmony_ci ValueType dst = acc_.GetDstType(gate); 5494514f5e3Sopenharmony_ci if (dst == ValueType::INT32) { 5504514f5e3Sopenharmony_ci result = builder_.TruncInt64ToInt32(value); 5514514f5e3Sopenharmony_ci } else if (dst == ValueType::FLOAT64) { 5524514f5e3Sopenharmony_ci result = builder_.CastInt64ToFloat64(value); 5534514f5e3Sopenharmony_ci } else if (dst == ValueType::TAGGED_INT) { 5544514f5e3Sopenharmony_ci GateRef rawInt = builder_.TruncInt64ToInt32(gate); 5554514f5e3Sopenharmony_ci result = ConvertInt32ToTaggedInt(rawInt); 5564514f5e3Sopenharmony_ci } else if (dst == ValueType::TAGGED_DOUBLE) { 5574514f5e3Sopenharmony_ci GateRef rawDouble = builder_.CastInt64ToFloat64(value); 5584514f5e3Sopenharmony_ci result = ConvertFloat64ToTaggedDouble(rawDouble); 5594514f5e3Sopenharmony_ci } else { 5604514f5e3Sopenharmony_ci UNREACHABLE(); 5614514f5e3Sopenharmony_ci } 5624514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 5634514f5e3Sopenharmony_ci} 5644514f5e3Sopenharmony_ci 5654514f5e3Sopenharmony_civoid MCRLowering::LowerCheckUInt32AndConvert(GateRef gate, GateRef frameState) 5664514f5e3Sopenharmony_ci{ 5674514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 5684514f5e3Sopenharmony_ci GateRef upperBound = builder_.Int32(INT32_MAX); 5694514f5e3Sopenharmony_ci GateRef check = builder_.Int32UnsignedLessThanOrEqual(value, upperBound); 5704514f5e3Sopenharmony_ci builder_.DeoptCheck(check, frameState, DeoptType::INT32OVERFLOW1); 5714514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), value); 5724514f5e3Sopenharmony_ci} 5734514f5e3Sopenharmony_ci 5744514f5e3Sopenharmony_civoid MCRLowering::LowerCheckTaggedIntAndConvert(GateRef gate, GateRef frameState) 5754514f5e3Sopenharmony_ci{ 5764514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 5774514f5e3Sopenharmony_ci GateRef typeCheck = builder_.TaggedIsInt(value); 5784514f5e3Sopenharmony_ci builder_.DeoptCheck(typeCheck, frameState, DeoptType::NOTINT1); 5794514f5e3Sopenharmony_ci GateRef result = Circuit::NullGate(); 5804514f5e3Sopenharmony_ci ValueType dst = acc_.GetDstType(gate); 5814514f5e3Sopenharmony_ci ASSERT(dst == ValueType::INT32 || dst == ValueType::FLOAT64); 5824514f5e3Sopenharmony_ci if (dst == ValueType::INT32) { 5834514f5e3Sopenharmony_ci result = ConvertTaggedIntToInt32(value); 5844514f5e3Sopenharmony_ci } else { 5854514f5e3Sopenharmony_ci result = ConvertTaggedIntToFloat64(value); 5864514f5e3Sopenharmony_ci } 5874514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 5884514f5e3Sopenharmony_ci} 5894514f5e3Sopenharmony_ci 5904514f5e3Sopenharmony_civoid MCRLowering::LowerCheckTaggedDoubleAndConvert(GateRef gate, GateRef frameState, Label *exit) 5914514f5e3Sopenharmony_ci{ 5924514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 5934514f5e3Sopenharmony_ci GateRef typeCheck = builder_.TaggedIsDouble(value); 5944514f5e3Sopenharmony_ci builder_.DeoptCheck(typeCheck, frameState, DeoptType::NOTDOUBLE1); 5954514f5e3Sopenharmony_ci GateRef result = Circuit::NullGate(); 5964514f5e3Sopenharmony_ci ValueType dst = acc_.GetDstType(gate); 5974514f5e3Sopenharmony_ci ASSERT(dst == ValueType::INT32 || dst == ValueType::FLOAT64); 5984514f5e3Sopenharmony_ci if (dst == ValueType::INT32) { 5994514f5e3Sopenharmony_ci result = ConvertTaggedDoubleToInt32(value, exit); 6004514f5e3Sopenharmony_ci } else { 6014514f5e3Sopenharmony_ci result = ConvertTaggedDoubleToFloat64(value); 6024514f5e3Sopenharmony_ci } 6034514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 6044514f5e3Sopenharmony_ci} 6054514f5e3Sopenharmony_ci 6064514f5e3Sopenharmony_civoid MCRLowering::LowerCheckTaggedNumberAndConvert(GateRef gate, GateRef frameState, Label *exit) 6074514f5e3Sopenharmony_ci{ 6084514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 6094514f5e3Sopenharmony_ci GateRef typeCheck = builder_.TaggedIsNumber(value); 6104514f5e3Sopenharmony_ci builder_.DeoptCheck(typeCheck, frameState, DeoptType::NOTNUMBER1); 6114514f5e3Sopenharmony_ci GateRef result = Circuit::NullGate(); 6124514f5e3Sopenharmony_ci ValueType dst = acc_.GetDstType(gate); 6134514f5e3Sopenharmony_ci if (dst == ValueType::INT32) { 6144514f5e3Sopenharmony_ci result = ConvertTaggedNumberToInt32(value, exit); 6154514f5e3Sopenharmony_ci } else if (dst == ValueType::FLOAT64) { 6164514f5e3Sopenharmony_ci result = ConvertTaggedNumberToFloat64(value, exit); 6174514f5e3Sopenharmony_ci } else { 6184514f5e3Sopenharmony_ci ASSERT(dst == ValueType::BOOL); 6194514f5e3Sopenharmony_ci result = ConvertTaggedNumberToBool(value, exit); 6204514f5e3Sopenharmony_ci } 6214514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 6224514f5e3Sopenharmony_ci} 6234514f5e3Sopenharmony_ci 6244514f5e3Sopenharmony_civoid MCRLowering::LowerCheckSupportAndConvert(GateRef gate, GateRef frameState) 6254514f5e3Sopenharmony_ci{ 6264514f5e3Sopenharmony_ci ValueType dstType = acc_.GetDstType(gate); 6274514f5e3Sopenharmony_ci ASSERT(dstType == ValueType::INT32 || dstType == ValueType::FLOAT64); 6284514f5e3Sopenharmony_ci bool support = acc_.IsConvertSupport(gate); 6294514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 6304514f5e3Sopenharmony_ci 6314514f5e3Sopenharmony_ci GateRef result = Circuit::NullGate(); 6324514f5e3Sopenharmony_ci if (dstType == ValueType::INT32) { 6334514f5e3Sopenharmony_ci builder_.DeoptCheck(builder_.Boolean(support), frameState, DeoptType::NOTINT2); 6344514f5e3Sopenharmony_ci result = builder_.BooleanToInt32(value); 6354514f5e3Sopenharmony_ci } else { 6364514f5e3Sopenharmony_ci builder_.DeoptCheck(builder_.Boolean(support), frameState, DeoptType::NOTDOUBLE2); 6374514f5e3Sopenharmony_ci result = builder_.BooleanToFloat64(value); 6384514f5e3Sopenharmony_ci } 6394514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 6404514f5e3Sopenharmony_ci} 6414514f5e3Sopenharmony_ci 6424514f5e3Sopenharmony_civoid MCRLowering::LowerCheckTaggedBoolAndConvert(GateRef gate, GateRef frameState) 6434514f5e3Sopenharmony_ci{ 6444514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 6454514f5e3Sopenharmony_ci GateRef typeCheck = builder_.TaggedIsBoolean(value); 6464514f5e3Sopenharmony_ci builder_.DeoptCheck(typeCheck, frameState, DeoptType::NOTBOOL1); 6474514f5e3Sopenharmony_ci GateRef result = Circuit::NullGate(); 6484514f5e3Sopenharmony_ci GateRef boolValue = ConvertTaggedBooleanToBool(value); 6494514f5e3Sopenharmony_ci if (acc_.GetDstType(gate) == ValueType::BOOL) { 6504514f5e3Sopenharmony_ci result = boolValue; 6514514f5e3Sopenharmony_ci } else if (acc_.GetDstType(gate) == ValueType::INT32) { 6524514f5e3Sopenharmony_ci result = builder_.ZExtInt1ToInt32(boolValue); 6534514f5e3Sopenharmony_ci } else if (acc_.GetDstType(gate) == ValueType::FLOAT64) { 6544514f5e3Sopenharmony_ci result = builder_.BooleanToFloat64(boolValue); 6554514f5e3Sopenharmony_ci } else { 6564514f5e3Sopenharmony_ci UNREACHABLE(); 6574514f5e3Sopenharmony_ci } 6584514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 6594514f5e3Sopenharmony_ci} 6604514f5e3Sopenharmony_ci 6614514f5e3Sopenharmony_civoid MCRLowering::LowerCheckNullAndConvert(GateRef gate, GateRef frameState) 6624514f5e3Sopenharmony_ci{ 6634514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 6644514f5e3Sopenharmony_ci GateRef typeCheck = builder_.TaggedIsNull(value); 6654514f5e3Sopenharmony_ci builder_.DeoptCheck(typeCheck, frameState, DeoptType::NOTNULL1); 6664514f5e3Sopenharmony_ci GateRef result = Circuit::NullGate(); 6674514f5e3Sopenharmony_ci if (acc_.GetDstType(gate) == ValueType::INT32) { 6684514f5e3Sopenharmony_ci result = builder_.Int32(0); 6694514f5e3Sopenharmony_ci } else if (acc_.GetDstType(gate) == ValueType::FLOAT64) { 6704514f5e3Sopenharmony_ci result = builder_.Double(0); 6714514f5e3Sopenharmony_ci } else if (acc_.GetDstType(gate) == ValueType::BOOL) { 6724514f5e3Sopenharmony_ci result = builder_.False(); 6734514f5e3Sopenharmony_ci } else { 6744514f5e3Sopenharmony_ci UNREACHABLE(); 6754514f5e3Sopenharmony_ci } 6764514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 6774514f5e3Sopenharmony_ci} 6784514f5e3Sopenharmony_ci 6794514f5e3Sopenharmony_civoid MCRLowering::LowerUndefinedAndConvert(GateRef gate, GateRef frameState) 6804514f5e3Sopenharmony_ci{ 6814514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 6824514f5e3Sopenharmony_ci GateRef typeCheck = builder_.TaggedIsUndefined(value); 6834514f5e3Sopenharmony_ci builder_.DeoptCheck(typeCheck, frameState, DeoptType::NOTNULL2); 6844514f5e3Sopenharmony_ci GateRef result = Circuit::NullGate(); 6854514f5e3Sopenharmony_ci if (acc_.GetDstType(gate) == ValueType::FLOAT64) { 6864514f5e3Sopenharmony_ci result = builder_.NanValue(); 6874514f5e3Sopenharmony_ci } else if (acc_.GetDstType(gate) == ValueType::BOOL) { 6884514f5e3Sopenharmony_ci result = builder_.False(); 6894514f5e3Sopenharmony_ci } else if (acc_.GetDstType(gate) == ValueType::INT32) { 6904514f5e3Sopenharmony_ci result = builder_.Int32(0); 6914514f5e3Sopenharmony_ci } else { 6924514f5e3Sopenharmony_ci UNREACHABLE(); 6934514f5e3Sopenharmony_ci } 6944514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 6954514f5e3Sopenharmony_ci} 6964514f5e3Sopenharmony_ci 6974514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertTaggedBooleanToBool(GateRef value) 6984514f5e3Sopenharmony_ci{ 6994514f5e3Sopenharmony_ci return builder_.TaggedIsTrue(value); 7004514f5e3Sopenharmony_ci} 7014514f5e3Sopenharmony_ci 7024514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertBoolToTaggedBoolean(GateRef gate) 7034514f5e3Sopenharmony_ci{ 7044514f5e3Sopenharmony_ci return builder_.BooleanToTaggedBooleanPtr(gate); 7054514f5e3Sopenharmony_ci} 7064514f5e3Sopenharmony_ci 7074514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertInt32ToFloat64(GateRef gate) 7084514f5e3Sopenharmony_ci{ 7094514f5e3Sopenharmony_ci return builder_.ChangeInt32ToFloat64(gate); 7104514f5e3Sopenharmony_ci} 7114514f5e3Sopenharmony_ci 7124514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertUInt32ToFloat64(GateRef gate) 7134514f5e3Sopenharmony_ci{ 7144514f5e3Sopenharmony_ci return builder_.ChangeUInt32ToFloat64(gate); 7154514f5e3Sopenharmony_ci} 7164514f5e3Sopenharmony_ci 7174514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertInt32ToTaggedInt(GateRef gate) 7184514f5e3Sopenharmony_ci{ 7194514f5e3Sopenharmony_ci return builder_.Int32ToTaggedPtr(gate); 7204514f5e3Sopenharmony_ci} 7214514f5e3Sopenharmony_ci 7224514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertUInt32ToTaggedNumber(GateRef gate, Label *exit) 7234514f5e3Sopenharmony_ci{ 7244514f5e3Sopenharmony_ci Label isOverFlow(&builder_); 7254514f5e3Sopenharmony_ci Label notOverFlow(&builder_); 7264514f5e3Sopenharmony_ci GateRef upperBound = builder_.Int32(INT32_MAX); 7274514f5e3Sopenharmony_ci DEFVALUE(taggedVal, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant()); 7284514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32UnsignedLessThanOrEqual(gate, upperBound), ¬OverFlow, &isOverFlow); 7294514f5e3Sopenharmony_ci builder_.Bind(¬OverFlow); 7304514f5e3Sopenharmony_ci taggedVal = builder_.Int32ToTaggedPtr(gate); 7314514f5e3Sopenharmony_ci builder_.Jump(exit); 7324514f5e3Sopenharmony_ci builder_.Bind(&isOverFlow); 7334514f5e3Sopenharmony_ci taggedVal = builder_.DoubleToTaggedDoublePtr(builder_.ChangeUInt32ToFloat64(gate)); 7344514f5e3Sopenharmony_ci builder_.Jump(exit); 7354514f5e3Sopenharmony_ci builder_.Bind(exit); 7364514f5e3Sopenharmony_ci return *taggedVal; 7374514f5e3Sopenharmony_ci} 7384514f5e3Sopenharmony_ci 7394514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertFloat64ToInt32(GateRef gate, Label *exit) 7404514f5e3Sopenharmony_ci{ 7414514f5e3Sopenharmony_ci return builder_.DoubleToInt(gate, exit); 7424514f5e3Sopenharmony_ci} 7434514f5e3Sopenharmony_ci 7444514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertFloat64ToBool(GateRef gate) 7454514f5e3Sopenharmony_ci{ 7464514f5e3Sopenharmony_ci return LogicAndBuilder(builder_.GetCurrentEnvironment()) 7474514f5e3Sopenharmony_ci .And(builder_.DoubleNotEqual(gate, builder_.Double(0.0))) 7484514f5e3Sopenharmony_ci .And(builder_.BoolNot(builder_.DoubleIsNAN(gate))) 7494514f5e3Sopenharmony_ci .Done(); 7504514f5e3Sopenharmony_ci} 7514514f5e3Sopenharmony_ci 7524514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertFloat64ToTaggedDouble(GateRef gate) 7534514f5e3Sopenharmony_ci{ 7544514f5e3Sopenharmony_ci return builder_.DoubleToTaggedDoublePtr(gate); 7554514f5e3Sopenharmony_ci} 7564514f5e3Sopenharmony_ci 7574514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertTaggedIntToInt32(GateRef gate) 7584514f5e3Sopenharmony_ci{ 7594514f5e3Sopenharmony_ci return builder_.GetInt32OfTInt(gate); 7604514f5e3Sopenharmony_ci} 7614514f5e3Sopenharmony_ci 7624514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertTaggedIntToFloat64(GateRef gate) 7634514f5e3Sopenharmony_ci{ 7644514f5e3Sopenharmony_ci return builder_.ChangeInt32ToFloat64(builder_.GetInt32OfTInt(gate)); 7654514f5e3Sopenharmony_ci} 7664514f5e3Sopenharmony_ci 7674514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertTaggedDoubleToInt32(GateRef gate, Label *exit) 7684514f5e3Sopenharmony_ci{ 7694514f5e3Sopenharmony_ci return builder_.DoubleToInt(builder_.GetDoubleOfTDouble(gate), exit); 7704514f5e3Sopenharmony_ci} 7714514f5e3Sopenharmony_ci 7724514f5e3Sopenharmony_ciGateRef MCRLowering::ConvertTaggedDoubleToFloat64(GateRef gate) 7734514f5e3Sopenharmony_ci{ 7744514f5e3Sopenharmony_ci return builder_.GetDoubleOfTDouble(gate); 7754514f5e3Sopenharmony_ci} 7764514f5e3Sopenharmony_ci 7774514f5e3Sopenharmony_civoid MCRLowering::LowerGetGlobalEnv(GateRef gate) 7784514f5e3Sopenharmony_ci{ 7794514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 7804514f5e3Sopenharmony_ci GateRef glueGlobalEnvOffset = builder_.IntPtr(JSThread::GlueData::GetGlueGlobalEnvOffset(false)); 7814514f5e3Sopenharmony_ci GateRef glueGlobalEnv = builder_.Load(VariableType::JS_POINTER(), glue_, glueGlobalEnvOffset); 7824514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, Circuit::NullGate(), builder_.GetDepend(), glueGlobalEnv); 7834514f5e3Sopenharmony_ci} 7844514f5e3Sopenharmony_ci 7854514f5e3Sopenharmony_civoid MCRLowering::LowerGetGlobalEnvObj(GateRef gate) 7864514f5e3Sopenharmony_ci{ 7874514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 7884514f5e3Sopenharmony_ci GateRef globalEnv = acc_.GetValueIn(gate, 0); 7894514f5e3Sopenharmony_ci size_t index = acc_.GetIndex(gate); 7904514f5e3Sopenharmony_ci GateRef offset = builder_.IntPtr(GlobalEnv::HEADER_SIZE + JSTaggedValue::TaggedTypeSize() * index); 7914514f5e3Sopenharmony_ci GateRef object = builder_.Load(VariableType::JS_ANY(), globalEnv, offset); 7924514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, Circuit::NullGate(), builder_.GetDepend(), object); 7934514f5e3Sopenharmony_ci} 7944514f5e3Sopenharmony_ci 7954514f5e3Sopenharmony_civoid MCRLowering::LowerGetGlobalEnvObjHClass(GateRef gate) 7964514f5e3Sopenharmony_ci{ 7974514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 7984514f5e3Sopenharmony_ci GateRef globalEnv = acc_.GetValueIn(gate, 0); 7994514f5e3Sopenharmony_ci size_t index = acc_.GetIndex(gate); 8004514f5e3Sopenharmony_ci GateRef offset = builder_.IntPtr(GlobalEnv::HEADER_SIZE + JSTaggedValue::TaggedTypeSize() * index); 8014514f5e3Sopenharmony_ci GateRef object = builder_.Load(VariableType::JS_ANY(), globalEnv, offset); 8024514f5e3Sopenharmony_ci auto hclass = builder_.Load(VariableType::JS_POINTER(), object, 8034514f5e3Sopenharmony_ci builder_.IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET)); 8044514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, Circuit::NullGate(), builder_.GetDepend(), hclass); 8054514f5e3Sopenharmony_ci} 8064514f5e3Sopenharmony_ci 8074514f5e3Sopenharmony_civoid MCRLowering::LowerGetGlobalConstantValue(GateRef gate) 8084514f5e3Sopenharmony_ci{ 8094514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 8104514f5e3Sopenharmony_ci size_t index = acc_.GetIndex(gate); 8114514f5e3Sopenharmony_ci GateRef gConstAddr = builder_.Load(VariableType::JS_POINTER(), glue_, 8124514f5e3Sopenharmony_ci builder_.IntPtr(JSThread::GlueData::GetGlobalConstOffset(false))); 8134514f5e3Sopenharmony_ci GateRef constantIndex = builder_.IntPtr(JSTaggedValue::TaggedTypeSize() * index); 8144514f5e3Sopenharmony_ci GateRef result = builder_.Load(VariableType::JS_POINTER(), gConstAddr, constantIndex); 8154514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, Circuit::NullGate(), builder_.GetDepend(), result); 8164514f5e3Sopenharmony_ci} 8174514f5e3Sopenharmony_ci 8184514f5e3Sopenharmony_civoid MCRLowering::HeapAllocateInSOld(GateRef gate) 8194514f5e3Sopenharmony_ci{ 8204514f5e3Sopenharmony_ci GateRef size = acc_.GetValueIn(gate, 0); 8214514f5e3Sopenharmony_ci GateRef ret = builder_.CallRuntime(glue_, RTSTUB_ID(AllocateInSOld), Gate::InvalidGateRef, 8224514f5e3Sopenharmony_ci {builder_.ToTaggedInt(size)}, gate); 8234514f5e3Sopenharmony_ci 8244514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), ret); 8254514f5e3Sopenharmony_ci} 8264514f5e3Sopenharmony_ci 8274514f5e3Sopenharmony_civoid MCRLowering::LowerInt32CheckRightIsZero(GateRef gate) 8284514f5e3Sopenharmony_ci{ 8294514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 8304514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 8314514f5e3Sopenharmony_ci GateRef right = acc_.GetValueIn(gate, 0); 8324514f5e3Sopenharmony_ci GateRef rightNotZero = builder_.Int32NotEqual(right, builder_.Int32(0)); 8334514f5e3Sopenharmony_ci builder_.DeoptCheck(rightNotZero, frameState, DeoptType::MODZERO1); 8344514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 8354514f5e3Sopenharmony_ci} 8364514f5e3Sopenharmony_ci 8374514f5e3Sopenharmony_civoid MCRLowering::LowerRemainderIsNegativeZero(GateRef gate) 8384514f5e3Sopenharmony_ci{ 8394514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 8404514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 8414514f5e3Sopenharmony_ci GateRef left = acc_.GetValueIn(gate, 0); 8424514f5e3Sopenharmony_ci GateRef right = acc_.GetValueIn(gate, 1); 8434514f5e3Sopenharmony_ci GateRef remainderIsNegative = LogicAndBuilder(&env) 8444514f5e3Sopenharmony_ci .And(builder_.Int32LessThan(left, builder_.Int32(0))) 8454514f5e3Sopenharmony_ci .And(builder_.Int32Equal(builder_.Int32(0), 8464514f5e3Sopenharmony_ci builder_.BinaryArithmetic(circuit_->Smod(), MachineType::I32, left, right, GateType::NJSValue()))) 8474514f5e3Sopenharmony_ci .Done(); 8484514f5e3Sopenharmony_ci GateRef remainderIsNotNegative = builder_.BoolNot(remainderIsNegative); 8494514f5e3Sopenharmony_ci builder_.DeoptCheck(remainderIsNotNegative, frameState, DeoptType::REMAINDERISNEGATIVEZERO); 8504514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 8514514f5e3Sopenharmony_ci} 8524514f5e3Sopenharmony_ci 8534514f5e3Sopenharmony_civoid MCRLowering::LowerFloat64CheckRightIsZero(GateRef gate) 8544514f5e3Sopenharmony_ci{ 8554514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 8564514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 8574514f5e3Sopenharmony_ci GateRef right = acc_.GetValueIn(gate, 0); 8584514f5e3Sopenharmony_ci GateRef rightNotZero = builder_.DoubleNotEqual(right, builder_.Double(0.0)); 8594514f5e3Sopenharmony_ci builder_.DeoptCheck(rightNotZero, frameState, DeoptType::DIVZERO1); 8604514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 8614514f5e3Sopenharmony_ci} 8624514f5e3Sopenharmony_ci 8634514f5e3Sopenharmony_civoid MCRLowering::LowerLexVarIsHoleCheck(GateRef gate) 8644514f5e3Sopenharmony_ci{ 8654514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 8664514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 8674514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 8684514f5e3Sopenharmony_ci GateRef valueIsNotHole = builder_.TaggedIsNotHole(value); 8694514f5e3Sopenharmony_ci builder_.DeoptCheck(valueIsNotHole, frameState, DeoptType::LEXVARISHOLE1); 8704514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 8714514f5e3Sopenharmony_ci} 8724514f5e3Sopenharmony_ci 8734514f5e3Sopenharmony_civoid MCRLowering::LowerIsUndefinedOrHoleCheck(GateRef gate) 8744514f5e3Sopenharmony_ci{ 8754514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 8764514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 8774514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 8784514f5e3Sopenharmony_ci GateRef isNotUndefinedorHole = builder_.BoolNot(builder_.TaggedIsUndefinedOrHole(value)); 8794514f5e3Sopenharmony_ci builder_.DeoptCheck(isNotUndefinedorHole, frameState, DeoptType::ISUNDEFINEDORHOLE); 8804514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 8814514f5e3Sopenharmony_ci} 8824514f5e3Sopenharmony_ci 8834514f5e3Sopenharmony_civoid MCRLowering::LowerIsNotUndefinedOrHoleCheck(GateRef gate) 8844514f5e3Sopenharmony_ci{ 8854514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 8864514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 8874514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 8884514f5e3Sopenharmony_ci GateRef isUndefinedorHole = builder_.TaggedIsUndefinedOrHole(value); 8894514f5e3Sopenharmony_ci builder_.DeoptCheck(isUndefinedorHole, frameState, DeoptType::ISNOTUNDEFINEDORHOLE); 8904514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 8914514f5e3Sopenharmony_ci} 8924514f5e3Sopenharmony_ci 8934514f5e3Sopenharmony_civoid MCRLowering::LowerIsDataViewCheck(GateRef gate) 8944514f5e3Sopenharmony_ci{ 8954514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 8964514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 8974514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 0); 8984514f5e3Sopenharmony_ci GateRef isDataView = builder_.CheckJSType(obj, JSType::JS_DATA_VIEW); 8994514f5e3Sopenharmony_ci builder_.DeoptCheck(isDataView, frameState, DeoptType::ISNOTDATAVIEW); 9004514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 9014514f5e3Sopenharmony_ci} 9024514f5e3Sopenharmony_ci 9034514f5e3Sopenharmony_civoid MCRLowering::LowerValueCheckNegOverflow(GateRef gate) 9044514f5e3Sopenharmony_ci{ 9054514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 9064514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 9074514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 9084514f5e3Sopenharmony_ci GateRef valueNotZero = builder_.NotEqual(value, builder_.Int32(0)); 9094514f5e3Sopenharmony_ci builder_.DeoptCheck(valueNotZero, frameState, DeoptType::NOTNEGOV1); 9104514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 9114514f5e3Sopenharmony_ci} 9124514f5e3Sopenharmony_ci 9134514f5e3Sopenharmony_civoid MCRLowering::LowerOverflowCheck(GateRef gate) 9144514f5e3Sopenharmony_ci{ 9154514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 9164514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 9174514f5e3Sopenharmony_ci GateRef result = acc_.GetValueIn(gate, 0); 9184514f5e3Sopenharmony_ci GateRef condition = builder_.BoolNot(builder_.ExtractValue(MachineType::I1, result, builder_.Int32(1))); 9194514f5e3Sopenharmony_ci builder_.DeoptCheck(condition, frameState, DeoptType::NOTINT3); 9204514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 9214514f5e3Sopenharmony_ci} 9224514f5e3Sopenharmony_ci 9234514f5e3Sopenharmony_civoid MCRLowering::LowerInt32UnsignedUpperBoundCheck(GateRef gate) 9244514f5e3Sopenharmony_ci{ 9254514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 9264514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 9274514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 9284514f5e3Sopenharmony_ci GateRef upperBound = acc_.GetValueIn(gate, 1); 9294514f5e3Sopenharmony_ci GateRef condition = builder_.Int32UnsignedLessThanOrEqual(value, upperBound); 9304514f5e3Sopenharmony_ci builder_.DeoptCheck(condition, frameState, DeoptType::NOTINT4); 9314514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 9324514f5e3Sopenharmony_ci} 9334514f5e3Sopenharmony_ci 9344514f5e3Sopenharmony_civoid MCRLowering::LowerInt32DivWithCheck(GateRef gate) 9354514f5e3Sopenharmony_ci{ 9364514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 9374514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 9384514f5e3Sopenharmony_ci GateRef left = acc_.GetValueIn(gate, 0); 9394514f5e3Sopenharmony_ci GateRef right = acc_.GetValueIn(gate, 1); 9404514f5e3Sopenharmony_ci GateRef result = Circuit::NullGate(); 9414514f5e3Sopenharmony_ci GateRef condition = LogicOrBuilder(&env) 9424514f5e3Sopenharmony_ci .Or(builder_.Int32GreaterThan(right, builder_.Int32(0))) 9434514f5e3Sopenharmony_ci .Or(builder_.BitAnd(builder_.Int32LessThan(right, builder_.Int32(0)), 9444514f5e3Sopenharmony_ci builder_.Int32NotEqual(left, builder_.Int32(0)))) 9454514f5e3Sopenharmony_ci .Done(); 9464514f5e3Sopenharmony_ci builder_.DeoptCheck(condition, frameState, DeoptType::DIVZERO2); 9474514f5e3Sopenharmony_ci result = builder_.BinaryArithmetic(circuit_->Sdiv(), MachineType::I32, left, right, GateType::NJSValue()); 9484514f5e3Sopenharmony_ci GateRef truncated = builder_.BinaryArithmetic(circuit_->Mul(), 9494514f5e3Sopenharmony_ci MachineType::I32, result, right, GateType::NJSValue()); 9504514f5e3Sopenharmony_ci GateRef overCheck = builder_.Int32Equal(truncated, left); 9514514f5e3Sopenharmony_ci builder_.DeoptCheck(overCheck, frameState, DeoptType::NOTINT5); 9524514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 9534514f5e3Sopenharmony_ci} 9544514f5e3Sopenharmony_ci 9554514f5e3Sopenharmony_civoid MCRLowering::LowerStoreMemory(GateRef gate) 9564514f5e3Sopenharmony_ci{ 9574514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 9584514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 0); 9594514f5e3Sopenharmony_ci GateRef index = acc_.GetValueIn(gate, 1); 9604514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 2); 9614514f5e3Sopenharmony_ci builder_.Store(VariableType::VOID(), glue_, receiver, index, value); 9624514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 9634514f5e3Sopenharmony_ci} 9644514f5e3Sopenharmony_ci 9654514f5e3Sopenharmony_civoid MCRLowering::InitializeWithSpeicalValue(Label *exit, GateRef object, GateRef glue, 9664514f5e3Sopenharmony_ci GateRef value, GateRef start, GateRef end) 9674514f5e3Sopenharmony_ci{ 9684514f5e3Sopenharmony_ci Label begin(&builder_); 9694514f5e3Sopenharmony_ci Label storeValue(&builder_); 9704514f5e3Sopenharmony_ci Label endLoop(&builder_); 9714514f5e3Sopenharmony_ci 9724514f5e3Sopenharmony_ci DEFVALUE(startOffset, (&builder_), VariableType::INT32(), start); 9734514f5e3Sopenharmony_ci builder_.Jump(&begin); 9744514f5e3Sopenharmony_ci builder_.LoopBegin(&begin); 9754514f5e3Sopenharmony_ci { 9764514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32UnsignedLessThan(*startOffset, end), &storeValue, exit); 9774514f5e3Sopenharmony_ci builder_.Bind(&storeValue); 9784514f5e3Sopenharmony_ci { 9794514f5e3Sopenharmony_ci builder_.Store(VariableType::INT64(), glue, object, builder_.ZExtInt32ToPtr(*startOffset), value); 9804514f5e3Sopenharmony_ci startOffset = builder_.Int32Add(*startOffset, builder_.Int32(JSTaggedValue::TaggedTypeSize())); 9814514f5e3Sopenharmony_ci builder_.Jump(&endLoop); 9824514f5e3Sopenharmony_ci } 9834514f5e3Sopenharmony_ci builder_.Bind(&endLoop); 9844514f5e3Sopenharmony_ci builder_.LoopEnd(&begin); 9854514f5e3Sopenharmony_ci } 9864514f5e3Sopenharmony_ci} 9874514f5e3Sopenharmony_ci 9884514f5e3Sopenharmony_civoid MCRLowering::LowerMigrateFromRawValueToHeapValues(GateRef gate) 9894514f5e3Sopenharmony_ci{ 9904514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 9914514f5e3Sopenharmony_ci DEFVALUE(newElements, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 9924514f5e3Sopenharmony_ci Label exit(&builder_); 9934514f5e3Sopenharmony_ci GateRef object = acc_.GetValueIn(gate, 0); 9944514f5e3Sopenharmony_ci GateRef needCOW = acc_.GetValueIn(gate, 1); 9954514f5e3Sopenharmony_ci GateRef isIntKind = acc_.GetValueIn(gate, 2); 9964514f5e3Sopenharmony_ci GateRef elements = builder_.GetElementsArray(object); 9974514f5e3Sopenharmony_ci GateRef length = builder_.GetLengthOfTaggedArray(elements); 9984514f5e3Sopenharmony_ci Label createCOW(&builder_); 9994514f5e3Sopenharmony_ci Label createNormal(&builder_); 10004514f5e3Sopenharmony_ci Label finishElementsInit(&builder_); 10014514f5e3Sopenharmony_ci BRANCH_CIR(needCOW, &createCOW, &createNormal); 10024514f5e3Sopenharmony_ci builder_.Bind(&createCOW); 10034514f5e3Sopenharmony_ci { 10044514f5e3Sopenharmony_ci newElements = builder_.CallRuntime(glue_, RTSTUB_ID(NewCOWTaggedArray), acc_.GetDep(gate), 10054514f5e3Sopenharmony_ci { builder_.Int32ToTaggedPtr(length) }, gate); 10064514f5e3Sopenharmony_ci builder_.Jump(&finishElementsInit); 10074514f5e3Sopenharmony_ci } 10084514f5e3Sopenharmony_ci builder_.Bind(&createNormal); 10094514f5e3Sopenharmony_ci { 10104514f5e3Sopenharmony_ci newElements = builder_.CallRuntime(glue_, RTSTUB_ID(NewTaggedArray), acc_.GetDep(gate), 10114514f5e3Sopenharmony_ci { builder_.Int32ToTaggedPtr(length) }, gate); 10124514f5e3Sopenharmony_ci builder_.Jump(&finishElementsInit); 10134514f5e3Sopenharmony_ci } 10144514f5e3Sopenharmony_ci builder_.Bind(&finishElementsInit); 10154514f5e3Sopenharmony_ci 10164514f5e3Sopenharmony_ci DEFVALUE(index, (&builder_), VariableType::INT32(), builder_.Int32(0)); 10174514f5e3Sopenharmony_ci Label loopHead(&builder_); 10184514f5e3Sopenharmony_ci Label loopEnd(&builder_); 10194514f5e3Sopenharmony_ci Label afterLoop(&builder_); 10204514f5e3Sopenharmony_ci Label storeValue(&builder_); 10214514f5e3Sopenharmony_ci builder_.Jump(&loopHead); 10224514f5e3Sopenharmony_ci builder_.LoopBegin(&loopHead); 10234514f5e3Sopenharmony_ci { 10244514f5e3Sopenharmony_ci Label storeHole(&builder_); 10254514f5e3Sopenharmony_ci Label storeNormalValue(&builder_); 10264514f5e3Sopenharmony_ci Label finishStore(&builder_); 10274514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32UnsignedLessThan(*index, length), &storeValue, &afterLoop); 10284514f5e3Sopenharmony_ci builder_.Bind(&storeValue); 10294514f5e3Sopenharmony_ci { 10304514f5e3Sopenharmony_ci Label rawValueIsInt(&builder_); 10314514f5e3Sopenharmony_ci Label rawValueIsNumber(&builder_); 10324514f5e3Sopenharmony_ci GateRef value = builder_.GetValueFromJSArrayWithElementsKind(VariableType::INT64(), elements, *index); 10334514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsSpecialHole(value), &storeHole, &storeNormalValue); 10344514f5e3Sopenharmony_ci builder_.Bind(&storeHole); 10354514f5e3Sopenharmony_ci { 10364514f5e3Sopenharmony_ci builder_.SetValueToTaggedArray(VariableType::JS_ANY(), glue_, *newElements, *index, builder_.Hole()); 10374514f5e3Sopenharmony_ci builder_.Jump(&finishStore); 10384514f5e3Sopenharmony_ci } 10394514f5e3Sopenharmony_ci builder_.Bind(&storeNormalValue); 10404514f5e3Sopenharmony_ci { 10414514f5e3Sopenharmony_ci BRANCH_CIR(isIntKind, &rawValueIsInt, &rawValueIsNumber); 10424514f5e3Sopenharmony_ci builder_.Bind(&rawValueIsInt); 10434514f5e3Sopenharmony_ci { 10444514f5e3Sopenharmony_ci GateRef convertedInt = builder_.ToTaggedIntPtr(value); 10454514f5e3Sopenharmony_ci builder_.SetValueToTaggedArray(VariableType::JS_ANY(), glue_, *newElements, *index, convertedInt); 10464514f5e3Sopenharmony_ci builder_.Jump(&finishStore); 10474514f5e3Sopenharmony_ci } 10484514f5e3Sopenharmony_ci builder_.Bind(&rawValueIsNumber); 10494514f5e3Sopenharmony_ci { 10504514f5e3Sopenharmony_ci GateRef tmpDouble = builder_.CastInt64ToFloat64(value); 10514514f5e3Sopenharmony_ci GateRef convertedDouble = builder_.DoubleToTaggedDoublePtr(tmpDouble); 10524514f5e3Sopenharmony_ci builder_.SetValueToTaggedArray(VariableType::JS_ANY(), glue_, *newElements, 10534514f5e3Sopenharmony_ci *index, convertedDouble); 10544514f5e3Sopenharmony_ci builder_.Jump(&finishStore); 10554514f5e3Sopenharmony_ci } 10564514f5e3Sopenharmony_ci } 10574514f5e3Sopenharmony_ci builder_.Bind(&finishStore); 10584514f5e3Sopenharmony_ci { 10594514f5e3Sopenharmony_ci index = builder_.Int32Add(*index, builder_.Int32(1)); 10604514f5e3Sopenharmony_ci builder_.Jump(&loopEnd); 10614514f5e3Sopenharmony_ci } 10624514f5e3Sopenharmony_ci } 10634514f5e3Sopenharmony_ci } 10644514f5e3Sopenharmony_ci builder_.Bind(&loopEnd); 10654514f5e3Sopenharmony_ci builder_.LoopEnd(&loopHead); 10664514f5e3Sopenharmony_ci builder_.Bind(&afterLoop); 10674514f5e3Sopenharmony_ci { 10684514f5e3Sopenharmony_ci builder_.Jump(&exit); 10694514f5e3Sopenharmony_ci } 10704514f5e3Sopenharmony_ci builder_.Bind(&exit); 10714514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *newElements); 10724514f5e3Sopenharmony_ci} 10734514f5e3Sopenharmony_ci 10744514f5e3Sopenharmony_civoid MCRLowering::LowerMigrateFromHeapValueToRawValue(GateRef gate) 10754514f5e3Sopenharmony_ci{ 10764514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 10774514f5e3Sopenharmony_ci DEFVALUE(newElements, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 10784514f5e3Sopenharmony_ci Label exit(&builder_); 10794514f5e3Sopenharmony_ci GateRef object = acc_.GetValueIn(gate, 0); 10804514f5e3Sopenharmony_ci GateRef needCOW = acc_.GetValueIn(gate, 1); 10814514f5e3Sopenharmony_ci GateRef isIntKind = acc_.GetValueIn(gate, 2); 10824514f5e3Sopenharmony_ci 10834514f5e3Sopenharmony_ci GateRef elements = builder_.GetElementsArray(object); 10844514f5e3Sopenharmony_ci GateRef length = builder_.GetLengthOfTaggedArray(elements); 10854514f5e3Sopenharmony_ci Label createCOW(&builder_); 10864514f5e3Sopenharmony_ci Label createNormal(&builder_); 10874514f5e3Sopenharmony_ci Label finishElementsInit(&builder_); 10884514f5e3Sopenharmony_ci BRANCH_CIR(needCOW, &createCOW, &createNormal); 10894514f5e3Sopenharmony_ci builder_.Bind(&createCOW); 10904514f5e3Sopenharmony_ci { 10914514f5e3Sopenharmony_ci newElements = builder_.CallRuntime(glue_, RTSTUB_ID(NewCOWMutantTaggedArray), acc_.GetDep(gate), 10924514f5e3Sopenharmony_ci { builder_.Int32ToTaggedPtr(length) }, gate); 10934514f5e3Sopenharmony_ci builder_.Jump(&finishElementsInit); 10944514f5e3Sopenharmony_ci } 10954514f5e3Sopenharmony_ci builder_.Bind(&createNormal); 10964514f5e3Sopenharmony_ci { 10974514f5e3Sopenharmony_ci newElements = builder_.CallRuntime(glue_, RTSTUB_ID(NewMutantTaggedArray), acc_.GetDep(gate), 10984514f5e3Sopenharmony_ci { builder_.Int32ToTaggedPtr(length) }, gate); 10994514f5e3Sopenharmony_ci builder_.Jump(&finishElementsInit); 11004514f5e3Sopenharmony_ci } 11014514f5e3Sopenharmony_ci builder_.Bind(&finishElementsInit); 11024514f5e3Sopenharmony_ci 11034514f5e3Sopenharmony_ci DEFVALUE(index, (&builder_), VariableType::INT32(), builder_.Int32(0)); 11044514f5e3Sopenharmony_ci Label loopHead(&builder_); 11054514f5e3Sopenharmony_ci Label loopEnd(&builder_); 11064514f5e3Sopenharmony_ci Label afterLoop(&builder_); 11074514f5e3Sopenharmony_ci Label storeValue(&builder_); 11084514f5e3Sopenharmony_ci builder_.Jump(&loopHead); 11094514f5e3Sopenharmony_ci builder_.LoopBegin(&loopHead); 11104514f5e3Sopenharmony_ci { 11114514f5e3Sopenharmony_ci Label storeSpecialHole(&builder_); 11124514f5e3Sopenharmony_ci Label storeNormalValue(&builder_); 11134514f5e3Sopenharmony_ci Label finishStore(&builder_); 11144514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32UnsignedLessThan(*index, length), &storeValue, &afterLoop); 11154514f5e3Sopenharmony_ci builder_.Bind(&storeValue); 11164514f5e3Sopenharmony_ci { 11174514f5e3Sopenharmony_ci Label convertToInt(&builder_); 11184514f5e3Sopenharmony_ci Label convertToDouble(&builder_); 11194514f5e3Sopenharmony_ci GateRef value = builder_.GetValueFromTaggedArray(elements, *index); 11204514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsHole(value), &storeSpecialHole, &storeNormalValue); 11214514f5e3Sopenharmony_ci builder_.Bind(&storeSpecialHole); 11224514f5e3Sopenharmony_ci { 11234514f5e3Sopenharmony_ci builder_.SetValueToTaggedArray(VariableType::INT64(), glue_, *newElements, 11244514f5e3Sopenharmony_ci *index, builder_.SpecialHoleConstant()); 11254514f5e3Sopenharmony_ci builder_.Jump(&finishStore); 11264514f5e3Sopenharmony_ci } 11274514f5e3Sopenharmony_ci builder_.Bind(&storeNormalValue); 11284514f5e3Sopenharmony_ci { 11294514f5e3Sopenharmony_ci Label valueIsInt(&builder_); 11304514f5e3Sopenharmony_ci Label valueIsDouble(&builder_); 11314514f5e3Sopenharmony_ci BRANCH_CIR(isIntKind, &convertToInt, &convertToDouble); 11324514f5e3Sopenharmony_ci builder_.Bind(&convertToInt); 11334514f5e3Sopenharmony_ci { 11344514f5e3Sopenharmony_ci GateRef convertedInt = builder_.GetInt64OfTInt(value); 11354514f5e3Sopenharmony_ci builder_.SetValueToTaggedArray(VariableType::INT64(), glue_, *newElements, *index, convertedInt); 11364514f5e3Sopenharmony_ci builder_.Jump(&finishStore); 11374514f5e3Sopenharmony_ci } 11384514f5e3Sopenharmony_ci builder_.Bind(&convertToDouble); 11394514f5e3Sopenharmony_ci { 11404514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsInt(value), &valueIsInt, &valueIsDouble); 11414514f5e3Sopenharmony_ci builder_.Bind(&valueIsInt); 11424514f5e3Sopenharmony_ci { 11434514f5e3Sopenharmony_ci GateRef convertedDoubleFromTInt = builder_.CastDoubleToInt64(builder_.GetDoubleOfTInt(value)); 11444514f5e3Sopenharmony_ci builder_.SetValueToTaggedArray(VariableType::INT64(), glue_, *newElements, *index, 11454514f5e3Sopenharmony_ci convertedDoubleFromTInt); 11464514f5e3Sopenharmony_ci builder_.Jump(&finishStore); 11474514f5e3Sopenharmony_ci } 11484514f5e3Sopenharmony_ci builder_.Bind(&valueIsDouble); 11494514f5e3Sopenharmony_ci { 11504514f5e3Sopenharmony_ci GateRef doubleValue = builder_.GetDoubleOfTDouble(value); 11514514f5e3Sopenharmony_ci GateRef convertedDoubleFromTDouble = builder_.CastDoubleToInt64(doubleValue); 11524514f5e3Sopenharmony_ci builder_.SetValueToTaggedArray(VariableType::INT64(), glue_, *newElements, *index, 11534514f5e3Sopenharmony_ci convertedDoubleFromTDouble); 11544514f5e3Sopenharmony_ci builder_.Jump(&finishStore); 11554514f5e3Sopenharmony_ci } 11564514f5e3Sopenharmony_ci } 11574514f5e3Sopenharmony_ci } 11584514f5e3Sopenharmony_ci builder_.Bind(&finishStore); 11594514f5e3Sopenharmony_ci { 11604514f5e3Sopenharmony_ci index = builder_.Int32Add(*index, builder_.Int32(1)); 11614514f5e3Sopenharmony_ci builder_.Jump(&loopEnd); 11624514f5e3Sopenharmony_ci } 11634514f5e3Sopenharmony_ci } 11644514f5e3Sopenharmony_ci } 11654514f5e3Sopenharmony_ci builder_.Bind(&loopEnd); 11664514f5e3Sopenharmony_ci builder_.LoopEnd(&loopHead); 11674514f5e3Sopenharmony_ci builder_.Bind(&afterLoop); 11684514f5e3Sopenharmony_ci { 11694514f5e3Sopenharmony_ci builder_.Jump(&exit); 11704514f5e3Sopenharmony_ci } 11714514f5e3Sopenharmony_ci 11724514f5e3Sopenharmony_ci builder_.Bind(&exit); 11734514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *newElements); 11744514f5e3Sopenharmony_ci} 11754514f5e3Sopenharmony_ci 11764514f5e3Sopenharmony_civoid MCRLowering::LowerMigrateFromHoleIntToHoleNumber(GateRef gate) 11774514f5e3Sopenharmony_ci{ 11784514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 11794514f5e3Sopenharmony_ci GateRef object = acc_.GetValueIn(gate, 0); 11804514f5e3Sopenharmony_ci Label exit(&builder_); 11814514f5e3Sopenharmony_ci GateRef elements = builder_.GetElementsArray(object); 11824514f5e3Sopenharmony_ci GateRef length = builder_.GetLengthOfTaggedArray(elements); 11834514f5e3Sopenharmony_ci DEFVALUE(index, (&builder_), VariableType::INT32(), builder_.Int32(0)); 11844514f5e3Sopenharmony_ci Label loopHead(&builder_); 11854514f5e3Sopenharmony_ci Label loopEnd(&builder_); 11864514f5e3Sopenharmony_ci Label afterLoop(&builder_); 11874514f5e3Sopenharmony_ci Label storeValue(&builder_); 11884514f5e3Sopenharmony_ci builder_.Jump(&loopHead); 11894514f5e3Sopenharmony_ci builder_.LoopBegin(&loopHead); 11904514f5e3Sopenharmony_ci { 11914514f5e3Sopenharmony_ci Label storeNormalValue(&builder_); 11924514f5e3Sopenharmony_ci Label finishStore(&builder_); 11934514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32UnsignedLessThan(*index, length), &storeValue, &afterLoop); 11944514f5e3Sopenharmony_ci builder_.Bind(&storeValue); 11954514f5e3Sopenharmony_ci { 11964514f5e3Sopenharmony_ci GateRef value = builder_.GetValueFromTaggedArray(VariableType::INT64(), elements, *index); 11974514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsSpecialHole(value), &finishStore, &storeNormalValue); 11984514f5e3Sopenharmony_ci builder_.Bind(&storeNormalValue); 11994514f5e3Sopenharmony_ci { 12004514f5e3Sopenharmony_ci GateRef intVal = builder_.TruncInt64ToInt32(value); 12014514f5e3Sopenharmony_ci GateRef convertedValue = builder_.CastDoubleToInt64(builder_.ChangeInt32ToFloat64(intVal)); 12024514f5e3Sopenharmony_ci builder_.SetValueToTaggedArray(VariableType::INT64(), glue_, elements, *index, 12034514f5e3Sopenharmony_ci convertedValue); 12044514f5e3Sopenharmony_ci builder_.Jump(&finishStore); 12054514f5e3Sopenharmony_ci } 12064514f5e3Sopenharmony_ci builder_.Bind(&finishStore); 12074514f5e3Sopenharmony_ci { 12084514f5e3Sopenharmony_ci index = builder_.Int32Add(*index, builder_.Int32(1)); 12094514f5e3Sopenharmony_ci builder_.Jump(&loopEnd); 12104514f5e3Sopenharmony_ci } 12114514f5e3Sopenharmony_ci } 12124514f5e3Sopenharmony_ci } 12134514f5e3Sopenharmony_ci builder_.Bind(&loopEnd); 12144514f5e3Sopenharmony_ci builder_.LoopEnd(&loopHead); 12154514f5e3Sopenharmony_ci builder_.Bind(&afterLoop); 12164514f5e3Sopenharmony_ci { 12174514f5e3Sopenharmony_ci builder_.Jump(&exit); 12184514f5e3Sopenharmony_ci } 12194514f5e3Sopenharmony_ci 12204514f5e3Sopenharmony_ci builder_.Bind(&exit); 12214514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 12224514f5e3Sopenharmony_ci} 12234514f5e3Sopenharmony_ci 12244514f5e3Sopenharmony_civoid MCRLowering::LowerMigrateFromHoleNumberToHoleInt(GateRef gate) 12254514f5e3Sopenharmony_ci{ 12264514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 12274514f5e3Sopenharmony_ci GateRef object = acc_.GetValueIn(gate, 0); 12284514f5e3Sopenharmony_ci Label exit(&builder_); 12294514f5e3Sopenharmony_ci GateRef elements = builder_.GetElementsArray(object); 12304514f5e3Sopenharmony_ci GateRef length = builder_.GetLengthOfTaggedArray(elements); 12314514f5e3Sopenharmony_ci DEFVALUE(index, (&builder_), VariableType::INT32(), builder_.Int32(0)); 12324514f5e3Sopenharmony_ci Label loopHead(&builder_); 12334514f5e3Sopenharmony_ci Label loopEnd(&builder_); 12344514f5e3Sopenharmony_ci Label afterLoop(&builder_); 12354514f5e3Sopenharmony_ci Label storeValue(&builder_); 12364514f5e3Sopenharmony_ci builder_.Jump(&loopHead); 12374514f5e3Sopenharmony_ci builder_.LoopBegin(&loopHead); 12384514f5e3Sopenharmony_ci { 12394514f5e3Sopenharmony_ci Label storeNormalValue(&builder_); 12404514f5e3Sopenharmony_ci Label finishStore(&builder_); 12414514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32UnsignedLessThan(*index, length), &storeValue, &afterLoop); 12424514f5e3Sopenharmony_ci builder_.Bind(&storeValue); 12434514f5e3Sopenharmony_ci { 12444514f5e3Sopenharmony_ci GateRef value = builder_.GetValueFromTaggedArray(VariableType::INT64(), elements, *index); 12454514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsSpecialHole(value), &finishStore, &storeNormalValue); 12464514f5e3Sopenharmony_ci builder_.Bind(&storeNormalValue); 12474514f5e3Sopenharmony_ci { 12484514f5e3Sopenharmony_ci GateRef doubleVal = builder_.CastInt64ToFloat64(value); 12494514f5e3Sopenharmony_ci GateRef convertedValue = builder_.SExtInt32ToInt64(builder_.ChangeFloat64ToInt32(doubleVal)); 12504514f5e3Sopenharmony_ci builder_.SetValueToTaggedArray(VariableType::INT64(), glue_, elements, *index, 12514514f5e3Sopenharmony_ci convertedValue); 12524514f5e3Sopenharmony_ci builder_.Jump(&finishStore); 12534514f5e3Sopenharmony_ci } 12544514f5e3Sopenharmony_ci builder_.Bind(&finishStore); 12554514f5e3Sopenharmony_ci { 12564514f5e3Sopenharmony_ci index = builder_.Int32Add(*index, builder_.Int32(1)); 12574514f5e3Sopenharmony_ci builder_.Jump(&loopEnd); 12584514f5e3Sopenharmony_ci } 12594514f5e3Sopenharmony_ci } 12604514f5e3Sopenharmony_ci } 12614514f5e3Sopenharmony_ci builder_.Bind(&loopEnd); 12624514f5e3Sopenharmony_ci builder_.LoopEnd(&loopHead); 12634514f5e3Sopenharmony_ci builder_.Bind(&afterLoop); 12644514f5e3Sopenharmony_ci { 12654514f5e3Sopenharmony_ci builder_.Jump(&exit); 12664514f5e3Sopenharmony_ci } 12674514f5e3Sopenharmony_ci 12684514f5e3Sopenharmony_ci builder_.Bind(&exit); 12694514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 12704514f5e3Sopenharmony_ci} 12714514f5e3Sopenharmony_ci 12724514f5e3Sopenharmony_civoid MCRLowering::LowerHeapObjectIsEcmaObject(GateRef gate) 12734514f5e3Sopenharmony_ci{ 12744514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 12754514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 12764514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 12774514f5e3Sopenharmony_ci 12784514f5e3Sopenharmony_ci GateRef isEcmaObject = builder_.TaggedObjectIsEcmaObject(value); 12794514f5e3Sopenharmony_ci builder_.DeoptCheck(isEcmaObject, frameState, DeoptType::NOT_ECMA_OBJECT); 12804514f5e3Sopenharmony_ci 12814514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 12824514f5e3Sopenharmony_ci} 12834514f5e3Sopenharmony_ci 12844514f5e3Sopenharmony_civoid MCRLowering::LowerIsCallableCheck(GateRef gate) 12854514f5e3Sopenharmony_ci{ 12864514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 12874514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, 0); 12884514f5e3Sopenharmony_ci GateRef frameState = acc_.GetFrameState(gate); 12894514f5e3Sopenharmony_ci GateRef isCallable = LogicAndBuilder(&env).And(builder_.TaggedIsHeapObject(func)) 12904514f5e3Sopenharmony_ci .And(builder_.IsCallable(func)).Done(); 12914514f5e3Sopenharmony_ci builder_.DeoptCheck(isCallable, frameState, DeoptType::NOTCALLABLE); 12924514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 12934514f5e3Sopenharmony_ci} 12944514f5e3Sopenharmony_ci} // namespace panda::ecmascript 1295