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 {
setDataLayout()26   void setDataLayout() {
27     StringRef Layout;
28 
29     if (ABI == "ilp32" || ABI == "ilp32f" || ABI == "ilp32d" ||
30         ABI == "ilp32e" ||
31         ABI == "il32pc64" || ABI == "il32pc64f" || ABI == "il32pc64d" ||
32         ABI == "il32pc64e") {
33       if (HasCheri)
34         Layout = "e-m:e-pf200:64:64:64:32-p:32:32-i64:64-n32-S128";
35       else
36         Layout = "e-m:e-p:32:32-i64:64-n32-S128";
37     } else if (ABI == "lp64" || ABI == "lp64f" || ABI == "lp64d" ||
38                ABI == "l64pc128" || ABI == "l64pc128f" || ABI == "l64pc128d") {
39       if (HasCheri)
40         Layout = "e-m:e-pf200:128:128:128:64-p:64:64-i64:64-i128:128-n64-S128";
41       else
42         Layout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128";
43     } else
44       llvm_unreachable("Invalid ABI");
45 
46     StringRef PurecapOptions = "";
47     // Only set globals address space to 200 for cap-table mode
48     if (CapabilityABI)
49       PurecapOptions = "-A200-P200-G200";
50 
51     resetDataLayout((Layout + PurecapOptions).str());
52   }
53 
54 protected:
55   std::string ABI;
56   bool HasM;
57   bool HasA;
58   bool HasF;
59   bool HasD;
60   bool HasC;
61   bool HasB;
62   bool HasCheri = false;
63   int CapSize = -1;
64 
setCapabilityABITypes()65   void setCapabilityABITypes() {
66     IntPtrType = TargetInfo::SignedIntCap;
67   }
68 
69 public:
RISCVTargetInfo(const llvm::Triple & Triple,const TargetOptions &)70   RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
71       : TargetInfo(Triple), HasM(false), HasA(false), HasF(false),
72         HasD(false), HasC(false), HasB(false) {
73     LongDoubleWidth = 128;
74     LongDoubleAlign = 128;
75     LongDoubleFormat = &llvm::APFloat::IEEEquad();
76     SuitableAlign = 128;
77     WCharType = SignedInt;
78     WIntType = UnsignedInt;
79   }
80 
getABI()81   StringRef getABI() const override { return ABI; }
82   void getTargetDefines(const LangOptions &Opts,
83                         MacroBuilder &Builder) const override;
84 
getTargetBuiltins()85   ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
86 
getBuiltinVaListKind()87   BuiltinVaListKind getBuiltinVaListKind() const override {
88     return TargetInfo::VoidPtrBuiltinVaList;
89   }
90 
getClobbers()91   const char *getClobbers() const override { return ""; }
92 
93   ArrayRef<const char *> getGCCRegNames() const override;
94 
getEHDataRegisterNumber(unsigned RegNo)95   int getEHDataRegisterNumber(unsigned RegNo) const override {
96     if (RegNo == 0)
97       return 10;
98     else if (RegNo == 1)
99       return 11;
100     else
101       return -1;
102   }
103 
104   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
105 
106   bool validateAsmConstraint(const char *&Name,
107                              TargetInfo::ConstraintInfo &Info) const override;
108 
109   bool hasFeature(StringRef Feature) const override;
110 
111   bool handleTargetFeatures(std::vector<std::string> &Features,
112                             DiagnosticsEngine &Diags) override;
113 
getIntCapWidth()114   unsigned getIntCapWidth() const override { return CapSize; }
getIntCapAlign()115   unsigned getIntCapAlign() const override { return CapSize; }
116 
getCHERICapabilityWidth()117   uint64_t getCHERICapabilityWidth() const override { return CapSize; }
118 
getCHERICapabilityAlign()119   uint64_t getCHERICapabilityAlign() const override { return CapSize; }
120 
getPointerWidthV(unsigned AddrSpace)121   uint64_t getPointerWidthV(unsigned AddrSpace) const override {
122     return (AddrSpace == 200) ? CapSize : PointerWidth;
123   }
124 
getPointerRangeV(unsigned AddrSpace)125   uint64_t getPointerRangeV(unsigned AddrSpace) const override {
126     return (AddrSpace == 200) ? getPointerRangeForCHERICapability() : PointerWidth;
127   }
128 
getPointerAlignV(unsigned AddrSpace)129   uint64_t getPointerAlignV(unsigned AddrSpace) const override {
130     return (AddrSpace == 200) ? CapSize : PointerAlign;
131   }
132 
SupportsCapabilities()133   bool SupportsCapabilities() const override { return HasCheri; }
134 
135   bool validateTarget(DiagnosticsEngine &Diags) const override;
136 
hasExtIntType()137   bool hasExtIntType() const override { return true; }
138 };
139 class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
140 public:
RISCV32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)141   RISCV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
142       : RISCVTargetInfo(Triple, Opts) {
143     ABI = "ilp32";
144     IntPtrType = SignedInt;
145     PtrDiffType = SignedInt;
146     SizeType = UnsignedInt;
147   }
148 
setABI(const std::string & Name)149   bool setABI(const std::string &Name) override {
150     if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") {
151       ABI = Name;
152       return true;
153     }
154     if (Name == "il32pc64" || Name == "il32pc64f" || Name == "il32pc64d") {
155       setCapabilityABITypes();
156       CapabilityABI = true;
157       ABI = Name;
158       return true;
159     }
160     return false;
161   }
162 
setMaxAtomicWidth()163   void setMaxAtomicWidth() override {
164     MaxAtomicPromoteWidth = 128;
165 
166     if (HasA)
167       MaxAtomicInlineWidth = 32;
168   }
169 
getPointerRangeForCHERICapability()170   uint64_t getPointerRangeForCHERICapability() const override { return 32; }
171 };
172 class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
173 public:
RISCV64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)174   RISCV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
175       : RISCVTargetInfo(Triple, Opts) {
176     ABI = "lp64";
177     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
178     IntMaxType = Int64Type = SignedLong;
179   }
180 
setABI(const std::string & Name)181   bool setABI(const std::string &Name) override {
182     if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") {
183       ABI = Name;
184       return true;
185     }
186     if (Name == "l64pc128" || Name == "l64pc128f" || Name == "l64pc128d") {
187       setCapabilityABITypes();
188       CapabilityABI = true;
189       ABI = Name;
190       return true;
191     }
192     return false;
193   }
194 
setMaxAtomicWidth()195   void setMaxAtomicWidth() override {
196     MaxAtomicPromoteWidth = 128;
197 
198     if (HasA)
199       MaxAtomicInlineWidth = 64;
200   }
201 
getPointerRangeForCHERICapability()202   uint64_t getPointerRangeForCHERICapability() const override { return 64; }
203 };
204 } // namespace targets
205 } // namespace clang
206 
207 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H
208