xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
106c3fb27SDimitry Andric //===--- RISCV.h - Declare RISC-V target feature support --------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
906c3fb27SDimitry Andric // This file declares RISC-V TargetInfo objects.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H
140b57cec5SDimitry Andric #define LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
170b57cec5SDimitry Andric #include "clang/Basic/TargetOptions.h"
180b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
19*0fca6ea1SDimitry Andric #include "llvm/TargetParser/RISCVISAInfo.h"
2006c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
21bdd1243dSDimitry Andric #include <optional>
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric namespace clang {
240b57cec5SDimitry Andric namespace targets {
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric // RISC-V Target
270b57cec5SDimitry Andric class RISCVTargetInfo : public TargetInfo {
280b57cec5SDimitry Andric protected:
29590d96feSDimitry Andric   std::string ABI, CPU;
30349cc55cSDimitry Andric   std::unique_ptr<llvm::RISCVISAInfo> ISAInfo;
31fe6060f1SDimitry Andric 
325f757f3fSDimitry Andric private:
33*0fca6ea1SDimitry Andric   bool FastScalarUnalignedAccess;
34cb14a3feSDimitry Andric   bool HasExperimental = false;
355f757f3fSDimitry Andric 
360b57cec5SDimitry Andric public:
RISCVTargetInfo(const llvm::Triple & Triple,const TargetOptions &)370b57cec5SDimitry Andric   RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
38e8d8bef9SDimitry Andric       : TargetInfo(Triple) {
395f757f3fSDimitry Andric     BFloat16Width = 16;
405f757f3fSDimitry Andric     BFloat16Align = 16;
415f757f3fSDimitry Andric     BFloat16Format = &llvm::APFloat::BFloat();
420b57cec5SDimitry Andric     LongDoubleWidth = 128;
430b57cec5SDimitry Andric     LongDoubleAlign = 128;
440b57cec5SDimitry Andric     LongDoubleFormat = &llvm::APFloat::IEEEquad();
450b57cec5SDimitry Andric     SuitableAlign = 128;
460b57cec5SDimitry Andric     WCharType = SignedInt;
470b57cec5SDimitry Andric     WIntType = UnsignedInt;
48fe6060f1SDimitry Andric     HasRISCVVTypes = true;
49fe6060f1SDimitry Andric     MCountName = "_mcount";
50fe6060f1SDimitry Andric     HasFloat16 = true;
5106c3fb27SDimitry Andric     HasStrictFP = true;
520b57cec5SDimitry Andric   }
530b57cec5SDimitry Andric 
setCPU(const std::string & Name)54590d96feSDimitry Andric   bool setCPU(const std::string &Name) override {
55590d96feSDimitry Andric     if (!isValidCPUName(Name))
56590d96feSDimitry Andric       return false;
57590d96feSDimitry Andric     CPU = Name;
58590d96feSDimitry Andric     return true;
59590d96feSDimitry Andric   }
60590d96feSDimitry Andric 
getABI()610b57cec5SDimitry Andric   StringRef getABI() const override { return ABI; }
620b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
630b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
640b57cec5SDimitry Andric 
65fe6060f1SDimitry Andric   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
660b57cec5SDimitry Andric 
getBuiltinVaListKind()670b57cec5SDimitry Andric   BuiltinVaListKind getBuiltinVaListKind() const override {
680b57cec5SDimitry Andric     return TargetInfo::VoidPtrBuiltinVaList;
690b57cec5SDimitry Andric   }
700b57cec5SDimitry Andric 
getClobbers()7106c3fb27SDimitry Andric   std::string_view getClobbers() const override { return ""; }
720b57cec5SDimitry Andric 
getConstraintRegister(StringRef Constraint,StringRef Expression)73349cc55cSDimitry Andric   StringRef getConstraintRegister(StringRef Constraint,
74349cc55cSDimitry Andric                                   StringRef Expression) const override {
75349cc55cSDimitry Andric     return Expression;
76349cc55cSDimitry Andric   }
77349cc55cSDimitry Andric 
780b57cec5SDimitry Andric   ArrayRef<const char *> getGCCRegNames() const override;
790b57cec5SDimitry Andric 
getEHDataRegisterNumber(unsigned RegNo)800b57cec5SDimitry Andric   int getEHDataRegisterNumber(unsigned RegNo) const override {
810b57cec5SDimitry Andric     if (RegNo == 0)
820b57cec5SDimitry Andric       return 10;
830b57cec5SDimitry Andric     else if (RegNo == 1)
840b57cec5SDimitry Andric       return 11;
850b57cec5SDimitry Andric     else
860b57cec5SDimitry Andric       return -1;
870b57cec5SDimitry Andric   }
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric   bool validateAsmConstraint(const char *&Name,
920b57cec5SDimitry Andric                              TargetInfo::ConstraintInfo &Info) const override;
930b57cec5SDimitry Andric 
94fe6060f1SDimitry Andric   std::string convertConstraint(const char *&Constraint) const override;
95fe6060f1SDimitry Andric 
96fe6060f1SDimitry Andric   bool
97fe6060f1SDimitry Andric   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
98fe6060f1SDimitry Andric                  StringRef CPU,
99fe6060f1SDimitry Andric                  const std::vector<std::string> &FeaturesVec) const override;
100fe6060f1SDimitry Andric 
101bdd1243dSDimitry Andric   std::optional<std::pair<unsigned, unsigned>>
102bdd1243dSDimitry Andric   getVScaleRange(const LangOptions &LangOpts) const override;
103bdd1243dSDimitry Andric 
1040b57cec5SDimitry Andric   bool hasFeature(StringRef Feature) const override;
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric   bool handleTargetFeatures(std::vector<std::string> &Features,
1070b57cec5SDimitry Andric                             DiagnosticsEngine &Diags) override;
1085ffd83dbSDimitry Andric 
hasBitIntType()1090eae32dcSDimitry Andric   bool hasBitIntType() const override { return true; }
11081ad6265SDimitry Andric 
hasBFloat16Type()1115f757f3fSDimitry Andric   bool hasBFloat16Type() const override { return true; }
1125f757f3fSDimitry Andric 
113*0fca6ea1SDimitry Andric   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
114*0fca6ea1SDimitry Andric 
useFP16ConversionIntrinsics()11581ad6265SDimitry Andric   bool useFP16ConversionIntrinsics() const override {
11681ad6265SDimitry Andric     return false;
11781ad6265SDimitry Andric   }
118bdd1243dSDimitry Andric 
119bdd1243dSDimitry Andric   bool isValidCPUName(StringRef Name) const override;
120bdd1243dSDimitry Andric   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
121bdd1243dSDimitry Andric   bool isValidTuneCPUName(StringRef Name) const override;
122bdd1243dSDimitry Andric   void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
supportsTargetAttributeTune()1235f757f3fSDimitry Andric   bool supportsTargetAttributeTune() const override { return true; }
1245f757f3fSDimitry Andric   ParsedTargetAttr parseTargetAttr(StringRef Str) const override;
125*0fca6ea1SDimitry Andric 
hardwareInterferenceSizes()126*0fca6ea1SDimitry Andric   std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
127*0fca6ea1SDimitry Andric     return std::make_pair(32, 32);
128*0fca6ea1SDimitry Andric   }
1290b57cec5SDimitry Andric };
1300b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
1310b57cec5SDimitry Andric public:
RISCV32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1320b57cec5SDimitry Andric   RISCV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1330b57cec5SDimitry Andric       : RISCVTargetInfo(Triple, Opts) {
1340b57cec5SDimitry Andric     IntPtrType = SignedInt;
1350b57cec5SDimitry Andric     PtrDiffType = SignedInt;
1360b57cec5SDimitry Andric     SizeType = UnsignedInt;
1370b57cec5SDimitry Andric     resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128");
1380b57cec5SDimitry Andric   }
1390b57cec5SDimitry Andric 
setABI(const std::string & Name)1400b57cec5SDimitry Andric   bool setABI(const std::string &Name) override {
1417a6dacacSDimitry Andric     if (Name == "ilp32e") {
1427a6dacacSDimitry Andric       ABI = Name;
1437a6dacacSDimitry Andric       resetDataLayout("e-m:e-p:32:32-i64:64-n32-S32");
1447a6dacacSDimitry Andric       return true;
1457a6dacacSDimitry Andric     }
1467a6dacacSDimitry Andric 
1470b57cec5SDimitry Andric     if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") {
1480b57cec5SDimitry Andric       ABI = Name;
1490b57cec5SDimitry Andric       return true;
1500b57cec5SDimitry Andric     }
1510b57cec5SDimitry Andric     return false;
1520b57cec5SDimitry Andric   }
1530b57cec5SDimitry Andric 
setMaxAtomicWidth()1540b57cec5SDimitry Andric   void setMaxAtomicWidth() override {
1550b57cec5SDimitry Andric     MaxAtomicPromoteWidth = 128;
1560b57cec5SDimitry Andric 
157349cc55cSDimitry Andric     if (ISAInfo->hasExtension("a"))
1580b57cec5SDimitry Andric       MaxAtomicInlineWidth = 32;
1590b57cec5SDimitry Andric   }
1600b57cec5SDimitry Andric };
1610b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
1620b57cec5SDimitry Andric public:
RISCV64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1630b57cec5SDimitry Andric   RISCV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1640b57cec5SDimitry Andric       : RISCVTargetInfo(Triple, Opts) {
1650b57cec5SDimitry Andric     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
1660b57cec5SDimitry Andric     IntMaxType = Int64Type = SignedLong;
167bdd1243dSDimitry Andric     resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128");
1680b57cec5SDimitry Andric   }
1690b57cec5SDimitry Andric 
setABI(const std::string & Name)1700b57cec5SDimitry Andric   bool setABI(const std::string &Name) override {
1717a6dacacSDimitry Andric     if (Name == "lp64e") {
1727a6dacacSDimitry Andric       ABI = Name;
1737a6dacacSDimitry Andric       resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S64");
1747a6dacacSDimitry Andric       return true;
1757a6dacacSDimitry Andric     }
1767a6dacacSDimitry Andric 
1770b57cec5SDimitry Andric     if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") {
1780b57cec5SDimitry Andric       ABI = Name;
1790b57cec5SDimitry Andric       return true;
1800b57cec5SDimitry Andric     }
1810b57cec5SDimitry Andric     return false;
1820b57cec5SDimitry Andric   }
1830b57cec5SDimitry Andric 
setMaxAtomicWidth()1840b57cec5SDimitry Andric   void setMaxAtomicWidth() override {
1850b57cec5SDimitry Andric     MaxAtomicPromoteWidth = 128;
1860b57cec5SDimitry Andric 
187349cc55cSDimitry Andric     if (ISAInfo->hasExtension("a"))
1880b57cec5SDimitry Andric       MaxAtomicInlineWidth = 64;
1890b57cec5SDimitry Andric   }
1900b57cec5SDimitry Andric };
1910b57cec5SDimitry Andric } // namespace targets
1920b57cec5SDimitry Andric } // namespace clang
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H
195