xref: /llvm-project/clang/lib/Basic/Targets/RISCV.h (revision d9ab3e82f30d646deff054230b0c742704a1cf26)
1 //===--- RISCV.h - Declare RISCV target feature support ---------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares RISCV TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H
14 #define LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H
15 
16 #include "clang/Basic/TargetInfo.h"
17 #include "clang/Basic/TargetOptions.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/Compiler.h"
20 #include "llvm/Support/RISCVISAInfo.h"
21 
22 namespace clang {
23 namespace targets {
24 
25 // RISC-V Target
26 class RISCVTargetInfo : public TargetInfo {
27 protected:
28   std::string ABI, CPU;
29   std::unique_ptr<llvm::RISCVISAInfo> ISAInfo;
30 
31 public:
32   RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
33       : TargetInfo(Triple) {
34     LongDoubleWidth = 128;
35     LongDoubleAlign = 128;
36     LongDoubleFormat = &llvm::APFloat::IEEEquad();
37     SuitableAlign = 128;
38     WCharType = SignedInt;
39     WIntType = UnsignedInt;
40     HasRISCVVTypes = true;
41     MCountName = "_mcount";
42     HasFloat16 = true;
43   }
44 
45   bool setCPU(const std::string &Name) override {
46     if (!isValidCPUName(Name))
47       return false;
48     CPU = Name;
49     return true;
50   }
51 
52   StringRef getABI() const override { return ABI; }
53   void getTargetDefines(const LangOptions &Opts,
54                         MacroBuilder &Builder) const override;
55 
56   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
57 
58   BuiltinVaListKind getBuiltinVaListKind() const override {
59     return TargetInfo::VoidPtrBuiltinVaList;
60   }
61 
62   const char *getClobbers() const override { return ""; }
63 
64   StringRef getConstraintRegister(StringRef Constraint,
65                                   StringRef Expression) const override {
66     return Expression;
67   }
68 
69   ArrayRef<const char *> getGCCRegNames() const override;
70 
71   int getEHDataRegisterNumber(unsigned RegNo) const override {
72     if (RegNo == 0)
73       return 10;
74     else if (RegNo == 1)
75       return 11;
76     else
77       return -1;
78   }
79 
80   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
81 
82   bool validateAsmConstraint(const char *&Name,
83                              TargetInfo::ConstraintInfo &Info) const override;
84 
85   std::string convertConstraint(const char *&Constraint) const override;
86 
87   bool
88   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
89                  StringRef CPU,
90                  const std::vector<std::string> &FeaturesVec) const override;
91 
92   Optional<std::pair<unsigned, unsigned>>
93   getVScaleRange(const LangOptions &LangOpts) const override;
94 
95   bool hasFeature(StringRef Feature) const override;
96 
97   bool handleTargetFeatures(std::vector<std::string> &Features,
98                             DiagnosticsEngine &Diags) override;
99 
100   bool hasBitIntType() const override { return true; }
101 
102   bool useFP16ConversionIntrinsics() const override {
103     return false;
104   }
105 
106   bool isValidCPUName(StringRef Name) const override;
107   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
108   bool isValidTuneCPUName(StringRef Name) const override;
109   void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
110 };
111 class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
112 public:
113   RISCV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
114       : RISCVTargetInfo(Triple, Opts) {
115     IntPtrType = SignedInt;
116     PtrDiffType = SignedInt;
117     SizeType = UnsignedInt;
118     resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128");
119   }
120 
121   bool setABI(const std::string &Name) override {
122     if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") {
123       ABI = Name;
124       return true;
125     }
126     return false;
127   }
128 
129   void setMaxAtomicWidth() override {
130     MaxAtomicPromoteWidth = 128;
131 
132     if (ISAInfo->hasExtension("a"))
133       MaxAtomicInlineWidth = 32;
134   }
135 };
136 class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
137 public:
138   RISCV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
139       : RISCVTargetInfo(Triple, Opts) {
140     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
141     IntMaxType = Int64Type = SignedLong;
142     resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128");
143   }
144 
145   bool setABI(const std::string &Name) override {
146     if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") {
147       ABI = Name;
148       return true;
149     }
150     return false;
151   }
152 
153   void setMaxAtomicWidth() override {
154     MaxAtomicPromoteWidth = 128;
155 
156     if (ISAInfo->hasExtension("a"))
157       MaxAtomicInlineWidth = 64;
158   }
159 };
160 } // namespace targets
161 } // namespace clang
162 
163 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H
164