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#ifndef ECMASCRIPT_COMPILER_LCR_CIRCUIT_BUILDER_H
174514f5e3Sopenharmony_ci#define ECMASCRIPT_COMPILER_LCR_CIRCUIT_BUILDER_H
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit_builder.h"
204514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit_builder_helper.h"
214514f5e3Sopenharmony_ci#include "ecmascript/compiler/share_gate_meta_data.h"
224514f5e3Sopenharmony_ci
234514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu {
244514f5e3Sopenharmony_ci
254514f5e3Sopenharmony_ciGateRef CircuitBuilder::Int8Equal(GateRef x, GateRef y)
264514f5e3Sopenharmony_ci{
274514f5e3Sopenharmony_ci    return Equal(x, y);
284514f5e3Sopenharmony_ci}
294514f5e3Sopenharmony_ci
304514f5e3Sopenharmony_ciGateRef CircuitBuilder::Int32NotEqual(GateRef x, GateRef y)
314514f5e3Sopenharmony_ci{
324514f5e3Sopenharmony_ci    return NotEqual(x, y);
334514f5e3Sopenharmony_ci}
344514f5e3Sopenharmony_ci
354514f5e3Sopenharmony_ciGateRef CircuitBuilder::Int64NotEqual(GateRef x, GateRef y)
364514f5e3Sopenharmony_ci{
374514f5e3Sopenharmony_ci    return NotEqual(x, y);
384514f5e3Sopenharmony_ci}
394514f5e3Sopenharmony_ci
404514f5e3Sopenharmony_ciGateRef CircuitBuilder::Int64Equal(GateRef x, GateRef y)
414514f5e3Sopenharmony_ci{
424514f5e3Sopenharmony_ci    return Equal(x, y);
434514f5e3Sopenharmony_ci}
444514f5e3Sopenharmony_ci
454514f5e3Sopenharmony_ciGateRef CircuitBuilder::Int32Equal(GateRef x, GateRef y)
464514f5e3Sopenharmony_ci{
474514f5e3Sopenharmony_ci    return Equal(x, y);
484514f5e3Sopenharmony_ci}
494514f5e3Sopenharmony_ci
504514f5e3Sopenharmony_ciGateRef CircuitBuilder::IntPtrGreaterThan(GateRef x, GateRef y)
514514f5e3Sopenharmony_ci{
524514f5e3Sopenharmony_ci    return env_->Is32Bit() ? Int32GreaterThan(x, y) : Int64GreaterThan(x, y);
534514f5e3Sopenharmony_ci}
544514f5e3Sopenharmony_ci
554514f5e3Sopenharmony_ciGateRef CircuitBuilder::IntPtrAnd(GateRef x, GateRef y)
564514f5e3Sopenharmony_ci{
574514f5e3Sopenharmony_ci    return env_->Is32Bit() ? Int32And(x, y) : Int64And(x, y);
584514f5e3Sopenharmony_ci}
594514f5e3Sopenharmony_ci
604514f5e3Sopenharmony_ciGateRef CircuitBuilder::IntPtrNot(GateRef x)
614514f5e3Sopenharmony_ci{
624514f5e3Sopenharmony_ci    return env_->Is32Bit() ? Int32Not(x) : Int64Not(x);
634514f5e3Sopenharmony_ci}
644514f5e3Sopenharmony_ci
654514f5e3Sopenharmony_ciGateRef CircuitBuilder::IntPtrEqual(GateRef x, GateRef y)
664514f5e3Sopenharmony_ci{
674514f5e3Sopenharmony_ci    return env_->Is32Bit() ? Int32Equal(x, y) : Int64Equal(x, y);
684514f5e3Sopenharmony_ci}
694514f5e3Sopenharmony_ci
704514f5e3Sopenharmony_ciGateRef CircuitBuilder::IntPtrLSR(GateRef x, GateRef y)
714514f5e3Sopenharmony_ci{
724514f5e3Sopenharmony_ci    auto ptrSize = env_->Is32Bit() ? MachineType::I32 : MachineType::I64;
734514f5e3Sopenharmony_ci    return BinaryArithmetic(circuit_->Lsr(), ptrSize, x, y);
744514f5e3Sopenharmony_ci}
754514f5e3Sopenharmony_ci
764514f5e3Sopenharmony_ciGateRef CircuitBuilder::IntPtrLSL(GateRef x, GateRef y)
774514f5e3Sopenharmony_ci{
784514f5e3Sopenharmony_ci    auto ptrSize = env_->Is32Bit() ? MachineType::I32 : MachineType::I64;
794514f5e3Sopenharmony_ci    return BinaryArithmetic(circuit_->Lsl(), ptrSize, x, y);
804514f5e3Sopenharmony_ci}
814514f5e3Sopenharmony_ci
824514f5e3Sopenharmony_ciGateRef CircuitBuilder::Int16ToBigEndianInt16(GateRef x)
834514f5e3Sopenharmony_ci{
844514f5e3Sopenharmony_ci    GateRef int16toint32 = ZExtInt16ToInt32(x);
854514f5e3Sopenharmony_ci    GateRef high8bits = Int32LSL(Int32And(int16toint32, Int32(0x00FF)), Int32(8));
864514f5e3Sopenharmony_ci    GateRef low8bits = Int32LSR(Int32And(int16toint32, Int32(0xFF00)), Int32(8));
874514f5e3Sopenharmony_ci    return TruncInt32ToInt16(Int32Add(high8bits, low8bits));
884514f5e3Sopenharmony_ci}
894514f5e3Sopenharmony_ci
904514f5e3Sopenharmony_ciGateRef CircuitBuilder::Int32ToBigEndianInt32(GateRef x)
914514f5e3Sopenharmony_ci{
924514f5e3Sopenharmony_ci    GateRef first8bits = Int32LSL(Int32And(x, Int32(0x000000FF)), Int32(24));
934514f5e3Sopenharmony_ci    GateRef second8bits = Int32LSL(Int32And(x, Int32(0x0000FF00)), Int32(8));
944514f5e3Sopenharmony_ci    GateRef third8bits = Int32LSR(Int32And(x, Int32(0x00FF0000)), Int32(8));
954514f5e3Sopenharmony_ci    GateRef fourth8bits = Int32LSR(Int32And(x, Int32(0xFF000000)), Int32(24));
964514f5e3Sopenharmony_ci    GateRef firstHalf = Int32Add(first8bits, second8bits);
974514f5e3Sopenharmony_ci    GateRef secondHalf = Int32Add(third8bits, fourth8bits);
984514f5e3Sopenharmony_ci    return Int32Add(firstHalf, secondHalf);
994514f5e3Sopenharmony_ci}
1004514f5e3Sopenharmony_ci
1014514f5e3Sopenharmony_ciGateRef CircuitBuilder::Int64ToBigEndianInt64(GateRef x)
1024514f5e3Sopenharmony_ci{
1034514f5e3Sopenharmony_ci    GateRef first8bits = Int64LSL(Int64And(x, Int64(0x00000000000000FF)), Int64(56));
1044514f5e3Sopenharmony_ci    GateRef second8bits = Int64LSL(Int64And(x, Int64(0x000000000000FF00)), Int64(40));
1054514f5e3Sopenharmony_ci    // 0-16bits
1064514f5e3Sopenharmony_ci    GateRef first16bits = Int64Add(first8bits, second8bits);
1074514f5e3Sopenharmony_ci    GateRef third8bits = Int64LSL(Int64And(x, Int64(0x0000000000FF0000)), Int64(24));
1084514f5e3Sopenharmony_ci    GateRef fourth8bits = Int64LSL(Int64And(x, Int64(0x00000000FF000000)), Int64(8));
1094514f5e3Sopenharmony_ci    // 16-32bits
1104514f5e3Sopenharmony_ci    GateRef second16bits = Int64Add(third8bits, fourth8bits);
1114514f5e3Sopenharmony_ci    // 0-32bits
1124514f5e3Sopenharmony_ci    GateRef firstHalf = Int64Add(first16bits, second16bits);
1134514f5e3Sopenharmony_ci    GateRef fifth8bits = Int64LSR(Int64And(x, Int64(0x000000FF00000000)), Int64(8));
1144514f5e3Sopenharmony_ci    GateRef sixth8bits = Int64LSR(Int64And(x, Int64(0x0000FF0000000000)), Int64(24));
1154514f5e3Sopenharmony_ci    //32-48bits
1164514f5e3Sopenharmony_ci    GateRef third16bits = Int64Add(fifth8bits, sixth8bits);
1174514f5e3Sopenharmony_ci    GateRef seventh8bits = Int64LSR(Int64And(x, Int64(0x00FF000000000000)), Int64(40));
1184514f5e3Sopenharmony_ci    GateRef eighth8bits = Int64LSR(Int64And(x, Int64(0xFF00000000000000)), Int64(56));
1194514f5e3Sopenharmony_ci    //48-64bits
1204514f5e3Sopenharmony_ci    GateRef fourth16bits = Int64Add(seventh8bits, eighth8bits);
1214514f5e3Sopenharmony_ci    //32-64bits
1224514f5e3Sopenharmony_ci    GateRef secondHalf = Int64Add(third16bits, fourth16bits);
1234514f5e3Sopenharmony_ci    //0-64bits
1244514f5e3Sopenharmony_ci    return Int64Add(firstHalf, secondHalf);
1254514f5e3Sopenharmony_ci}
1264514f5e3Sopenharmony_ci
1274514f5e3Sopenharmony_ciGateRef CircuitBuilder::IntPtrOr(GateRef x, GateRef y)
1284514f5e3Sopenharmony_ci{
1294514f5e3Sopenharmony_ci    auto ptrsize = env_->Is32Bit() ? MachineType::I32 : MachineType::I64;
1304514f5e3Sopenharmony_ci    return BinaryArithmetic(circuit_->Or(), ptrsize, x, y);
1314514f5e3Sopenharmony_ci}
1324514f5e3Sopenharmony_ci
1334514f5e3Sopenharmony_ciGateRef CircuitBuilder::IntPtrDiv(GateRef x, GateRef y)
1344514f5e3Sopenharmony_ci{
1354514f5e3Sopenharmony_ci    return env_->Is32Bit() ? Int32Div(x, y) : Int64Div(x, y);
1364514f5e3Sopenharmony_ci}
1374514f5e3Sopenharmony_ci
1384514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetInt64OfTInt(GateRef x)
1394514f5e3Sopenharmony_ci{
1404514f5e3Sopenharmony_ci    GateRef tagged = ChangeTaggedPointerToInt64(x);
1414514f5e3Sopenharmony_ci    return Int64And(tagged, Int64(~JSTaggedValue::TAG_MARK));
1424514f5e3Sopenharmony_ci}
1434514f5e3Sopenharmony_ci
1444514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetInt32OfTInt(GateRef x)
1454514f5e3Sopenharmony_ci{
1464514f5e3Sopenharmony_ci    GateRef tagged = ChangeTaggedPointerToInt64(x);
1474514f5e3Sopenharmony_ci    return TruncInt64ToInt32(tagged);
1484514f5e3Sopenharmony_ci}
1494514f5e3Sopenharmony_ci
1504514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetInt32OfTNumber(GateRef x)
1514514f5e3Sopenharmony_ci{
1524514f5e3Sopenharmony_ci    Label subentry(env_);
1534514f5e3Sopenharmony_ci    SubCfgEntry(&subentry);
1544514f5e3Sopenharmony_ci    Label isInt(env_);
1554514f5e3Sopenharmony_ci    Label isDouble(env_);
1564514f5e3Sopenharmony_ci    Label exit(env_);
1574514f5e3Sopenharmony_ci    DEFVALUE(result, env_, VariableType::INT32(), Int32(0));
1584514f5e3Sopenharmony_ci    BRANCH_CIR2(TaggedIsInt(x), &isInt, &isDouble);
1594514f5e3Sopenharmony_ci    Bind(&isInt);
1604514f5e3Sopenharmony_ci    {
1614514f5e3Sopenharmony_ci        result = GetInt32OfTInt(x);
1624514f5e3Sopenharmony_ci        Jump(&exit);
1634514f5e3Sopenharmony_ci    }
1644514f5e3Sopenharmony_ci    Bind(&isDouble);
1654514f5e3Sopenharmony_ci    {
1664514f5e3Sopenharmony_ci        result = DoubleCheckINFInRangeInt32(GetDoubleOfTDouble(x));
1674514f5e3Sopenharmony_ci        Jump(&exit);
1684514f5e3Sopenharmony_ci    }
1694514f5e3Sopenharmony_ci    Bind(&exit);
1704514f5e3Sopenharmony_ci    GateRef ret = *result;
1714514f5e3Sopenharmony_ci    SubCfgExit();
1724514f5e3Sopenharmony_ci    return ret;
1734514f5e3Sopenharmony_ci}
1744514f5e3Sopenharmony_ci
1754514f5e3Sopenharmony_ciGateRef CircuitBuilder::TaggedCastToIntPtr(GateRef x)
1764514f5e3Sopenharmony_ci{
1774514f5e3Sopenharmony_ci    return env_->Is32Bit() ? GetInt32OfTInt(x) : GetInt64OfTInt(x);
1784514f5e3Sopenharmony_ci}
1794514f5e3Sopenharmony_ci
1804514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetDoubleOfTInt(GateRef x)
1814514f5e3Sopenharmony_ci{
1824514f5e3Sopenharmony_ci    return ChangeInt32ToFloat64(GetInt32OfTInt(x));
1834514f5e3Sopenharmony_ci}
1844514f5e3Sopenharmony_ci
1854514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetDoubleOfTDouble(GateRef x)
1864514f5e3Sopenharmony_ci{
1874514f5e3Sopenharmony_ci    GateRef tagged = ChangeTaggedPointerToInt64(x);
1884514f5e3Sopenharmony_ci    GateRef val = Int64Sub(tagged, Int64(JSTaggedValue::DOUBLE_ENCODE_OFFSET));
1894514f5e3Sopenharmony_ci    return CastInt64ToFloat64(val);
1904514f5e3Sopenharmony_ci}
1914514f5e3Sopenharmony_ci
1924514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetBooleanOfTBoolean(GateRef x)
1934514f5e3Sopenharmony_ci{
1944514f5e3Sopenharmony_ci    GateRef tagged = ChangeTaggedPointerToInt64(x);
1954514f5e3Sopenharmony_ci    return TruncInt64ToInt1(tagged);
1964514f5e3Sopenharmony_ci}
1974514f5e3Sopenharmony_ci
1984514f5e3Sopenharmony_ciGateRef CircuitBuilder::Int32ToTaggedInt(GateRef x)
1994514f5e3Sopenharmony_ci{
2004514f5e3Sopenharmony_ci    GateRef val = SExtInt32ToInt64(x);
2014514f5e3Sopenharmony_ci    return Int64Or(val, Int64(JSTaggedValue::TAG_INT));
2024514f5e3Sopenharmony_ci}
2034514f5e3Sopenharmony_ci
2044514f5e3Sopenharmony_ciGateRef CircuitBuilder::Int32ToTaggedPtr(GateRef x)
2054514f5e3Sopenharmony_ci{
2064514f5e3Sopenharmony_ci    GateRef val = SExtInt32ToInt64(x);
2074514f5e3Sopenharmony_ci    return Int64ToTaggedPtr(Int64Or(val, Int64(JSTaggedValue::TAG_INT)));
2084514f5e3Sopenharmony_ci}
2094514f5e3Sopenharmony_ci
2104514f5e3Sopenharmony_ciGateRef CircuitBuilder::Int64ToTaggedPtr(GateRef x)
2114514f5e3Sopenharmony_ci{
2124514f5e3Sopenharmony_ci    return GetCircuit()->NewGate(circuit_->Int64ToTagged(),
2134514f5e3Sopenharmony_ci        MachineType::I64, { x }, GateType::TaggedValue());
2144514f5e3Sopenharmony_ci}
2154514f5e3Sopenharmony_ci
2164514f5e3Sopenharmony_ciGateRef CircuitBuilder::ToTaggedInt(GateRef x)
2174514f5e3Sopenharmony_ci{
2184514f5e3Sopenharmony_ci    return Int64Or(x, Int64(JSTaggedValue::TAG_INT));
2194514f5e3Sopenharmony_ci}
2204514f5e3Sopenharmony_ci
2214514f5e3Sopenharmony_ciGateRef CircuitBuilder::ToTaggedIntPtr(GateRef x)
2224514f5e3Sopenharmony_ci{
2234514f5e3Sopenharmony_ci    return Int64ToTaggedPtr(Int64Or(x, Int64(JSTaggedValue::TAG_INT)));
2244514f5e3Sopenharmony_ci}
2254514f5e3Sopenharmony_ci
2264514f5e3Sopenharmony_ciGateRef CircuitBuilder::DoubleToTaggedDoublePtr(GateRef x)
2274514f5e3Sopenharmony_ci{
2284514f5e3Sopenharmony_ci    GateRef val = CastDoubleToInt64(x);
2294514f5e3Sopenharmony_ci    return Int64ToTaggedPtr(Int64Add(val, Int64(JSTaggedValue::DOUBLE_ENCODE_OFFSET)));
2304514f5e3Sopenharmony_ci}
2314514f5e3Sopenharmony_ci
2324514f5e3Sopenharmony_ciGateRef CircuitBuilder::DoubleIsImpureNaN(GateRef x)
2334514f5e3Sopenharmony_ci{
2344514f5e3Sopenharmony_ci    GateRef impureNaN = Int64(JSTaggedValue::TAG_INT - JSTaggedValue::DOUBLE_ENCODE_OFFSET);
2354514f5e3Sopenharmony_ci    GateRef val = CastDoubleToInt64(x);
2364514f5e3Sopenharmony_ci    return Int64UnsignedGreaterThanOrEqual(val, impureNaN);
2374514f5e3Sopenharmony_ci}
2384514f5e3Sopenharmony_ci
2394514f5e3Sopenharmony_ciGateRef CircuitBuilder::BooleanToTaggedBooleanPtr(GateRef x)
2404514f5e3Sopenharmony_ci{
2414514f5e3Sopenharmony_ci    auto val = ZExtInt1ToInt64(x);
2424514f5e3Sopenharmony_ci    return Int64ToTaggedPtr(Int64Or(val, Int64(JSTaggedValue::TAG_BOOLEAN_MASK)));
2434514f5e3Sopenharmony_ci}
2444514f5e3Sopenharmony_ci
2454514f5e3Sopenharmony_ciGateRef CircuitBuilder::BooleanToInt32(GateRef x)
2464514f5e3Sopenharmony_ci{
2474514f5e3Sopenharmony_ci    return ZExtInt1ToInt32(x);
2484514f5e3Sopenharmony_ci}
2494514f5e3Sopenharmony_ci
2504514f5e3Sopenharmony_ciGateRef CircuitBuilder::BooleanToFloat64(GateRef x)
2514514f5e3Sopenharmony_ci{
2524514f5e3Sopenharmony_ci    return ChangeInt32ToFloat64(ZExtInt1ToInt32(x));
2534514f5e3Sopenharmony_ci}
2544514f5e3Sopenharmony_ci
2554514f5e3Sopenharmony_ciGateRef CircuitBuilder::Float32ToTaggedDoublePtr(GateRef x)
2564514f5e3Sopenharmony_ci{
2574514f5e3Sopenharmony_ci    GateRef val = ExtFloat32ToDouble(x);
2584514f5e3Sopenharmony_ci    return DoubleToTaggedDoublePtr(val);
2594514f5e3Sopenharmony_ci}
2604514f5e3Sopenharmony_ci
2614514f5e3Sopenharmony_ciGateRef CircuitBuilder::TaggedDoublePtrToFloat32(GateRef x)
2624514f5e3Sopenharmony_ci{
2634514f5e3Sopenharmony_ci    GateRef val = GetDoubleOfTDouble(x);
2644514f5e3Sopenharmony_ci    return TruncDoubleToFloat32(val);
2654514f5e3Sopenharmony_ci}
2664514f5e3Sopenharmony_ci
2674514f5e3Sopenharmony_ciGateRef CircuitBuilder::TaggedIntPtrToFloat32(GateRef x)
2684514f5e3Sopenharmony_ci{
2694514f5e3Sopenharmony_ci    GateRef val = GetInt32OfTInt(x);
2704514f5e3Sopenharmony_ci    return ChangeInt32ToFloat32(val);
2714514f5e3Sopenharmony_ci}
2724514f5e3Sopenharmony_ci
2734514f5e3Sopenharmony_ciGateRef CircuitBuilder::DoubleToTaggedDouble(GateRef x)
2744514f5e3Sopenharmony_ci{
2754514f5e3Sopenharmony_ci    GateRef val = CastDoubleToInt64(x);
2764514f5e3Sopenharmony_ci    return Int64Add(val, Int64(JSTaggedValue::DOUBLE_ENCODE_OFFSET));
2774514f5e3Sopenharmony_ci}
2784514f5e3Sopenharmony_ci
2794514f5e3Sopenharmony_ciGateRef CircuitBuilder::DoubleIsNAN(GateRef x)
2804514f5e3Sopenharmony_ci{
2814514f5e3Sopenharmony_ci    GateRef diff = DoubleEqual(x, x);
2824514f5e3Sopenharmony_ci    return Equal(SExtInt1ToInt32(diff), Int32(0));
2834514f5e3Sopenharmony_ci}
2844514f5e3Sopenharmony_ci
2854514f5e3Sopenharmony_ciGateRef CircuitBuilder::DoubleToTagged(GateRef x)
2864514f5e3Sopenharmony_ci{
2874514f5e3Sopenharmony_ci    GateRef val = CastDoubleToInt64(x);
2884514f5e3Sopenharmony_ci    acc_.SetGateType(val, GateType::TaggedValue());
2894514f5e3Sopenharmony_ci    return Int64Add(val, Int64(JSTaggedValue::DOUBLE_ENCODE_OFFSET));
2904514f5e3Sopenharmony_ci}
2914514f5e3Sopenharmony_ci
2924514f5e3Sopenharmony_citemplate<OpCode Op, MachineType Type>
2934514f5e3Sopenharmony_ciGateRef CircuitBuilder::BinaryOp(GateRef x, GateRef y)
2944514f5e3Sopenharmony_ci{
2954514f5e3Sopenharmony_ci    if (Op == OpCode::ADD) {
2964514f5e3Sopenharmony_ci        return BinaryArithmetic(circuit_->Add(), Type, x, y);
2974514f5e3Sopenharmony_ci    } else if (Op == OpCode::SUB) {
2984514f5e3Sopenharmony_ci        return BinaryArithmetic(circuit_->Sub(), Type, x, y);
2994514f5e3Sopenharmony_ci    } else if (Op == OpCode::MUL) {
3004514f5e3Sopenharmony_ci        return BinaryArithmetic(circuit_->Mul(), Type, x, y);
3014514f5e3Sopenharmony_ci    }
3024514f5e3Sopenharmony_ci    UNREACHABLE();
3034514f5e3Sopenharmony_ci    return Circuit::NullGate();
3044514f5e3Sopenharmony_ci}
3054514f5e3Sopenharmony_ci
3064514f5e3Sopenharmony_citemplate<OpCode Op, MachineType Type>
3074514f5e3Sopenharmony_ciGateRef CircuitBuilder::BinaryOpWithOverflow(GateRef x, GateRef y)
3084514f5e3Sopenharmony_ci{
3094514f5e3Sopenharmony_ci    if (Op == OpCode::ADD) {
3104514f5e3Sopenharmony_ci        return BinaryArithmetic(circuit_->AddWithOverflow(), Type, x, y);
3114514f5e3Sopenharmony_ci    } else if (Op == OpCode::SUB) {
3124514f5e3Sopenharmony_ci        return BinaryArithmetic(circuit_->SubWithOverflow(), Type, x, y);
3134514f5e3Sopenharmony_ci    } else if (Op == OpCode::MUL) {
3144514f5e3Sopenharmony_ci        return BinaryArithmetic(circuit_->MulWithOverflow(), Type, x, y);
3154514f5e3Sopenharmony_ci    }
3164514f5e3Sopenharmony_ci    UNREACHABLE();
3174514f5e3Sopenharmony_ci    return Circuit::NullGate();
3184514f5e3Sopenharmony_ci}
3194514f5e3Sopenharmony_ci
3204514f5e3Sopenharmony_ciGateRef CircuitBuilder::Equal(GateRef x, GateRef y, const char* comment)
3214514f5e3Sopenharmony_ci{
3224514f5e3Sopenharmony_ci    auto xType = acc_.GetMachineType(x);
3234514f5e3Sopenharmony_ci    switch (xType) {
3244514f5e3Sopenharmony_ci        case ARCH:
3254514f5e3Sopenharmony_ci        case FLEX:
3264514f5e3Sopenharmony_ci        case I1:
3274514f5e3Sopenharmony_ci        case I8:
3284514f5e3Sopenharmony_ci        case I16:
3294514f5e3Sopenharmony_ci        case I32:
3304514f5e3Sopenharmony_ci        case I64:
3314514f5e3Sopenharmony_ci            return BinaryCmp(circuit_->Icmp(static_cast<uint64_t>(ICmpCondition::EQ)), x, y, comment);
3324514f5e3Sopenharmony_ci        case F32:
3334514f5e3Sopenharmony_ci        case F64:
3344514f5e3Sopenharmony_ci            return BinaryCmp(circuit_->Fcmp(static_cast<uint64_t>(FCmpCondition::OEQ)), x, y, comment);
3354514f5e3Sopenharmony_ci        default:
3364514f5e3Sopenharmony_ci            LOG_ECMA(FATAL) << "this branch is unreachable";
3374514f5e3Sopenharmony_ci            UNREACHABLE();
3384514f5e3Sopenharmony_ci    }
3394514f5e3Sopenharmony_ci}
3404514f5e3Sopenharmony_ci
3414514f5e3Sopenharmony_ciGateRef CircuitBuilder::NotEqual(GateRef x, GateRef y, const char* comment)
3424514f5e3Sopenharmony_ci{
3434514f5e3Sopenharmony_ci    auto xType = acc_.GetMachineType(x);
3444514f5e3Sopenharmony_ci    switch (xType) {
3454514f5e3Sopenharmony_ci        case ARCH:
3464514f5e3Sopenharmony_ci        case FLEX:
3474514f5e3Sopenharmony_ci        case I1:
3484514f5e3Sopenharmony_ci        case I8:
3494514f5e3Sopenharmony_ci        case I16:
3504514f5e3Sopenharmony_ci        case I32:
3514514f5e3Sopenharmony_ci        case I64:
3524514f5e3Sopenharmony_ci            return BinaryCmp(circuit_->Icmp(static_cast<uint64_t>(ICmpCondition::NE)), x, y, comment);
3534514f5e3Sopenharmony_ci        case F32:
3544514f5e3Sopenharmony_ci        case F64:
3554514f5e3Sopenharmony_ci            return BinaryCmp(circuit_->Fcmp(static_cast<uint64_t>(FCmpCondition::ONE)), x, y, comment);
3564514f5e3Sopenharmony_ci        default:
3574514f5e3Sopenharmony_ci            LOG_ECMA(FATAL) << "this branch is unreachable";
3584514f5e3Sopenharmony_ci            UNREACHABLE();
3594514f5e3Sopenharmony_ci    }
3604514f5e3Sopenharmony_ci}
3614514f5e3Sopenharmony_ci
3624514f5e3Sopenharmony_ci}
3634514f5e3Sopenharmony_ci
3644514f5e3Sopenharmony_ci#endif  // ECMASCRIPT_COMPILER_LCR_CIRCUIT_BUILDER_H
365