diff options
Diffstat (limited to 'clang/utils/TableGen/RISCVVEmitter.cpp')
-rw-r--r-- | clang/utils/TableGen/RISCVVEmitter.cpp | 104 |
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; } |