aboutsummaryrefslogtreecommitdiff
path: root/clang/utils/TableGen/RISCVVEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/utils/TableGen/RISCVVEmitter.cpp')
-rw-r--r--clang/utils/TableGen/RISCVVEmitter.cpp104
1 files changed, 65 insertions, 39 deletions
diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp
index 62eef830318f..4b80d6da72fa 100644
--- a/clang/utils/TableGen/RISCVVEmitter.cpp
+++ b/clang/utils/TableGen/RISCVVEmitter.cpp
@@ -100,6 +100,9 @@ public:
bool isValid() const { return Valid; }
bool isScalar() const { return Scale.hasValue() && Scale.getValue() == 0; }
bool isVector() const { return Scale.hasValue() && Scale.getValue() != 0; }
+ bool isVector(unsigned Width) const {
+ return isVector() && ElementBitwidth == Width;
+ }
bool isFloat() const { return ScalarType == ScalarTypeKind::Float; }
bool isSignedInteger() const {
return ScalarType == ScalarTypeKind::SignedInteger;
@@ -134,13 +137,16 @@ private:
using RVVTypePtr = RVVType *;
using RVVTypes = std::vector<RVVTypePtr>;
+using RISCVPredefinedMacroT = uint8_t;
-enum RISCVExtension : uint8_t {
+enum RISCVPredefinedMacro : RISCVPredefinedMacroT {
Basic = 0,
- F = 1 << 1,
- D = 1 << 2,
- Zfh = 1 << 3,
- Zvlsseg = 1 << 4,
+ V = 1 << 1,
+ Zfh = 1 << 2,
+ RV64 = 1 << 3,
+ VectorMaxELen64 = 1 << 4,
+ VectorMaxELenFp32 = 1 << 5,
+ VectorMaxELenFp64 = 1 << 6,
};
// TODO refactor RVVIntrinsic class design after support all intrinsic
@@ -164,7 +170,7 @@ private:
// The types we use to obtain the specific LLVM intrinsic. They are index of
// InputTypes. -1 means the return type.
std::vector<int64_t> IntrinsicTypes;
- uint8_t RISCVExtensions = 0;
+ RISCVPredefinedMacroT RISCVPredefinedMacros = 0;
unsigned NF = 1;
public:
@@ -174,7 +180,7 @@ public:
bool HasNoMaskedOverloaded, bool HasAutoDef,
StringRef ManualCodegen, const RVVTypes &Types,
const std::vector<int64_t> &IntrinsicTypes,
- StringRef RequiredExtension, unsigned NF);
+ const std::vector<StringRef> &RequiredFeatures, unsigned NF);
~RVVIntrinsic() = default;
StringRef getBuiltinName() const { return BuiltinName; }
@@ -188,7 +194,9 @@ public:
bool isMask() const { return IsMask; }
StringRef getIRName() const { return IRName; }
StringRef getManualCodegen() const { return ManualCodegen; }
- uint8_t getRISCVExtensions() const { return RISCVExtensions; }
+ RISCVPredefinedMacroT getRISCVPredefinedMacros() const {
+ return RISCVPredefinedMacros;
+ }
unsigned getNF() const { return NF; }
const std::vector<int64_t> &getIntrinsicTypes() const {
return IntrinsicTypes;
@@ -251,7 +259,8 @@ private:
// Emit the architecture preprocessor definitions. Return true when emits
// non-empty string.
- bool emitExtDefStr(uint8_t Extensions, raw_ostream &o);
+ bool emitMacroRestrictionStr(RISCVPredefinedMacroT PredefinedMacros,
+ raw_ostream &o);
// Slice Prototypes string into sub prototype string and process each sub
// prototype string individually in the Handler.
void parsePrototypes(StringRef Prototypes,
@@ -444,8 +453,8 @@ void RVVType::initBuiltinStr() {
return;
}
BuiltinStr = "q" + utostr(Scale.getValue()) + BuiltinStr;
- // Pointer to vector types. Defined for Zvlsseg load intrinsics.
- // Zvlsseg load intrinsics have pointer type arguments to store the loaded
+ // Pointer to vector types. Defined for segment load intrinsics.
+ // segment load intrinsics have pointer type arguments to store the loaded
// vector values.
if (IsPointer)
BuiltinStr += "*";
@@ -764,7 +773,8 @@ RVVIntrinsic::RVVIntrinsic(StringRef NewName, StringRef Suffix,
bool HasNoMaskedOverloaded, bool HasAutoDef,
StringRef ManualCodegen, const RVVTypes &OutInTypes,
const std::vector<int64_t> &NewIntrinsicTypes,
- StringRef RequiredExtension, unsigned NF)
+ const std::vector<StringRef> &RequiredFeatures,
+ unsigned NF)
: IRName(IRName), IsMask(IsMask), HasVL(HasVL), HasPolicy(HasPolicy),
HasNoMaskedOverloaded(HasNoMaskedOverloaded), HasAutoDef(HasAutoDef),
ManualCodegen(ManualCodegen.str()), NF(NF) {
@@ -788,14 +798,23 @@ RVVIntrinsic::RVVIntrinsic(StringRef NewName, StringRef Suffix,
// Init RISC-V extensions
for (const auto &T : OutInTypes) {
if (T->isFloatVector(16) || T->isFloat(16))
- RISCVExtensions |= RISCVExtension::Zfh;
- else if (T->isFloatVector(32) || T->isFloat(32))
- RISCVExtensions |= RISCVExtension::F;
- else if (T->isFloatVector(64) || T->isFloat(64))
- RISCVExtensions |= RISCVExtension::D;
+ RISCVPredefinedMacros |= RISCVPredefinedMacro::Zfh;
+ if (T->isFloatVector(32))
+ RISCVPredefinedMacros |= RISCVPredefinedMacro::VectorMaxELenFp32;
+ if (T->isFloatVector(64))
+ RISCVPredefinedMacros |= RISCVPredefinedMacro::VectorMaxELenFp64;
+ if (T->isVector(64))
+ RISCVPredefinedMacros |= RISCVPredefinedMacro::VectorMaxELen64;
+ }
+ for (auto Feature : RequiredFeatures) {
+ if (Feature == "RV64")
+ RISCVPredefinedMacros |= RISCVPredefinedMacro::RV64;
+ // Note: Full multiply instruction (mulh, mulhu, mulhsu, smul) for EEW=64
+ // require V.
+ if (Feature == "FullMultiply" &&
+ (RISCVPredefinedMacros & RISCVPredefinedMacro::VectorMaxELen64))
+ RISCVPredefinedMacros |= RISCVPredefinedMacro::V;
}
- if (RequiredExtension == "Zvlsseg")
- RISCVExtensions |= RISCVExtension::Zvlsseg;
// Init OutputType and InputTypes
OutputType = OutInTypes[0];
@@ -978,7 +997,7 @@ void RVVEmitter::createHeader(raw_ostream &OS) {
// The same extension include in the same arch guard marco.
llvm::stable_sort(Defs, [](const std::unique_ptr<RVVIntrinsic> &A,
const std::unique_ptr<RVVIntrinsic> &B) {
- return A->getRISCVExtensions() < B->getRISCVExtensions();
+ return A->getRISCVPredefinedMacros() < B->getRISCVPredefinedMacros();
});
OS << "#define __rvv_ai static __inline__\n";
@@ -1021,7 +1040,7 @@ void RVVEmitter::createBuiltins(raw_ostream &OS) {
OS << "#if defined(TARGET_BUILTIN) && !defined(RISCVV_BUILTIN)\n";
OS << "#define RISCVV_BUILTIN(ID, TYPE, ATTRS) TARGET_BUILTIN(ID, TYPE, "
- "ATTRS, \"experimental-v\")\n";
+ "ATTRS, \"zve32x|v\")\n";
OS << "#endif\n";
for (auto &Def : Defs) {
auto P =
@@ -1141,7 +1160,8 @@ void RVVEmitter::createRVVIntrinsics(
StringRef ManualCodegenMask = R->getValueAsString("ManualCodegenMask");
std::vector<int64_t> IntrinsicTypes =
R->getValueAsListOfInts("IntrinsicTypes");
- StringRef RequiredExtension = R->getValueAsString("RequiredExtension");
+ std::vector<StringRef> RequiredFeatures =
+ R->getValueAsListOfStrings("RequiredFeatures");
StringRef IRName = R->getValueAsString("IRName");
StringRef IRNameMask = R->getValueAsString("IRNameMask");
unsigned NF = R->getValueAsInt("NF");
@@ -1209,7 +1229,7 @@ void RVVEmitter::createRVVIntrinsics(
Name, SuffixStr, MangledName, MangledSuffixStr, IRName,
/*IsMask=*/false, /*HasMaskedOffOperand=*/false, HasVL, HasPolicy,
HasNoMaskedOverloaded, HasAutoDef, ManualCodegen, Types.getValue(),
- IntrinsicTypes, RequiredExtension, NF));
+ IntrinsicTypes, RequiredFeatures, NF));
if (HasMask) {
// Create a mask intrinsic
Optional<RVVTypes> MaskTypes =
@@ -1218,7 +1238,7 @@ void RVVEmitter::createRVVIntrinsics(
Name, SuffixStr, MangledName, MangledSuffixStr, IRNameMask,
/*IsMask=*/true, HasMaskedOffOperand, HasVL, HasPolicy,
HasNoMaskedOverloaded, HasAutoDef, ManualCodegenMask,
- MaskTypes.getValue(), IntrinsicTypes, RequiredExtension, NF));
+ MaskTypes.getValue(), IntrinsicTypes, RequiredFeatures, NF));
}
} // end for Log2LMULList
} // end for TypeRange
@@ -1276,15 +1296,16 @@ Optional<RVVTypePtr> RVVEmitter::computeType(BasicType BT, int Log2LMUL,
void RVVEmitter::emitArchMacroAndBody(
std::vector<std::unique_ptr<RVVIntrinsic>> &Defs, raw_ostream &OS,
std::function<void(raw_ostream &, const RVVIntrinsic &)> PrintBody) {
- uint8_t PrevExt = (*Defs.begin())->getRISCVExtensions();
- bool NeedEndif = emitExtDefStr(PrevExt, OS);
+ RISCVPredefinedMacroT PrevMacros =
+ (*Defs.begin())->getRISCVPredefinedMacros();
+ bool NeedEndif = emitMacroRestrictionStr(PrevMacros, OS);
for (auto &Def : Defs) {
- uint8_t CurExt = Def->getRISCVExtensions();
- if (CurExt != PrevExt) {
+ RISCVPredefinedMacroT CurMacros = Def->getRISCVPredefinedMacros();
+ if (CurMacros != PrevMacros) {
if (NeedEndif)
OS << "#endif\n\n";
- NeedEndif = emitExtDefStr(CurExt, OS);
- PrevExt = CurExt;
+ NeedEndif = emitMacroRestrictionStr(CurMacros, OS);
+ PrevMacros = CurMacros;
}
if (Def->hasAutoDef())
PrintBody(OS, *Def);
@@ -1293,19 +1314,24 @@ void RVVEmitter::emitArchMacroAndBody(
OS << "#endif\n\n";
}
-bool RVVEmitter::emitExtDefStr(uint8_t Extents, raw_ostream &OS) {
- if (Extents == RISCVExtension::Basic)
+bool RVVEmitter::emitMacroRestrictionStr(RISCVPredefinedMacroT PredefinedMacros,
+ raw_ostream &OS) {
+ if (PredefinedMacros == RISCVPredefinedMacro::Basic)
return false;
OS << "#if ";
ListSeparator LS(" && ");
- if (Extents & RISCVExtension::F)
- OS << LS << "defined(__riscv_f)";
- if (Extents & RISCVExtension::D)
- OS << LS << "defined(__riscv_d)";
- if (Extents & RISCVExtension::Zfh)
+ if (PredefinedMacros & RISCVPredefinedMacro::V)
+ OS << LS << "defined(__riscv_v)";
+ if (PredefinedMacros & RISCVPredefinedMacro::Zfh)
OS << LS << "defined(__riscv_zfh)";
- if (Extents & RISCVExtension::Zvlsseg)
- OS << LS << "defined(__riscv_zvlsseg)";
+ if (PredefinedMacros & RISCVPredefinedMacro::RV64)
+ OS << LS << "(__riscv_xlen == 64)";
+ if (PredefinedMacros & RISCVPredefinedMacro::VectorMaxELen64)
+ OS << LS << "(__riscv_v_elen >= 64)";
+ if (PredefinedMacros & RISCVPredefinedMacro::VectorMaxELenFp32)
+ OS << LS << "(__riscv_v_elen_fp >= 32)";
+ if (PredefinedMacros & RISCVPredefinedMacro::VectorMaxELenFp64)
+ OS << LS << "(__riscv_v_elen_fp >= 64)";
OS << "\n";
return true;
}