4vtomat created this revision.
Herald added subscribers: jobnoorman, luke, VincentWu, vkmr, frasercrmck,
evandro, luismarques, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl,
jocewei, PkmX, arphaman, the_o, brucehoult, MartinMosbeck, rogfer01,
edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal,
simoncook, johnrusso, rbar, asb, arichardson.
Herald added a project: All.
4vtomat requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, pcwang-thead, eopXD,
MaskRay.
Herald added projects: clang, LLVM.
Since we don't always need the vendor extension to be in riscv_vector.td,
so it's better to make it be in separated header.
Depends on D148223 <https://reviews.llvm.org/D148223>
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D148308
Files:
clang/include/clang/Basic/BuiltinsRISCVVector.def
clang/include/clang/Basic/CMakeLists.txt
clang/include/clang/Basic/riscv_sifive_vcix.td
clang/include/clang/Basic/riscv_vector.td
clang/include/clang/Basic/riscv_vector_common.td
clang/include/clang/Sema/RISCVIntrinsicManager.h
clang/include/clang/Sema/Sema.h
clang/lib/CodeGen/CGBuiltin.cpp
clang/lib/Headers/CMakeLists.txt
clang/lib/Headers/sifive_vector.h
clang/lib/Parse/ParsePragma.cpp
clang/lib/Sema/SemaLookup.cpp
clang/lib/Sema/SemaRISCVVectorLookup.cpp
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x-rv64.c
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x.c
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv-rv64.c
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv.c
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv-rv64.c
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv.c
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvw.c
clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/xsfvcp-index-out-of-range.c
clang/test/Sema/riscv-bad-intrinsic-pragma.c
clang/utils/TableGen/TableGen.cpp
llvm/docs/CommandGuide/tblgen.rst
Index: llvm/docs/CommandGuide/tblgen.rst
===================================================================
--- llvm/docs/CommandGuide/tblgen.rst
+++ llvm/docs/CommandGuide/tblgen.rst
@@ -348,6 +348,14 @@
Generate ``riscv_vector_builtin_cg.inc`` for Clang.
+.. option:: -gen-riscv-sifive-vcix-builtins
+
+ Generate ``riscv_sifive_vcix_builtins.inc`` for Clang.
+
+.. option:: -gen-riscv-sifive-vcix-builtin-codegen
+
+ Generate ``riscv_sifive_vcix_builtin_cg.inc`` for Clang.
+
.. option:: -gen-attr-docs
Generate attribute documentation.
Index: clang/utils/TableGen/TableGen.cpp
===================================================================
--- clang/utils/TableGen/TableGen.cpp
+++ clang/utils/TableGen/TableGen.cpp
@@ -91,6 +91,9 @@
GenRISCVVectorBuiltins,
GenRISCVVectorBuiltinCG,
GenRISCVVectorBuiltinSema,
+ GenRISCVSiFiveVCIXBuiltins,
+ GenRISCVSiFiveVCIXBuiltinCG,
+ GenRISCVSiFiveVCIXBuiltinSema,
GenAttrDocs,
GenDiagDocs,
GenOptDocs,
@@ -251,6 +254,12 @@
"Generate riscv_vector_builtin_cg.inc for clang"),
clEnumValN(GenRISCVVectorBuiltinSema, "gen-riscv-vector-builtin-sema",
"Generate riscv_vector_builtin_sema.inc for clang"),
+ clEnumValN(GenRISCVSiFiveVCIXBuiltins, "gen-riscv-sifive-vcix-builtins",
+ "Generate riscv_sifive_vcix_builtins.inc for clang"),
+ clEnumValN(GenRISCVSiFiveVCIXBuiltinCG, "gen-riscv-sifive-vcix-builtin-codegen",
+ "Generate riscv_sifive_vcix_builtin_cg.inc for clang"),
+ clEnumValN(GenRISCVSiFiveVCIXBuiltinSema, "gen-riscv-sifive-vcix-builtin-sema",
+ "Generate riscv_sifive_vcix_builtin_sema.inc for clang"),
clEnumValN(GenAttrDocs, "gen-attr-docs",
"Generate attribute documentation"),
clEnumValN(GenDiagDocs, "gen-diag-docs",
@@ -472,6 +481,15 @@
case GenRISCVVectorBuiltinSema:
EmitRVVBuiltinSema(Records, OS);
break;
+ case GenRISCVSiFiveVCIXBuiltins:
+ EmitRVVBuiltins(Records, OS);
+ break;
+ case GenRISCVSiFiveVCIXBuiltinCG:
+ EmitRVVBuiltinCG(Records, OS);
+ break;
+ case GenRISCVSiFiveVCIXBuiltinSema:
+ EmitRVVBuiltinSema(Records, OS);
+ break;
case GenAttrDocs:
EmitClangAttrDocs(Records, OS);
break;
Index: clang/test/Sema/riscv-bad-intrinsic-pragma.c
===================================================================
--- clang/test/Sema/riscv-bad-intrinsic-pragma.c
+++ clang/test/Sema/riscv-bad-intrinsic-pragma.c
@@ -2,7 +2,7 @@
// RUN: 2>&1 | FileCheck %s
#pragma clang riscv intrinsic vvvv
-// CHECK: warning: unexpected argument 'vvvv' to '#pragma riscv'; expected 'vector' [-Wignored-pragmas]
+// CHECK: warning: unexpected argument 'vvvv' to '#pragma riscv'; expected 'vector' or 'sifive_vcix' [-Wignored-pragmas]
#pragma clang riscv what + 3241
// CHECK: warning: unexpected argument 'what' to '#pragma riscv'; expected 'intrinsic' [-Wignored-pragmas]
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/xsfvcp-index-out-of-range.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/xsfvcp-index-out-of-range.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/xsfvcp-index-out-of-range.c
@@ -5,7 +5,7 @@
// RUN: -target-feature +xsfvcp \
// RUN: -fsyntax-only -verify %s
-#include <riscv_vector.h>
+#include <sifive_vector.h>
#define p27_26 (0b11)
#define p26 (0b1)
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvw.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvw.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvw.c
@@ -2,7 +2,7 @@
// RUN: %clang_cc1 -triple riscv32 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV32 %s
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
-#include <riscv_vector.h>
+#include <sifive_vector.h>
#define p27_26 (0b11)
#define p26 (0b1)
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv.c
@@ -2,7 +2,7 @@
// RUN: %clang_cc1 -triple riscv32 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV32 %s
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
-#include <riscv_vector.h>
+#include <sifive_vector.h>
#define p27_26 (0b11)
#define p26 (0b1)
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv-rv64.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv-rv64.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv-rv64.c
@@ -2,7 +2,7 @@
// REQUIRES: riscv-registered-target
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
-#include <riscv_vector.h>
+#include <sifive_vector.h>
#define p27_26 (0b11)
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv.c
@@ -2,7 +2,7 @@
// RUN: %clang_cc1 -triple riscv32 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV32 %s
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
-#include <riscv_vector.h>
+#include <sifive_vector.h>
#define p27_26 (0b11)
#define p26 (0b1)
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv-rv64.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv-rv64.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv-rv64.c
@@ -2,7 +2,7 @@
// REQUIRES: riscv-registered-target
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
-#include <riscv_vector.h>
+#include <sifive_vector.h>
#define p27_26 (0b11)
#define p11_7 (0b11111)
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x.c
@@ -2,7 +2,7 @@
// RUN: %clang_cc1 -triple riscv32 -target-feature +v -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV32 %s
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
-#include <riscv_vector.h>
+#include <sifive_vector.h>
#define p27_26 (0b11)
#define p24_20 (0b11111)
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x-rv64.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x-rv64.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x-rv64.c
@@ -1,7 +1,7 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
-#include <riscv_vector.h>
+#include <sifive_vector.h>
#define p27_26 (0b11)
#define p24_20 (0b11111)
Index: clang/lib/Sema/SemaRISCVVectorLookup.cpp
===================================================================
--- clang/lib/Sema/SemaRISCVVectorLookup.cpp
+++ clang/lib/Sema/SemaRISCVVectorLookup.cpp
@@ -28,6 +28,8 @@
using namespace clang;
using namespace clang::RISCV;
+using IntrinsicKind = sema::RISCVIntrinsicManager::IntrinsicKind;
+
namespace {
// Function definition of a RVV intrinsic.
@@ -58,16 +60,35 @@
#undef DECL_SIGNATURE_TABLE
};
+static const PrototypeDescriptor RVSiFiveVCIXSignatureTable[] = {
+#define DECL_SIGNATURE_TABLE
+#include "clang/Basic/riscv_sifive_vcix_builtin_sema.inc"
+#undef DECL_SIGNATURE_TABLE
+};
+
static const RVVIntrinsicRecord RVVIntrinsicRecords[] = {
#define DECL_INTRINSIC_RECORDS
#include "clang/Basic/riscv_vector_builtin_sema.inc"
#undef DECL_INTRINSIC_RECORDS
};
+static const RVVIntrinsicRecord RVSiFiveVCIXIntrinsicRecords[] = {
+#define DECL_INTRINSIC_RECORDS
+#include "clang/Basic/riscv_sifive_vcix_builtin_sema.inc"
+#undef DECL_INTRINSIC_RECORDS
+};
+
// Get subsequence of signature table.
-static ArrayRef<PrototypeDescriptor> ProtoSeq2ArrayRef(uint16_t Index,
- uint8_t Length) {
- return ArrayRef(&RVVSignatureTable[Index], Length);
+static ArrayRef<PrototypeDescriptor>
+ProtoSeq2ArrayRef(IntrinsicKind K, uint16_t Index, uint8_t Length) {
+ switch (K) {
+ default:
+ llvm_unreachable("Unsupported intrinsic kind.");
+ case IntrinsicKind::RVV:
+ return ArrayRef(&RVVSignatureTable[Index], Length);
+ case IntrinsicKind::SIFIVE_VCIX:
+ return ArrayRef(&RVSiFiveVCIXSignatureTable[Index], Length);
+ }
}
static QualType RVVType2Qual(ASTContext &Context, const RVVType *Type) {
@@ -172,123 +193,132 @@
bool HasRV64 = TI.hasFeature("64bit");
bool HasFullMultiply = TI.hasFeature("v");
- // Construction of RVVIntrinsicRecords need to sync with createRVVIntrinsics
- // in RISCVVEmitter.cpp.
- for (auto &Record : RVVIntrinsicRecords) {
- // Create Intrinsics for each type and LMUL.
- BasicType BaseType = BasicType::Unknown;
- ArrayRef<PrototypeDescriptor> BasicProtoSeq =
- ProtoSeq2ArrayRef(Record.PrototypeIndex, Record.PrototypeLength);
- ArrayRef<PrototypeDescriptor> SuffixProto =
- ProtoSeq2ArrayRef(Record.SuffixIndex, Record.SuffixLength);
- ArrayRef<PrototypeDescriptor> OverloadedSuffixProto = ProtoSeq2ArrayRef(
- Record.OverloadedSuffixIndex, Record.OverloadedSuffixSize);
-
- PolicyScheme UnMaskedPolicyScheme =
- static_cast<PolicyScheme>(Record.UnMaskedPolicyScheme);
- PolicyScheme MaskedPolicyScheme =
- static_cast<PolicyScheme>(Record.MaskedPolicyScheme);
-
- const Policy DefaultPolicy;
-
- llvm::SmallVector<PrototypeDescriptor> ProtoSeq =
- RVVIntrinsic::computeBuiltinTypes(BasicProtoSeq, /*IsMasked=*/false,
- /*HasMaskedOffOperand=*/false,
- Record.HasVL, Record.NF,
- UnMaskedPolicyScheme, DefaultPolicy);
-
- llvm::SmallVector<PrototypeDescriptor> ProtoMaskSeq =
- RVVIntrinsic::computeBuiltinTypes(
- BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
- Record.HasVL, Record.NF, MaskedPolicyScheme, DefaultPolicy);
-
- bool UnMaskedHasPolicy = UnMaskedPolicyScheme != PolicyScheme::SchemeNone;
- bool MaskedHasPolicy = MaskedPolicyScheme != PolicyScheme::SchemeNone;
- SmallVector<Policy> SupportedUnMaskedPolicies =
- RVVIntrinsic::getSupportedUnMaskedPolicies();
- SmallVector<Policy> SupportedMaskedPolicies =
- RVVIntrinsic::getSupportedMaskedPolicies(Record.HasTailPolicy,
- Record.HasMaskPolicy);
-
- for (unsigned int TypeRangeMaskShift = 0;
- TypeRangeMaskShift <= static_cast<unsigned int>(BasicType::MaxOffset);
- ++TypeRangeMaskShift) {
- unsigned int BaseTypeI = 1 << TypeRangeMaskShift;
- BaseType = static_cast<BasicType>(BaseTypeI);
-
- if ((BaseTypeI & Record.TypeRangeMask) != BaseTypeI)
- continue;
-
- // Check requirement.
- if (((Record.RequiredExtensions & RVV_REQ_RV64) == RVV_REQ_RV64) &&
- !HasRV64)
- continue;
-
- if ((BaseType == BasicType::Int64) &&
- ((Record.RequiredExtensions & RVV_REQ_FullMultiply) ==
- RVV_REQ_FullMultiply) &&
- !HasFullMultiply)
- continue;
-
- // Expanded with different LMUL.
- for (int Log2LMUL = -3; Log2LMUL <= 3; Log2LMUL++) {
- if (!(Record.Log2LMULMask & (1 << (Log2LMUL + 3))))
+ auto ConstructRVVIntrinsics = [&](ArrayRef<RVVIntrinsicRecord> Recs,
+ IntrinsicKind K) {
+ // Construction of RVVIntrinsicRecords need to sync with createRVVIntrinsics
+ // in RISCVVEmitter.cpp.
+ for (auto &Record : Recs) {
+ // Create Intrinsics for each type and LMUL.
+ BasicType BaseType = BasicType::Unknown;
+ ArrayRef<PrototypeDescriptor> BasicProtoSeq =
+ ProtoSeq2ArrayRef(K, Record.PrototypeIndex, Record.PrototypeLength);
+ ArrayRef<PrototypeDescriptor> SuffixProto =
+ ProtoSeq2ArrayRef(K, Record.SuffixIndex, Record.SuffixLength);
+ ArrayRef<PrototypeDescriptor> OverloadedSuffixProto = ProtoSeq2ArrayRef(
+ K, Record.OverloadedSuffixIndex, Record.OverloadedSuffixSize);
+
+ PolicyScheme UnMaskedPolicyScheme =
+ static_cast<PolicyScheme>(Record.UnMaskedPolicyScheme);
+ PolicyScheme MaskedPolicyScheme =
+ static_cast<PolicyScheme>(Record.MaskedPolicyScheme);
+
+ const Policy DefaultPolicy;
+
+ llvm::SmallVector<PrototypeDescriptor> ProtoSeq =
+ RVVIntrinsic::computeBuiltinTypes(BasicProtoSeq, /*IsMasked=*/false,
+ /*HasMaskedOffOperand=*/false,
+ Record.HasVL, Record.NF,
+ UnMaskedPolicyScheme, DefaultPolicy);
+
+ llvm::SmallVector<PrototypeDescriptor> ProtoMaskSeq =
+ RVVIntrinsic::computeBuiltinTypes(
+ BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
+ Record.HasVL, Record.NF, MaskedPolicyScheme, DefaultPolicy);
+
+ bool UnMaskedHasPolicy = UnMaskedPolicyScheme != PolicyScheme::SchemeNone;
+ bool MaskedHasPolicy = MaskedPolicyScheme != PolicyScheme::SchemeNone;
+ SmallVector<Policy> SupportedUnMaskedPolicies =
+ RVVIntrinsic::getSupportedUnMaskedPolicies();
+ SmallVector<Policy> SupportedMaskedPolicies =
+ RVVIntrinsic::getSupportedMaskedPolicies(Record.HasTailPolicy,
+ Record.HasMaskPolicy);
+
+ for (unsigned int TypeRangeMaskShift = 0;
+ TypeRangeMaskShift <= static_cast<unsigned int>(BasicType::MaxOffset);
+ ++TypeRangeMaskShift) {
+ unsigned int BaseTypeI = 1 << TypeRangeMaskShift;
+ BaseType = static_cast<BasicType>(BaseTypeI);
+
+ if ((BaseTypeI & Record.TypeRangeMask) != BaseTypeI)
continue;
- std::optional<RVVTypes> Types =
- TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoSeq);
-
- // Ignored to create new intrinsic if there are any illegal types.
- if (!Types.has_value())
+ // Check requirement.
+ if (((Record.RequiredExtensions & RVV_REQ_RV64) == RVV_REQ_RV64) &&
+ !HasRV64)
continue;
- std::string SuffixStr = RVVIntrinsic::getSuffixStr(
- TypeCache, BaseType, Log2LMUL, SuffixProto);
- std::string OverloadedSuffixStr = RVVIntrinsic::getSuffixStr(
- TypeCache, BaseType, Log2LMUL, OverloadedSuffixProto);
-
- // Create non-masked intrinsic.
- InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, false, *Types,
- UnMaskedHasPolicy, DefaultPolicy);
+ if ((BaseType == BasicType::Int64) &&
+ ((Record.RequiredExtensions & RVV_REQ_FullMultiply) ==
+ RVV_REQ_FullMultiply) &&
+ !HasFullMultiply)
+ continue;
- // Create non-masked policy intrinsic.
- if (Record.UnMaskedPolicyScheme != PolicyScheme::SchemeNone) {
- for (auto P : SupportedUnMaskedPolicies) {
+ // Expanded with different LMUL.
+ for (int Log2LMUL = -3; Log2LMUL <= 3; Log2LMUL++) {
+ if (!(Record.Log2LMULMask & (1 << (Log2LMUL + 3))))
+ continue;
+
+ std::optional<RVVTypes> Types =
+ TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoSeq);
+
+ // Ignored to create new intrinsic if there are any illegal types.
+ if (!Types.has_value())
+ continue;
+
+ std::string SuffixStr = RVVIntrinsic::getSuffixStr(
+ TypeCache, BaseType, Log2LMUL, SuffixProto);
+ std::string OverloadedSuffixStr = RVVIntrinsic::getSuffixStr(
+ TypeCache, BaseType, Log2LMUL, OverloadedSuffixProto);
+
+ // Create non-masked intrinsic.
+ InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, false, *Types,
+ UnMaskedHasPolicy, DefaultPolicy);
+
+ // Create non-masked policy intrinsic.
+ if (Record.UnMaskedPolicyScheme != PolicyScheme::SchemeNone) {
+ for (auto P : SupportedUnMaskedPolicies) {
+ llvm::SmallVector<PrototypeDescriptor> PolicyPrototype =
+ RVVIntrinsic::computeBuiltinTypes(
+ BasicProtoSeq, /*IsMasked=*/false,
+ /*HasMaskedOffOperand=*/false, Record.HasVL, Record.NF,
+ UnMaskedPolicyScheme, P);
+ std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
+ BaseType, Log2LMUL, Record.NF, PolicyPrototype);
+ InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
+ /*IsMask=*/false, *PolicyTypes, UnMaskedHasPolicy,
+ P);
+ }
+ }
+ if (!Record.HasMasked)
+ continue;
+ // Create masked intrinsic.
+ std::optional<RVVTypes> MaskTypes =
+ TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoMaskSeq);
+ InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, true,
+ *MaskTypes, MaskedHasPolicy, DefaultPolicy);
+ if (Record.MaskedPolicyScheme == PolicyScheme::SchemeNone)
+ continue;
+ // Create masked policy intrinsic.
+ for (auto P : SupportedMaskedPolicies) {
llvm::SmallVector<PrototypeDescriptor> PolicyPrototype =
RVVIntrinsic::computeBuiltinTypes(
- BasicProtoSeq, /*IsMasked=*/false,
- /*HasMaskedOffOperand=*/false, Record.HasVL, Record.NF,
- UnMaskedPolicyScheme, P);
+ BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
+ Record.HasVL, Record.NF, MaskedPolicyScheme, P);
std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
BaseType, Log2LMUL, Record.NF, PolicyPrototype);
InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
- /*IsMask=*/false, *PolicyTypes, UnMaskedHasPolicy,
- P);
+ /*IsMask=*/true, *PolicyTypes, MaskedHasPolicy, P);
}
- }
- if (!Record.HasMasked)
- continue;
- // Create masked intrinsic.
- std::optional<RVVTypes> MaskTypes =
- TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoMaskSeq);
- InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, true,
- *MaskTypes, MaskedHasPolicy, DefaultPolicy);
- if (Record.MaskedPolicyScheme == PolicyScheme::SchemeNone)
- continue;
- // Create masked policy intrinsic.
- for (auto P : SupportedMaskedPolicies) {
- llvm::SmallVector<PrototypeDescriptor> PolicyPrototype =
- RVVIntrinsic::computeBuiltinTypes(
- BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
- Record.HasVL, Record.NF, MaskedPolicyScheme, P);
- std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
- BaseType, Log2LMUL, Record.NF, PolicyPrototype);
- InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
- /*IsMask=*/true, *PolicyTypes, MaskedHasPolicy, P);
- }
- } // End for different LMUL
- } // End for different TypeRange
- }
+ } // End for different LMUL
+ } // End for different TypeRange
+ }
+ };
+ if (S.DeclareRISCVVBuiltins)
+ ConstructRVVIntrinsics(RVVIntrinsicRecords,
+ IntrinsicKind::RVV);
+ if (S.DeclareRISCVVCIXBuiltins)
+ ConstructRVVIntrinsics(RVSiFiveVCIXIntrinsicRecords,
+ IntrinsicKind::SIFIVE_VCIX);
}
// Compute name and signatures for intrinsic with practical types.
Index: clang/lib/Sema/SemaLookup.cpp
===================================================================
--- clang/lib/Sema/SemaLookup.cpp
+++ clang/lib/Sema/SemaLookup.cpp
@@ -932,7 +932,7 @@
}
}
- if (DeclareRISCVVBuiltins) {
+ if (DeclareRISCVVBuiltins || DeclareRISCVVCIXBuiltins) {
if (!RVIntrinsicManager)
RVIntrinsicManager = CreateRISCVIntrinsicManager(*this);
Index: clang/lib/Parse/ParsePragma.cpp
===================================================================
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -4023,6 +4023,7 @@
}
// Handle '#pragma clang riscv intrinsic vector'.
+// '#pragma clang riscv intrinsic sifive_vcix'.
void PragmaRISCVHandler::HandlePragma(Preprocessor &PP,
PragmaIntroducer Introducer,
Token &FirstToken) {
@@ -4038,9 +4039,11 @@
PP.Lex(Tok);
II = Tok.getIdentifierInfo();
- if (!II || !II->isStr("vector")) {
+ StringRef IntrinsicClass = II->getName();
+ if (!II || !(II->isStr("vector") || II->isStr("sifive_vcix"))) {
PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument)
- << PP.getSpelling(Tok) << "riscv" << /*Expected=*/true << "'vector'";
+ << PP.getSpelling(Tok) << "riscv" << /*Expected=*/true
+ << "'vector' or 'sifive_vcix'";
return;
}
@@ -4051,5 +4054,8 @@
return;
}
- Actions.DeclareRISCVVBuiltins = true;
+ if (IntrinsicClass == "vector")
+ Actions.DeclareRISCVVBuiltins = true;
+ else if (IntrinsicClass == "sifive_vcix")
+ Actions.DeclareRISCVVCIXBuiltins = true;
}
Index: clang/lib/Headers/sifive_vector.h
===================================================================
--- /dev/null
+++ clang/lib/Headers/sifive_vector.h
@@ -0,0 +1,16 @@
+//===----- sifive_vector.h - SiFive Vector definitions --------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _SIFIVE_VECTOR_H_
+#define _SIFIVE_VECTOR_H_
+
+#include "riscv_vector.h"
+
+#pragma clang riscv intrinsic sifive_vcix
+
+#endif //_SIFIVE_VECTOR_H_
Index: clang/lib/Headers/CMakeLists.txt
===================================================================
--- clang/lib/Headers/CMakeLists.txt
+++ clang/lib/Headers/CMakeLists.txt
@@ -98,6 +98,10 @@
htmxlintrin.h
)
+set(sifive_files
+ sifive_vector.h
+ )
+
set(systemz_files
s390intrin.h
vecintrin.h
@@ -244,6 +248,7 @@
${opencl_files}
${ppc_files}
${ppc_htm_files}
+ ${sifive_files}
${systemz_files}
${ve_files}
${x86_files}
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -19966,6 +19966,8 @@
// Vector builtins are handled from here.
#include "clang/Basic/riscv_vector_builtin_cg.inc"
+ // SiFive VCIX builtins are handled from here.
+#include "clang/Basic/riscv_sifive_vcix_builtin_cg.inc"
}
assert(ID != Intrinsic::not_intrinsic);
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -1621,6 +1621,9 @@
/// Indicate RISC-V vector builtin functions enabled or not.
bool DeclareRISCVVBuiltins = false;
+ /// Indicate RISC-V Sifive vcix builtin functions enabled or not.
+ bool DeclareRISCVVCIXBuiltins = false;
+
private:
std::unique_ptr<sema::RISCVIntrinsicManager> RVIntrinsicManager;
Index: clang/include/clang/Sema/RISCVIntrinsicManager.h
===================================================================
--- clang/include/clang/Sema/RISCVIntrinsicManager.h
+++ clang/include/clang/Sema/RISCVIntrinsicManager.h
@@ -22,6 +22,8 @@
namespace sema {
class RISCVIntrinsicManager {
public:
+ enum class IntrinsicKind : uint8_t { RVV, SIFIVE_VCIX };
+
virtual ~RISCVIntrinsicManager() = default;
// Create RISC-V intrinsic and insert into symbol table and return true if
Index: clang/include/clang/Basic/riscv_vector_common.td
===================================================================
--- /dev/null
+++ clang/include/clang/Basic/riscv_vector_common.td
@@ -0,0 +1,239 @@
+//==------ riscv_vector_common.td - RISC-V V-ext builtin class ------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines RVV builtin base class for RISC-V V-extension.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction definitions
+//===----------------------------------------------------------------------===//
+// Each record of the class RVVBuiltin defines a collection of builtins (i.e.
+// "def vadd : RVVBuiltin" will be used to define things like "vadd_vv_i32m1",
+// "vadd_vv_i32m2", etc).
+//
+// The elements of this collection are defined by an instantiation process the
+// range of which is specified by the cross product of the LMUL attribute and
+// every element in the attribute TypeRange. By default builtins have LMUL = [1,
+// 2, 4, 8, 1/2, 1/4, 1/8] so the process is repeated 7 times. In tablegen we
+// use the Log2LMUL [0, 1, 2, 3, -1, -2, -3] to represent the LMUL.
+//
+// LMUL represents the fact that the types of values used by that builtin are
+// values generated by instructions that are executed under that LMUL. However,
+// this does not mean the builtin is necessarily lowered into an instruction
+// that executes under the specified LMUL. An example where this happens are
+// loads and stores of masks. A mask like `vbool8_t` can be generated, for
+// instance, by comparing two `__rvv_int8m1_t` (this is LMUL=1) or comparing two
+// `__rvv_int16m2_t` (this is LMUL=2). The actual load or store, however, will
+// be performed under LMUL=1 because mask registers are not grouped.
+//
+// TypeRange is a non-empty sequence of basic types:
+//
+// c: int8_t (i8)
+// s: int16_t (i16)
+// i: int32_t (i32)
+// l: int64_t (i64)
+// x: float16_t (half)
+// f: float32_t (float)
+// d: float64_t (double)
+//
+// This way, given an LMUL, a record with a TypeRange "sil" will cause the
+// definition of 3 builtins. Each type "t" in the TypeRange (in this example
+// they are int16_t, int32_t, int64_t) is used as a parameter that drives the
+// definition of that particular builtin (for the given LMUL).
+//
+// During the instantiation, types can be transformed or modified using type
+// transformers. Given a type "t" the following primitive type transformers can
+// be applied to it to yield another type.
+//
+// e: type of "t" as is (identity)
+// v: computes a vector type whose element type is "t" for the current LMUL
+// w: computes a vector type identical to what 'v' computes except for the
+// element type which is twice as wide as the element type of 'v'
+// q: computes a vector type identical to what 'v' computes except for the
+// element type which is four times as wide as the element type of 'v'
+// o: computes a vector type identical to what 'v' computes except for the
+// element type which is eight times as wide as the element type of 'v'
+// m: computes a vector type identical to what 'v' computes except for the
+// element type which is bool
+// 0: void type, ignores "t"
+// z: size_t, ignores "t"
+// t: ptrdiff_t, ignores "t"
+// u: unsigned long, ignores "t"
+// l: long, ignores "t"
+//
+// So for instance if t is "i", i.e. int, then "e" will yield int again. "v"
+// will yield an RVV vector type (assume LMUL=1), so __rvv_int32m1_t.
+// Accordingly "w" would yield __rvv_int64m2_t.
+//
+// A type transformer can be prefixed by other non-primitive type transformers.
+//
+// P: constructs a pointer to the current type
+// C: adds const to the type
+// K: requires the integer type to be a constant expression
+// U: given an integer type or vector type, computes its unsigned variant
+// I: given a vector type, compute the vector type with integer type
+// elements of the same width
+// F: given a vector type, compute the vector type with floating-point type
+// elements of the same width
+// S: given a vector type, computes its equivalent one for LMUL=1. This is a
+// no-op if the vector was already LMUL=1
+// (Log2EEW:Value): Log2EEW value could be 3/4/5/6 (8/16/32/64), given a
+// vector type (SEW and LMUL) and EEW (8/16/32/64), computes its
+// equivalent integer vector type with EEW and corresponding ELMUL (elmul =
+// (eew/sew) * lmul). For example, vector type is __rvv_float16m4
+// (SEW=16, LMUL=4) and Log2EEW is 3 (EEW=8), and then equivalent vector
+// type is __rvv_uint8m2_t (elmul=(8/16)*4 = 2). Ignore to define a new
+// builtins if its equivalent type has illegal lmul.
+// (FixedSEW:Value): Given a vector type (SEW and LMUL), and computes another
+// vector type which only changed SEW as given value. Ignore to define a new
+// builtin if its equivalent type has illegal lmul or the SEW does not changed.
+// (SFixedLog2LMUL:Value): Smaller Fixed Log2LMUL. Given a vector type (SEW
+// and LMUL), and computes another vector type which only changed LMUL as
+// given value. The new LMUL should be smaller than the old one. Ignore to
+// define a new builtin if its equivalent type has illegal lmul.
+// (LFixedLog2LMUL:Value): Larger Fixed Log2LMUL. Given a vector type (SEW
+// and LMUL), and computes another vector type which only changed LMUL as
+// given value. The new LMUL should be larger than the old one. Ignore to
+// define a new builtin if its equivalent type has illegal lmul.
+//
+// Following with the example above, if t is "i", then "Ue" will yield unsigned
+// int and "Fv" will yield __rvv_float32m1_t (again assuming LMUL=1), Fw would
+// yield __rvv_float64m2_t, etc.
+//
+// Each builtin is then defined by applying each type in TypeRange against the
+// sequence of type transformers described in Suffix and Prototype.
+//
+// The name of the builtin is defined by the Name attribute (which defaults to
+// the name of the class) appended (separated with an underscore) the Suffix
+// attribute. For instance with Name="foo", Suffix = "v" and TypeRange = "il",
+// the builtin generated will be __builtin_rvv_foo_i32m1 and
+// __builtin_rvv_foo_i64m1 (under LMUL=1). If Suffix contains more than one
+// type transformer (say "vv") each of the types is separated with an
+// underscore as in "__builtin_rvv_foo_i32m1_i32m1".
+//
+// The C/C++ prototype of the builtin is defined by the Prototype attribute.
+// Prototype is a non-empty sequence of type transformers, the first of which
+// is the return type of the builtin and the rest are the parameters of the
+// builtin, in order. For instance if Prototype is "wvv" and TypeRange is "si"
+// a first builtin will have type
+// __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t) and the second builtin
+// will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t) (again
+// under LMUL=1).
+//
+// There are a number of attributes that are used to constraint the number and
+// shape of the builtins generated. Refer to the comments below for them.
+
+class PolicyScheme<int val>{
+ int Value = val;
+}
+def NonePolicy : PolicyScheme<0>;
+def HasPassthruOperand : PolicyScheme<1>;
+def HasPolicyOperand : PolicyScheme<2>;
+
+class RVVBuiltin<string suffix, string prototype, string type_range,
+ string overloaded_suffix = ""> {
+ // Base name that will be prepended in __builtin_rvv_ and appended the
+ // computed Suffix.
+ string Name = NAME;
+
+ // If not empty, each instantiated builtin will have this appended after an
+ // underscore (_). It is instantiated like Prototype.
+ string Suffix = suffix;
+
+ // If empty, default OverloadedName is sub string of `Name` which end of first
+ // '_'. For example, the default overloaded name is `vadd` for Name `vadd_vv`.
+ // It's used for describe some special naming cases.
+ string OverloadedName = "";
+
+ // If not empty, each OverloadedName will have this appended after an
+ // underscore (_). It is instantiated like Prototype.
+ string OverloadedSuffix = overloaded_suffix;
+
+ // The different variants of the builtin, parameterised with a type.
+ string TypeRange = type_range;
+
+ // We use each type described in TypeRange and LMUL with prototype to
+ // instantiate a specific element of the set of builtins being defined.
+ // Prototype attribute defines the C/C++ prototype of the builtin. It is a
+ // non-empty sequence of type transformers, the first of which is the return
+ // type of the builtin and the rest are the parameters of the builtin, in
+ // order. For instance if Prototype is "wvv", TypeRange is "si" and LMUL=1, a
+ // first builtin will have type
+ // __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t), and the second builtin
+ // will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t).
+ string Prototype = prototype;
+
+ // This builtin has a masked form.
+ bit HasMasked = true;
+
+ // If HasMasked, this flag states that this builtin has a maskedoff operand. It
+ // is always the first operand in builtin and IR intrinsic.
+ bit HasMaskedOffOperand = true;
+
+ // This builtin has a granted vector length parameter.
+ bit HasVL = true;
+
+ // The policy scheme for masked intrinsic IR.
+ // It could be NonePolicy or HasPolicyOperand.
+ // HasPolicyOperand: Has a policy operand. 0 is tail and mask undisturbed, 1 is
+ // tail agnostic, 2 is mask undisturbed, and 3 is tail and mask agnostic. The
+ // policy operand is located at the last position.
+ PolicyScheme MaskedPolicyScheme = HasPolicyOperand;
+
+ // The policy scheme for unmasked intrinsic IR.
+ // It could be NonePolicy, HasPassthruOperand or HasPolicyOperand.
+ // HasPassthruOperand: Has a passthru operand to decide tail policy. If it is
+ // poison, tail policy is tail agnostic, otherwise policy is tail undisturbed.
+ // HasPolicyOperand: Has a policy operand. 1 is tail agnostic and 0 is tail
+ // undisturbed.
+ PolicyScheme UnMaskedPolicyScheme = NonePolicy;
+
+ // This builtin support tail agnostic and undisturbed policy.
+ bit HasTailPolicy = true;
+ // This builtin support mask agnostic and undisturbed policy.
+ bit HasMaskPolicy = true;
+
+ // This builtin prototype with TA or TAMA policy could not support overloading
+ // API. Other policy intrinsic functions would support overloading API with
+ // suffix `_tu`, `tumu`, `tuma`, `tamu` and `tama`.
+ bit SupportOverloading = true;
+
+ // This builtin is valid for the given Log2LMULs.
+ list<int> Log2LMUL = [0, 1, 2, 3, -1, -2, -3];
+
+ // Manual code in clang codegen riscv_vector_builtin_cg.inc
+ code ManualCodegen = [{}];
+
+ // When emit the automatic clang codegen, it describes what types we have to use
+ // to obtain the specific LLVM intrinsic. -1 means the return type, otherwise,
+ // k >= 0 meaning the k-th operand (counting from zero) of the codegen'd
+ // parameter of the unmasked version. k can't be the mask operand's position.
+ list<int> IntrinsicTypes = [];
+
+ // If these names are not empty, this is the ID of the LLVM intrinsic
+ // we want to lower to.
+ string IRName = NAME;
+
+ // If HasMasked, this is the ID of the LLVM intrinsic we want to lower to.
+ string MaskedIRName = NAME #"_mask";
+
+ // Use clang_builtin_alias to save the number of builtins.
+ bit HasBuiltinAlias = true;
+
+ // Features required to enable for this builtin.
+ list<string> RequiredFeatures = [];
+
+ // Number of fields for Load/Store Segment instructions.
+ int NF = 1;
+}
+
+// This is the code emitted in the header.
+class RVVHeader {
+ code HeaderCode;
+}
Index: clang/include/clang/Basic/riscv_vector.td
===================================================================
--- clang/include/clang/Basic/riscv_vector.td
+++ clang/include/clang/Basic/riscv_vector.td
@@ -12,233 +12,7 @@
//
//===----------------------------------------------------------------------===//
-//===----------------------------------------------------------------------===//
-// Instruction definitions
-//===----------------------------------------------------------------------===//
-// Each record of the class RVVBuiltin defines a collection of builtins (i.e.
-// "def vadd : RVVBuiltin" will be used to define things like "vadd_vv_i32m1",
-// "vadd_vv_i32m2", etc).
-//
-// The elements of this collection are defined by an instantiation process the
-// range of which is specified by the cross product of the LMUL attribute and
-// every element in the attribute TypeRange. By default builtins have LMUL = [1,
-// 2, 4, 8, 1/2, 1/4, 1/8] so the process is repeated 7 times. In tablegen we
-// use the Log2LMUL [0, 1, 2, 3, -1, -2, -3] to represent the LMUL.
-//
-// LMUL represents the fact that the types of values used by that builtin are
-// values generated by instructions that are executed under that LMUL. However,
-// this does not mean the builtin is necessarily lowered into an instruction
-// that executes under the specified LMUL. An example where this happens are
-// loads and stores of masks. A mask like `vbool8_t` can be generated, for
-// instance, by comparing two `__rvv_int8m1_t` (this is LMUL=1) or comparing two
-// `__rvv_int16m2_t` (this is LMUL=2). The actual load or store, however, will
-// be performed under LMUL=1 because mask registers are not grouped.
-//
-// TypeRange is a non-empty sequence of basic types:
-//
-// c: int8_t (i8)
-// s: int16_t (i16)
-// i: int32_t (i32)
-// l: int64_t (i64)
-// x: float16_t (half)
-// f: float32_t (float)
-// d: float64_t (double)
-//
-// This way, given an LMUL, a record with a TypeRange "sil" will cause the
-// definition of 3 builtins. Each type "t" in the TypeRange (in this example
-// they are int16_t, int32_t, int64_t) is used as a parameter that drives the
-// definition of that particular builtin (for the given LMUL).
-//
-// During the instantiation, types can be transformed or modified using type
-// transformers. Given a type "t" the following primitive type transformers can
-// be applied to it to yield another type.
-//
-// e: type of "t" as is (identity)
-// v: computes a vector type whose element type is "t" for the current LMUL
-// w: computes a vector type identical to what 'v' computes except for the
-// element type which is twice as wide as the element type of 'v'
-// q: computes a vector type identical to what 'v' computes except for the
-// element type which is four times as wide as the element type of 'v'
-// o: computes a vector type identical to what 'v' computes except for the
-// element type which is eight times as wide as the element type of 'v'
-// m: computes a vector type identical to what 'v' computes except for the
-// element type which is bool
-// 0: void type, ignores "t"
-// z: size_t, ignores "t"
-// t: ptrdiff_t, ignores "t"
-// u: unsigned long, ignores "t"
-// l: long, ignores "t"
-//
-// So for instance if t is "i", i.e. int, then "e" will yield int again. "v"
-// will yield an RVV vector type (assume LMUL=1), so __rvv_int32m1_t.
-// Accordingly "w" would yield __rvv_int64m2_t.
-//
-// A type transformer can be prefixed by other non-primitive type transformers.
-//
-// P: constructs a pointer to the current type
-// C: adds const to the type
-// K: requires the integer type to be a constant expression
-// U: given an integer type or vector type, computes its unsigned variant
-// I: given a vector type, compute the vector type with integer type
-// elements of the same width
-// F: given a vector type, compute the vector type with floating-point type
-// elements of the same width
-// S: given a vector type, computes its equivalent one for LMUL=1. This is a
-// no-op if the vector was already LMUL=1
-// (Log2EEW:Value): Log2EEW value could be 3/4/5/6 (8/16/32/64), given a
-// vector type (SEW and LMUL) and EEW (8/16/32/64), computes its
-// equivalent integer vector type with EEW and corresponding ELMUL (elmul =
-// (eew/sew) * lmul). For example, vector type is __rvv_float16m4
-// (SEW=16, LMUL=4) and Log2EEW is 3 (EEW=8), and then equivalent vector
-// type is __rvv_uint8m2_t (elmul=(8/16)*4 = 2). Ignore to define a new
-// builtins if its equivalent type has illegal lmul.
-// (FixedSEW:Value): Given a vector type (SEW and LMUL), and computes another
-// vector type which only changed SEW as given value. Ignore to define a new
-// builtin if its equivalent type has illegal lmul or the SEW does not changed.
-// (SFixedLog2LMUL:Value): Smaller Fixed Log2LMUL. Given a vector type (SEW
-// and LMUL), and computes another vector type which only changed LMUL as
-// given value. The new LMUL should be smaller than the old one. Ignore to
-// define a new builtin if its equivalent type has illegal lmul.
-// (LFixedLog2LMUL:Value): Larger Fixed Log2LMUL. Given a vector type (SEW
-// and LMUL), and computes another vector type which only changed LMUL as
-// given value. The new LMUL should be larger than the old one. Ignore to
-// define a new builtin if its equivalent type has illegal lmul.
-//
-// Following with the example above, if t is "i", then "Ue" will yield unsigned
-// int and "Fv" will yield __rvv_float32m1_t (again assuming LMUL=1), Fw would
-// yield __rvv_float64m2_t, etc.
-//
-// Each builtin is then defined by applying each type in TypeRange against the
-// sequence of type transformers described in Suffix and Prototype.
-//
-// The name of the builtin is defined by the Name attribute (which defaults to
-// the name of the class) appended (separated with an underscore) the Suffix
-// attribute. For instance with Name="foo", Suffix = "v" and TypeRange = "il",
-// the builtin generated will be __builtin_rvv_foo_i32m1 and
-// __builtin_rvv_foo_i64m1 (under LMUL=1). If Suffix contains more than one
-// type transformer (say "vv") each of the types is separated with an
-// underscore as in "__builtin_rvv_foo_i32m1_i32m1".
-//
-// The C/C++ prototype of the builtin is defined by the Prototype attribute.
-// Prototype is a non-empty sequence of type transformers, the first of which
-// is the return type of the builtin and the rest are the parameters of the
-// builtin, in order. For instance if Prototype is "wvv" and TypeRange is "si"
-// a first builtin will have type
-// __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t) and the second builtin
-// will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t) (again
-// under LMUL=1).
-//
-// There are a number of attributes that are used to constraint the number and
-// shape of the builtins generated. Refer to the comments below for them.
-
-class PolicyScheme<int val>{
- int Value = val;
-}
-def NonePolicy : PolicyScheme<0>;
-def HasPassthruOperand : PolicyScheme<1>;
-def HasPolicyOperand : PolicyScheme<2>;
-
-class RVVBuiltin<string suffix, string prototype, string type_range,
- string overloaded_suffix = ""> {
- // Base name that will be prepended in __builtin_rvv_ and appended the
- // computed Suffix.
- string Name = NAME;
-
- // If not empty, each instantiated builtin will have this appended after an
- // underscore (_). It is instantiated like Prototype.
- string Suffix = suffix;
-
- // If empty, default OverloadedName is sub string of `Name` which end of first
- // '_'. For example, the default overloaded name is `vadd` for Name `vadd_vv`.
- // It's used for describe some special naming cases.
- string OverloadedName = "";
-
- // If not empty, each OverloadedName will have this appended after an
- // underscore (_). It is instantiated like Prototype.
- string OverloadedSuffix = overloaded_suffix;
-
- // The different variants of the builtin, parameterised with a type.
- string TypeRange = type_range;
-
- // We use each type described in TypeRange and LMUL with prototype to
- // instantiate a specific element of the set of builtins being defined.
- // Prototype attribute defines the C/C++ prototype of the builtin. It is a
- // non-empty sequence of type transformers, the first of which is the return
- // type of the builtin and the rest are the parameters of the builtin, in
- // order. For instance if Prototype is "wvv", TypeRange is "si" and LMUL=1, a
- // first builtin will have type
- // __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t), and the second builtin
- // will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t).
- string Prototype = prototype;
-
- // This builtin has a masked form.
- bit HasMasked = true;
-
- // If HasMasked, this flag states that this builtin has a maskedoff operand. It
- // is always the first operand in builtin and IR intrinsic.
- bit HasMaskedOffOperand = true;
-
- // This builtin has a granted vector length parameter.
- bit HasVL = true;
-
- // The policy scheme for masked intrinsic IR.
- // It could be NonePolicy or HasPolicyOperand.
- // HasPolicyOperand: Has a policy operand. 0 is tail and mask undisturbed, 1 is
- // tail agnostic, 2 is mask undisturbed, and 3 is tail and mask agnostic. The
- // policy operand is located at the last position.
- PolicyScheme MaskedPolicyScheme = HasPolicyOperand;
-
- // The policy scheme for unmasked intrinsic IR.
- // It could be NonePolicy, HasPassthruOperand or HasPolicyOperand.
- // HasPassthruOperand: Has a passthru operand to decide tail policy. If it is
- // poison, tail policy is tail agnostic, otherwise policy is tail undisturbed.
- // HasPolicyOperand: Has a policy operand. 1 is tail agnostic and 0 is tail
- // undisturbed.
- PolicyScheme UnMaskedPolicyScheme = NonePolicy;
-
- // This builtin support tail agnostic and undisturbed policy.
- bit HasTailPolicy = true;
- // This builtin support mask agnostic and undisturbed policy.
- bit HasMaskPolicy = true;
-
- // This builtin prototype with TA or TAMA policy could not support overloading
- // API. Other policy intrinsic functions would support overloading API with
- // suffix `_tu`, `tumu`, `tuma`, `tamu` and `tama`.
- bit SupportOverloading = true;
-
- // This builtin is valid for the given Log2LMULs.
- list<int> Log2LMUL = [0, 1, 2, 3, -1, -2, -3];
-
- // Manual code in clang codegen riscv_vector_builtin_cg.inc
- code ManualCodegen = [{}];
-
- // When emit the automatic clang codegen, it describes what types we have to use
- // to obtain the specific LLVM intrinsic. -1 means the return type, otherwise,
- // k >= 0 meaning the k-th operand (counting from zero) of the codegen'd
- // parameter of the unmasked version. k can't be the mask operand's position.
- list<int> IntrinsicTypes = [];
-
- // If these names are not empty, this is the ID of the LLVM intrinsic
- // we want to lower to.
- string IRName = NAME;
-
- // If HasMasked, this is the ID of the LLVM intrinsic we want to lower to.
- string MaskedIRName = NAME #"_mask";
-
- // Use clang_builtin_alias to save the number of builtins.
- bit HasBuiltinAlias = true;
-
- // Features required to enable for this builtin.
- list<string> RequiredFeatures = [];
-
- // Number of fields for Load/Store Segment instructions.
- int NF = 1;
-}
-
-// This is the code emitted in the header.
-class RVVHeader {
- code HeaderCode;
-}
+include "riscv_vector_common.td"
//===----------------------------------------------------------------------===//
// Basic classes with automatic codegen.
@@ -2374,91 +2148,3 @@
}
}
}
-
-class VCIXSuffix<string range> {
- list<string> suffix = !cond(!eq(range, "c"): ["8mf8", "8mf4", "8mf2", "8m1", "8m2", "8m4", "8m8"],
- !eq(range, "s"): ["16mf4", "16mf2", "16m1", "16m2", "16m4", "16m8"],
- !eq(range, "i"): ["32mf2", "32m1", "32m2", "32m4", "32m8"],
- !eq(range, "l"): ["64m1", "64m2", "64m4", "64m8"]);
-}
-
-class VCIXBuiltinSet<string name, string IR_name, string suffix,
- string prototype, string type_range,
- list<int> intrinsic_types>
- : RVVBuiltin<suffix, prototype, type_range> {
- let Name = name;
- let OverloadedName = name;
- let IRName = IR_name;
- let HasMasked = false;
- let IntrinsicTypes = intrinsic_types;
-}
-
-multiclass VCIXBuiltinSet<string name, string IR_name, string suffix,
- string prototype, string type_range,
- list<int> intrinsic_types> {
- if !find(prototype, "0") then {
- def : VCIXBuiltinSet<name, IR_name, suffix, prototype, type_range, intrinsic_types>;
- }
- def : VCIXBuiltinSet<name # "_se", IR_name # "_se", suffix, prototype, type_range, intrinsic_types>;
-}
-
-multiclass RVVVCIXBuiltinSet<list<string> range, string prototype,
- list<int> intrinsic_types, bit EncodeVtype,
- bit UseGPR> {
- defvar suffix = !if(EncodeVtype, "", "Uv");
- foreach r = range in {
- let RequiredFeatures = !if(!and(UseGPR, !eq(r, "l")),
- ["Xsfvcp", "RV64"], ["Xsfvcp"]) in {
- // If EncodeVtype is true, then these intrinsic don't have any vector
- // types in the output and inputs, but we still need to add vetvli for
- // them. So we encode different VTYPE into the intrinsic names, and
- // then will know which vsetvli is correct.
- if EncodeVtype then {
- foreach s = VCIXSuffix<r>.suffix in {
- defvar name = NAME # "_u" # s;
- defvar IR_name = NAME # "_e" # s;
- // Since we already encode the Vtype into the name, so just set
- // Log2LMUL to zero. Otherwise the RISCVVEmitter will expand
- // lots of redundant intrinsic but have same names.
- let Log2LMUL = [0] in
- def : VCIXBuiltinSet<name, IR_name, suffix, prototype, r, intrinsic_types>;
- }
- } else {
- defm : VCIXBuiltinSet<NAME, NAME, suffix, prototype, r, intrinsic_types>;
- }
- }
- }
-}
-
-let SupportOverloading = false in {
- defm sf_vc_x_se : RVVVCIXBuiltinSet<["c", "s", "i", "l"], "0KzKzKzUe", [0, 3], /*EncodeVtype*/1, /*UseGPR*/1>;
- defm sf_vc_i_se : RVVVCIXBuiltinSet<["c", "s", "i", "l"], "0KzKzKzKz", [2, 3], /*EncodeVtype*/1, /*UseGPR*/0>;
- defm sf_vc_xv : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvUe", [0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
- defm sf_vc_iv : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvKz", [0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_vv : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvUv", [0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_fv : RVVVCIXBuiltinSet<["si", "l"], "0KzKzUvFe", [0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_xvv : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvUe", [0, 1, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
- defm sf_vc_ivv : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvKz", [0, 1, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_vvv : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvUv", [0, 1, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_fvv : RVVVCIXBuiltinSet<["si", "l"], "0KzUvUvFe", [0, 1, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_v_x : RVVVCIXBuiltinSet<["csi", "l"], "UvKzKzUe", [-1, 1, 2], /*EncodeVtype*/0, /*UseGPR*/1>;
- defm sf_vc_v_i : RVVVCIXBuiltinSet<["csi", "l"], "UvKzKzKz", [-1, 1, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_v_xv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUe", [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/1>;
- defm sf_vc_v_iv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvKz", [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_v_vv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUv", [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_v_fv : RVVVCIXBuiltinSet<["si", "l"], "UvKzUvFe", [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_v_xvv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvUe", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
- defm sf_vc_v_ivv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvKz", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_v_vvv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvUv", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_v_fvv : RVVVCIXBuiltinSet<["si", "l"], "UvKzUvUvFe", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
- defm sf_vc_xvw : RVVVCIXBuiltinSet<["csi"], "0KzUwUvUe", [0, 1, 2, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
- defm sf_vc_ivw : RVVVCIXBuiltinSet<["csi"], "0KzUwUvKz", [0, 1, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_vvw : RVVVCIXBuiltinSet<["csi"], "0KzUwUvUv", [0, 1, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_fvw : RVVVCIXBuiltinSet<["si"], "0KzUwUvFe", [0, 1, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_v_xvw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvUe", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
- defm sf_vc_v_ivw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvKz", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_v_vvw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvUv", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- defm sf_vc_v_fvw : RVVVCIXBuiltinSet<["si"], "UwKzUwUvFe", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
- }
-}
Index: clang/include/clang/Basic/riscv_sifive_vcix.td
===================================================================
--- /dev/null
+++ clang/include/clang/Basic/riscv_sifive_vcix.td
@@ -0,0 +1,107 @@
+//==--- riscv_sifive_vcix.td - RISC-V SiFive VCIX function list -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the builtins for RISC-V SiFive VCIX. See:
+//
+// https://sifive.cdn.prismic.io/sifive/c3829e36-8552-41f0-a841-79945784241b_vcix-spec-software.pdf
+//
+//===----------------------------------------------------------------------===//
+
+include "riscv_vector_common.td"
+
+//===----------------------------------------------------------------------===//
+// Instruction definitions
+//===----------------------------------------------------------------------===//
+
+class VCIXSuffix<string range> {
+ list<string> suffix = !cond(!eq(range, "c"): ["8mf8", "8mf4", "8mf2", "8m1", "8m2", "8m4", "8m8"],
+ !eq(range, "s"): ["16mf4", "16mf2", "16m1", "16m2", "16m4", "16m8"],
+ !eq(range, "i"): ["32mf2", "32m1", "32m2", "32m4", "32m8"],
+ !eq(range, "l"): ["64m1", "64m2", "64m4", "64m8"]);
+}
+
+class VCIXBuiltinSet<string name, string IR_name, string suffix,
+ string prototype, string type_range,
+ list<int> intrinsic_types>
+ : RVVBuiltin<suffix, prototype, type_range> {
+ let Name = name;
+ let OverloadedName = name;
+ let IRName = IR_name;
+ let HasMasked = false;
+ let IntrinsicTypes = intrinsic_types;
+}
+
+multiclass VCIXBuiltinSet<string name, string IR_name, string suffix,
+ string prototype, string type_range,
+ list<int> intrinsic_types> {
+ if !find(prototype, "0") then {
+ def : VCIXBuiltinSet<name, IR_name, suffix, prototype, type_range, intrinsic_types>;
+ }
+ def : VCIXBuiltinSet<name # "_se", IR_name # "_se", suffix, prototype, type_range, intrinsic_types>;
+}
+
+multiclass RVVVCIXBuiltinSet<list<string> range, string prototype,
+ list<int> intrinsic_types, bit EncodeVtype,
+ bit UseGPR> {
+ defvar suffix = !if(EncodeVtype, "", "Uv");
+ foreach r = range in {
+ let RequiredFeatures = !if(!and(UseGPR, !eq(r, "l")),
+ ["Xsfvcp", "RV64"], ["Xsfvcp"]) in {
+ // If EncodeVtype is true, then these intrinsic don't have any vector
+ // types in the output and inputs, but we still need to add vetvli for
+ // them. So we encode different VTYPE into the intrinsic names, and
+ // then will know which vsetvli is correct.
+ if EncodeVtype then {
+ foreach s = VCIXSuffix<r>.suffix in {
+ defvar name = NAME # "_u" # s;
+ defvar IR_name = NAME # "_e" # s;
+ // Since we already encode the Vtype into the name, so just set
+ // Log2LMUL to zero. Otherwise the RISCVVEmitter will expand
+ // lots of redundant intrinsic but have same names.
+ let Log2LMUL = [0] in
+ def : VCIXBuiltinSet<name, IR_name, suffix, prototype, r, intrinsic_types>;
+ }
+ } else {
+ defm : VCIXBuiltinSet<NAME, NAME, suffix, prototype, r, intrinsic_types>;
+ }
+ }
+ }
+}
+
+let SupportOverloading = false in {
+ defm sf_vc_x_se : RVVVCIXBuiltinSet<["c", "s", "i", "l"], "0KzKzKzUe", [0, 3], /*EncodeVtype*/1, /*UseGPR*/1>;
+ defm sf_vc_i_se : RVVVCIXBuiltinSet<["c", "s", "i", "l"], "0KzKzKzKz", [2, 3], /*EncodeVtype*/1, /*UseGPR*/0>;
+ defm sf_vc_xv : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvUe", [0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
+ defm sf_vc_iv : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvKz", [0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_vv : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvUv", [0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_fv : RVVVCIXBuiltinSet<["si", "l"], "0KzKzUvFe", [0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_xvv : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvUe", [0, 1, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
+ defm sf_vc_ivv : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvKz", [0, 1, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_vvv : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvUv", [0, 1, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_fvv : RVVVCIXBuiltinSet<["si", "l"], "0KzUvUvFe", [0, 1, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_v_x : RVVVCIXBuiltinSet<["csi", "l"], "UvKzKzUe", [-1, 1, 2], /*EncodeVtype*/0, /*UseGPR*/1>;
+ defm sf_vc_v_i : RVVVCIXBuiltinSet<["csi", "l"], "UvKzKzKz", [-1, 1, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_v_xv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUe", [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/1>;
+ defm sf_vc_v_iv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvKz", [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_v_vv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUv", [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_v_fv : RVVVCIXBuiltinSet<["si", "l"], "UvKzUvFe", [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_v_xvv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvUe", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
+ defm sf_vc_v_ivv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvKz", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_v_vvv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvUv", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_v_fvv : RVVVCIXBuiltinSet<["si", "l"], "UvKzUvUvFe", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
+ defm sf_vc_xvw : RVVVCIXBuiltinSet<["csi"], "0KzUwUvUe", [0, 1, 2, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
+ defm sf_vc_ivw : RVVVCIXBuiltinSet<["csi"], "0KzUwUvKz", [0, 1, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_vvw : RVVVCIXBuiltinSet<["csi"], "0KzUwUvUv", [0, 1, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_fvw : RVVVCIXBuiltinSet<["si"], "0KzUwUvFe", [0, 1, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_v_xvw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvUe", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
+ defm sf_vc_v_ivw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvKz", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_v_vvw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvUv", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ defm sf_vc_v_fvw : RVVVCIXBuiltinSet<["si"], "UwKzUwUvFe", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+ }
+}
Index: clang/include/clang/Basic/CMakeLists.txt
===================================================================
--- clang/include/clang/Basic/CMakeLists.txt
+++ clang/include/clang/Basic/CMakeLists.txt
@@ -93,3 +93,12 @@
clang_tablegen(riscv_vector_builtin_sema.inc -gen-riscv-vector-builtin-sema
SOURCE riscv_vector.td
TARGET ClangRISCVVectorBuiltinSema)
+clang_tablegen(riscv_sifive_vcix_builtins.inc -gen-riscv-sifive-vcix-builtins
+ SOURCE riscv_sifive_vcix.td
+ TARGET ClangRISCVSiFiveVCIXBuiltins)
+clang_tablegen(riscv_sifive_vcix_builtin_cg.inc -gen-riscv-sifive-vcix-builtin-codegen
+ SOURCE riscv_sifive_vcix.td
+ TARGET ClangRISCVSiFiveVCIXBuiltinCG)
+clang_tablegen(riscv_sifive_vcix_builtin_sema.inc -gen-riscv-sifive-vcix-builtin-sema
+ SOURCE riscv_sifive_vcix.td
+ TARGET ClangRISCVSiFiveVCIXBuiltinSema)
Index: clang/include/clang/Basic/BuiltinsRISCVVector.def
===================================================================
--- clang/include/clang/Basic/BuiltinsRISCVVector.def
+++ clang/include/clang/Basic/BuiltinsRISCVVector.def
@@ -16,6 +16,7 @@
#endif
#include "clang/Basic/riscv_vector_builtins.inc"
+#include "clang/Basic/riscv_sifive_vcix_builtins.inc"
#undef BUILTIN
#undef TARGET_BUILTIN
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits