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 
21 namespace clang {
22 namespace targets {
23 
24 // RISC-V Target
25 class RISCVTargetInfo : public TargetInfo {
26 protected:
27   std::string ABI, CPU;
28   bool HasM = false;
29   bool HasA = false;
30   bool HasF = false;
31   bool HasD = false;
32   bool HasC = false;
33   bool HasB = false;
34   bool HasV = false;
35   bool HasZba = false;
36   bool HasZbb = false;
37   bool HasZbc = false;
38   bool HasZbe = false;
39   bool HasZbf = false;
40   bool HasZbm = false;
41   bool HasZbp = false;
42   bool HasZbproposedc = false;
43   bool HasZbr = false;
44   bool HasZbs = false;
45   bool HasZbt = false;
46   bool HasZfh = false;
47   bool HasZvamo = false;
48   bool HasZvlsseg = false;
49 
50   static const Builtin::Info BuiltinInfo[];
51 
52 public:
RISCVTargetInfo(const llvm::Triple & Triple,const TargetOptions &)53   RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
54       : TargetInfo(Triple) {
55     LongDoubleWidth = 128;
56     LongDoubleAlign = 128;
57     LongDoubleFormat = &llvm::APFloat::IEEEquad();
58     SuitableAlign = 128;
59     WCharType = SignedInt;
60     WIntType = UnsignedInt;
61     HasRISCVVTypes = true;
62     MCountName = "_mcount";
63     HasFloat16 = true;
64   }
65 
setCPU(const std::string & Name)66   bool setCPU(const std::string &Name) override {
67     if (!isValidCPUName(Name))
68       return false;
69     CPU = Name;
70     return true;
71   }
72 
getABI()73   StringRef getABI() const override { return ABI; }
74   void getTargetDefines(const LangOptions &Opts,
75                         MacroBuilder &Builder) const override;
76 
77   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
78 
getBuiltinVaListKind()79   BuiltinVaListKind getBuiltinVaListKind() const override {
80     return TargetInfo::VoidPtrBuiltinVaList;
81   }
82 
getClobbers()83   const char *getClobbers() const override { return ""; }
84 
85   ArrayRef<const char *> getGCCRegNames() const override;
86 
getEHDataRegisterNumber(unsigned RegNo)87   int getEHDataRegisterNumber(unsigned RegNo) const override {
88     if (RegNo == 0)
89       return 10;
90     else if (RegNo == 1)
91       return 11;
92     else
93       return -1;
94   }
95 
96   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
97 
98   bool validateAsmConstraint(const char *&Name,
99                              TargetInfo::ConstraintInfo &Info) const override;
100 
101   std::string convertConstraint(const char *&Constraint) const override;
102 
103   bool
104   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
105                  StringRef CPU,
106                  const std::vector<std::string> &FeaturesVec) const override;
107 
108   bool hasFeature(StringRef Feature) const override;
109 
110   bool handleTargetFeatures(std::vector<std::string> &Features,
111                             DiagnosticsEngine &Diags) override;
112 
hasExtIntType()113   bool hasExtIntType() const override { return true; }
114 };
115 class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
116 public:
RISCV32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)117   RISCV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
118       : RISCVTargetInfo(Triple, Opts) {
119     IntPtrType = SignedInt;
120     PtrDiffType = SignedInt;
121     SizeType = UnsignedInt;
122     resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128");
123   }
124 
setABI(const std::string & Name)125   bool setABI(const std::string &Name) override {
126     if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") {
127       ABI = Name;
128       return true;
129     }
130     return false;
131   }
132 
133   bool isValidCPUName(StringRef Name) const override;
134   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
135   bool isValidTuneCPUName(StringRef Name) const override;
136   void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
137 
setMaxAtomicWidth()138   void setMaxAtomicWidth() override {
139     MaxAtomicPromoteWidth = 128;
140 
141     if (HasA)
142       MaxAtomicInlineWidth = 32;
143   }
144 };
145 class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
146 public:
RISCV64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)147   RISCV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
148       : RISCVTargetInfo(Triple, Opts) {
149     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
150     IntMaxType = Int64Type = SignedLong;
151     resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n64-S128");
152   }
153 
setABI(const std::string & Name)154   bool setABI(const std::string &Name) override {
155     if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") {
156       ABI = Name;
157       return true;
158     }
159     return false;
160   }
161 
162   bool isValidCPUName(StringRef Name) const override;
163   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
164   bool isValidTuneCPUName(StringRef Name) const override;
165   void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
166 
setMaxAtomicWidth()167   void setMaxAtomicWidth() override {
168     MaxAtomicPromoteWidth = 128;
169 
170     if (HasA)
171       MaxAtomicInlineWidth = 64;
172   }
173 };
174 } // namespace targets
175 } // namespace clang
176 
177 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H
178