106c3fb27SDimitry Andric//==--- riscv_sifive_vector.td - RISC-V SiFive VCIX function list ---------===// 206c3fb27SDimitry Andric// 306c3fb27SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric// 706c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric// 906c3fb27SDimitry Andric// This file defines the builtins for RISC-V SiFive VCIX. See: 1006c3fb27SDimitry Andric// 1106c3fb27SDimitry Andric// https://sifive.cdn.prismic.io/sifive/c3829e36-8552-41f0-a841-79945784241b_vcix-spec-software.pdf 1206c3fb27SDimitry Andric// 1306c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 1406c3fb27SDimitry Andric 1506c3fb27SDimitry Andricinclude "riscv_vector_common.td" 1606c3fb27SDimitry Andric 1706c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 1806c3fb27SDimitry Andric// Instruction definitions 1906c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 2006c3fb27SDimitry Andric 2106c3fb27SDimitry Andricclass VCIXSuffix<string range> { 2206c3fb27SDimitry Andric list<string> suffix = !cond(!eq(range, "c"): ["8mf8", "8mf4", "8mf2", "8m1", "8m2", "8m4", "8m8"], 2306c3fb27SDimitry Andric !eq(range, "s"): ["16mf4", "16mf2", "16m1", "16m2", "16m4", "16m8"], 2406c3fb27SDimitry Andric !eq(range, "i"): ["32mf2", "32m1", "32m2", "32m4", "32m8"], 2506c3fb27SDimitry Andric !eq(range, "l"): ["64m1", "64m2", "64m4", "64m8"]); 2606c3fb27SDimitry Andric} 2706c3fb27SDimitry Andric 2806c3fb27SDimitry Andricclass VCIXBuiltinSet<string name, string IR_name, string suffix, 2906c3fb27SDimitry Andric string prototype, string type_range, 3006c3fb27SDimitry Andric list<int> intrinsic_types> 3106c3fb27SDimitry Andric : RVVBuiltin<suffix, prototype, type_range> { 3206c3fb27SDimitry Andric let Name = name; 3306c3fb27SDimitry Andric let OverloadedName = name; 3406c3fb27SDimitry Andric let IRName = IR_name; 3506c3fb27SDimitry Andric let HasMasked = false; 3606c3fb27SDimitry Andric let IntrinsicTypes = intrinsic_types; 3706c3fb27SDimitry Andric} 3806c3fb27SDimitry Andric 3906c3fb27SDimitry Andricmulticlass VCIXBuiltinSet<string name, string IR_name, string suffix, 4006c3fb27SDimitry Andric string prototype, string type_range, 4106c3fb27SDimitry Andric list<int> intrinsic_types> { 4206c3fb27SDimitry Andric if !find(prototype, "0") then { 4306c3fb27SDimitry Andric def : VCIXBuiltinSet<name, IR_name, suffix, prototype, type_range, intrinsic_types>; 4406c3fb27SDimitry Andric } 4506c3fb27SDimitry Andric def : VCIXBuiltinSet<name # "_se", IR_name # "_se", suffix, prototype, type_range, intrinsic_types>; 4606c3fb27SDimitry Andric} 4706c3fb27SDimitry Andric 4806c3fb27SDimitry Andricmulticlass RVVVCIXBuiltinSet<list<string> range, string prototype, 4906c3fb27SDimitry Andric list<int> intrinsic_types, bit UseGPR> { 5006c3fb27SDimitry Andric foreach r = range in 5106c3fb27SDimitry Andric let RequiredFeatures = !if(!and(UseGPR, !eq(r, "l")), 5206c3fb27SDimitry Andric ["Xsfvcp", "RV64"], ["Xsfvcp"]) in 5306c3fb27SDimitry Andric defm : VCIXBuiltinSet<NAME, NAME, "Uv", prototype, r, intrinsic_types>; 5406c3fb27SDimitry Andric} 5506c3fb27SDimitry Andric 5606c3fb27SDimitry Andricmulticlass RVVVCIXBuiltinSetWVType<list<string> range, string prototype, 5706c3fb27SDimitry Andric list<int> intrinsic_types, bit UseGPR> { 5806c3fb27SDimitry Andric foreach r = range in 5906c3fb27SDimitry Andric let RequiredFeatures = !if(!and(UseGPR, !eq(r, "l")), 6006c3fb27SDimitry Andric ["Xsfvcp", "RV64"], ["Xsfvcp"]) in 6106c3fb27SDimitry Andric // These intrinsics don't have any vector types in the output and inputs, 6206c3fb27SDimitry Andric // but we still need to add vetvli for them. So we encode different 6306c3fb27SDimitry Andric // VTYPE into the intrinsic names, and then will know which vsetvli is 6406c3fb27SDimitry Andric // correct. 6506c3fb27SDimitry Andric foreach s = VCIXSuffix<r>.suffix in 6606c3fb27SDimitry Andric // Since we already encode the Vtype into the name, so just set 6706c3fb27SDimitry Andric // Log2LMUL to zero. Otherwise the RISCVVEmitter will expand 6806c3fb27SDimitry Andric // lots of redundant intrinsic but have same names. 6906c3fb27SDimitry Andric let Log2LMUL = [0] in 7006c3fb27SDimitry Andric def : VCIXBuiltinSet<NAME # "_u" # s, NAME # "_e" # s, 7106c3fb27SDimitry Andric "", prototype, r, intrinsic_types>; 7206c3fb27SDimitry Andric} 7306c3fb27SDimitry Andric 7406c3fb27SDimitry Andriclet SupportOverloading = false in { 755f757f3fSDimitry Andric defm sf_vc_x_se : RVVVCIXBuiltinSetWVType<["c", "s", "i", "l"], "0KzKzKzUe", [0, 3], UseGPR=1>; 765f757f3fSDimitry Andric defm sf_vc_i_se : RVVVCIXBuiltinSetWVType<["c", "s", "i", "l"], "0KzKzKzKz", [2, 3], UseGPR=0>; 775f757f3fSDimitry Andric defm sf_vc_xv : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvUe", [0, 2, 3], UseGPR=1>; 785f757f3fSDimitry Andric defm sf_vc_iv : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvKz", [0, 2, 3], UseGPR=0>; 795f757f3fSDimitry Andric defm sf_vc_vv : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvUv", [0, 2, 3], UseGPR=0>; 805f757f3fSDimitry Andric defm sf_vc_fv : RVVVCIXBuiltinSet<["si", "l"], "0KzKzUvFe", [0, 2, 3], UseGPR=0>; 815f757f3fSDimitry Andric defm sf_vc_xvv : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvUe", [0, 1, 2, 3], UseGPR=1>; 825f757f3fSDimitry Andric defm sf_vc_ivv : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvKz", [0, 1, 2, 3], UseGPR=0>; 835f757f3fSDimitry Andric defm sf_vc_vvv : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvUv", [0, 1, 2, 3], UseGPR=0>; 845f757f3fSDimitry Andric defm sf_vc_fvv : RVVVCIXBuiltinSet<["si", "l"], "0KzUvUvFe", [0, 1, 2, 3], UseGPR=0>; 855f757f3fSDimitry Andric defm sf_vc_v_x : RVVVCIXBuiltinSet<["csi", "l"], "UvKzKzUe", [-1, 1, 2], UseGPR=1>; 865f757f3fSDimitry Andric defm sf_vc_v_i : RVVVCIXBuiltinSet<["csi", "l"], "UvKzKzKz", [-1, 1, 2], UseGPR=0>; 875f757f3fSDimitry Andric defm sf_vc_v_xv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUe", [-1, 0, 1, 2], UseGPR=1>; 885f757f3fSDimitry Andric defm sf_vc_v_iv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvKz", [-1, 0, 1, 2], UseGPR=0>; 895f757f3fSDimitry Andric defm sf_vc_v_vv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUv", [-1, 0, 1, 2], UseGPR=0>; 905f757f3fSDimitry Andric defm sf_vc_v_fv : RVVVCIXBuiltinSet<["si", "l"], "UvKzUvFe", [-1, 0, 1, 2], UseGPR=0>; 915f757f3fSDimitry Andric defm sf_vc_v_xvv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvUe", [-1, 0, 1, 2, 3], UseGPR=1>; 925f757f3fSDimitry Andric defm sf_vc_v_ivv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvKz", [-1, 0, 1, 2, 3], UseGPR=0>; 935f757f3fSDimitry Andric defm sf_vc_v_vvv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvUv", [-1, 0, 1, 2, 3], UseGPR=0>; 945f757f3fSDimitry Andric defm sf_vc_v_fvv : RVVVCIXBuiltinSet<["si", "l"], "UvKzUvUvFe", [-1, 0, 1, 2, 3], UseGPR=0>; 9506c3fb27SDimitry Andric let Log2LMUL = [-3, -2, -1, 0, 1, 2] in { 965f757f3fSDimitry Andric defm sf_vc_xvw : RVVVCIXBuiltinSet<["csi"], "0KzUwUvUe", [0, 1, 2, 3], UseGPR=1>; 975f757f3fSDimitry Andric defm sf_vc_ivw : RVVVCIXBuiltinSet<["csi"], "0KzUwUvKz", [0, 1, 2, 3], UseGPR=0>; 985f757f3fSDimitry Andric defm sf_vc_vvw : RVVVCIXBuiltinSet<["csi"], "0KzUwUvUv", [0, 1, 2, 3], UseGPR=0>; 995f757f3fSDimitry Andric defm sf_vc_fvw : RVVVCIXBuiltinSet<["si"], "0KzUwUvFe", [0, 1, 2, 3], UseGPR=0>; 1005f757f3fSDimitry Andric defm sf_vc_v_xvw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvUe", [-1, 0, 1, 2, 3], UseGPR=1>; 1015f757f3fSDimitry Andric defm sf_vc_v_ivw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvKz", [-1, 0, 1, 2, 3], UseGPR=0>; 1025f757f3fSDimitry Andric defm sf_vc_v_vvw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvUv", [-1, 0, 1, 2, 3], UseGPR=0>; 1035f757f3fSDimitry Andric defm sf_vc_v_fvw : RVVVCIXBuiltinSet<["si"], "UwKzUwUvFe", [-1, 0, 1, 2, 3], UseGPR=0>; 1045f757f3fSDimitry Andric } 1055f757f3fSDimitry Andric} 1065f757f3fSDimitry Andric 1075f757f3fSDimitry Andricmulticlass RVVVFWMACCBuiltinSet<list<list<string>> suffixes_prototypes> { 1085f757f3fSDimitry Andric let OverloadedName = NAME, 1095f757f3fSDimitry Andric Name = NAME, 1105f757f3fSDimitry Andric HasMasked = false, 1115f757f3fSDimitry Andric Log2LMUL = [-2, -1, 0, 1, 2] in 112*647cbc5dSDimitry Andric defm NAME : RVVOutOp1Op2BuiltinSet<NAME, "y", suffixes_prototypes>; 1135f757f3fSDimitry Andric} 1145f757f3fSDimitry Andric 115*647cbc5dSDimitry Andricmulticlass RVVVQMACCDODBuiltinSet<list<list<string>> suffixes_prototypes> { 1165f757f3fSDimitry Andric let OverloadedName = NAME, 1175f757f3fSDimitry Andric Name = NAME, 1185f757f3fSDimitry Andric HasMasked = false, 1195f757f3fSDimitry Andric Log2LMUL = [0, 1, 2, 3] in 1205f757f3fSDimitry Andric defm NAME : RVVOutOp1Op2BuiltinSet<NAME, "i", suffixes_prototypes>; 1215f757f3fSDimitry Andric} 1225f757f3fSDimitry Andric 123*647cbc5dSDimitry Andricmulticlass RVVVQMACCQOQBuiltinSet<list<list<string>> suffixes_prototypes> { 124*647cbc5dSDimitry Andric let OverloadedName = NAME, 125*647cbc5dSDimitry Andric Name = NAME, 126*647cbc5dSDimitry Andric HasMasked = false, 127*647cbc5dSDimitry Andric Log2LMUL = [-1, 0, 1, 2] in 128*647cbc5dSDimitry Andric defm NAME : RVVOutOp1Op2BuiltinSet<NAME, "s", suffixes_prototypes>; 129*647cbc5dSDimitry Andric} 130*647cbc5dSDimitry Andric 1315f757f3fSDimitry Andricmulticlass RVVVFNRCLIPBuiltinSet<string suffix, string prototype, string type_range> { 1325f757f3fSDimitry Andric let Log2LMUL = [-3, -2, -1, 0, 1, 2], 1335f757f3fSDimitry Andric Name = NAME, 1345f757f3fSDimitry Andric IRName = NAME, 1355f757f3fSDimitry Andric MaskedIRName = NAME # "_mask" in 1365f757f3fSDimitry Andric def : RVVConvBuiltin<suffix, prototype, type_range, NAME>; 1375f757f3fSDimitry Andric} 1385f757f3fSDimitry Andric 1395f757f3fSDimitry Andriclet UnMaskedPolicyScheme = HasPolicyOperand in 1405f757f3fSDimitry Andric let RequiredFeatures = ["Xsfvqmaccdod"] in { 141*647cbc5dSDimitry Andric defm sf_vqmaccu_2x8x2 : RVVVQMACCDODBuiltinSet<[["", "v", "vv(FixedSEW:8)SUv(FixedSEW:8)Uv"]]>; 142*647cbc5dSDimitry Andric defm sf_vqmacc_2x8x2 : RVVVQMACCDODBuiltinSet<[["", "v", "vv(FixedSEW:8)Sv(FixedSEW:8)v"]]>; 143*647cbc5dSDimitry Andric defm sf_vqmaccus_2x8x2 : RVVVQMACCDODBuiltinSet<[["", "v", "vv(FixedSEW:8)SUv(FixedSEW:8)v"]]>; 144*647cbc5dSDimitry Andric defm sf_vqmaccsu_2x8x2 : RVVVQMACCDODBuiltinSet<[["", "v", "vv(FixedSEW:8)Sv(FixedSEW:8)Uv"]]>; 1455f757f3fSDimitry Andric } 1465f757f3fSDimitry Andric 1475f757f3fSDimitry Andriclet UnMaskedPolicyScheme = HasPolicyOperand in 1485f757f3fSDimitry Andric let RequiredFeatures = ["Xsfvqmaccqoq"] in { 149*647cbc5dSDimitry Andric defm sf_vqmaccu_4x8x4 : RVVVQMACCQOQBuiltinSet<[["", "w", "ww(FixedSEW:8)SUv(FixedSEW:8)Uv"]]>; 150*647cbc5dSDimitry Andric defm sf_vqmacc_4x8x4 : RVVVQMACCQOQBuiltinSet<[["", "w", "ww(FixedSEW:8)Sv(FixedSEW:8)v"]]>; 151*647cbc5dSDimitry Andric defm sf_vqmaccus_4x8x4 : RVVVQMACCQOQBuiltinSet<[["", "w", "ww(FixedSEW:8)SUv(FixedSEW:8)v"]]>; 152*647cbc5dSDimitry Andric defm sf_vqmaccsu_4x8x4 : RVVVQMACCQOQBuiltinSet<[["", "w", "ww(FixedSEW:8)Sv(FixedSEW:8)Uv"]]>; 1535f757f3fSDimitry Andric } 1545f757f3fSDimitry Andric 1555f757f3fSDimitry Andriclet UnMaskedPolicyScheme = HasPolicyOperand in 1565f757f3fSDimitry Andric let RequiredFeatures = ["Xsfvfwmaccqqq"] in 1575f757f3fSDimitry Andric defm sf_vfwmacc_4x4x4 : RVVVFWMACCBuiltinSet<[["", "Fw", "FwFwSvv"]]>; 1585f757f3fSDimitry Andric 1595f757f3fSDimitry Andriclet UnMaskedPolicyScheme = HasPassthruOperand, RequiredFeatures = ["Xsfvfnrclipxfqf"] in { 1605f757f3fSDimitry Andriclet ManualCodegen = [{ 1615f757f3fSDimitry Andric { 1625f757f3fSDimitry Andric // LLVM intrinsic 1635f757f3fSDimitry Andric // Unmasked: (passthru, vector_in, scalar_in, frm, vl) 1645f757f3fSDimitry Andric // Masked: (passthru, vector_in, scalar_in, mask, frm, vl, policy) 1655f757f3fSDimitry Andric 1665f757f3fSDimitry Andric SmallVector<llvm::Value*, 7> Operands; 1675f757f3fSDimitry Andric bool HasMaskedOff = !( 1685f757f3fSDimitry Andric (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) || 1695f757f3fSDimitry Andric (!IsMasked && PolicyAttrs & RVV_VTA)); 1705f757f3fSDimitry Andric bool HasRoundModeOp = IsMasked ? 1715f757f3fSDimitry Andric (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5) : 1725f757f3fSDimitry Andric (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4); 1735f757f3fSDimitry Andric 1745f757f3fSDimitry Andric unsigned Offset = IsMasked ? 1755f757f3fSDimitry Andric (HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0); 1765f757f3fSDimitry Andric 1775f757f3fSDimitry Andric if (!HasMaskedOff) 1785f757f3fSDimitry Andric Operands.push_back(llvm::PoisonValue::get(ResultType)); 1795f757f3fSDimitry Andric else 1805f757f3fSDimitry Andric Operands.push_back(Ops[IsMasked ? 1 : 0]); 1815f757f3fSDimitry Andric 1825f757f3fSDimitry Andric Operands.push_back(Ops[Offset]); // op0 1835f757f3fSDimitry Andric Operands.push_back(Ops[Offset + 1]); // op1 1845f757f3fSDimitry Andric 1855f757f3fSDimitry Andric if (IsMasked) 1865f757f3fSDimitry Andric Operands.push_back(Ops[0]); // mask 1875f757f3fSDimitry Andric 1885f757f3fSDimitry Andric if (HasRoundModeOp) { 1895f757f3fSDimitry Andric Operands.push_back(Ops[Offset + 2]); // frm 1905f757f3fSDimitry Andric Operands.push_back(Ops[Offset + 3]); // vl 1915f757f3fSDimitry Andric } else { 1925f757f3fSDimitry Andric Operands.push_back(ConstantInt::get(Ops[Offset + 2]->getType(), 7)); // frm 1935f757f3fSDimitry Andric Operands.push_back(Ops[Offset + 2]); // vl 1945f757f3fSDimitry Andric } 1955f757f3fSDimitry Andric 1965f757f3fSDimitry Andric if (IsMasked) 1975f757f3fSDimitry Andric Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs)); 1985f757f3fSDimitry Andric 1995f757f3fSDimitry Andric IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Operands.back()->getType()}; 2005f757f3fSDimitry Andric llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes); 2015f757f3fSDimitry Andric return Builder.CreateCall(F, Operands, ""); 2025f757f3fSDimitry Andric } 2035f757f3fSDimitry Andric}] in { 2045f757f3fSDimitry Andric let HasFRMRoundModeOp = true in { 2055f757f3fSDimitry Andric defm sf_vfnrclip_x_f_qf : RVVVFNRCLIPBuiltinSet<"v", "vFqfu", "c">; 2065f757f3fSDimitry Andric defm sf_vfnrclip_xu_f_qf : RVVVFNRCLIPBuiltinSet<"Uv", "UvFqfu", "c">; 2075f757f3fSDimitry Andric } 2085f757f3fSDimitry Andric defm sf_vfnrclip_x_f_qf : RVVVFNRCLIPBuiltinSet<"v", "vFqf", "c">; 2095f757f3fSDimitry Andric defm sf_vfnrclip_xu_f_qf : RVVVFNRCLIPBuiltinSet<"Uv", "UvFqf", "c">; 21006c3fb27SDimitry Andric} 21106c3fb27SDimitry Andric} 212