1 //=== WebAssembly.h - Declare WebAssembly target feature support *- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares WebAssembly TargetInfo objects.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
15 #define LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
16 
17 #include "clang/Basic/TargetInfo.h"
18 #include "clang/Basic/TargetOptions.h"
19 #include "llvm/ADT/Triple.h"
20 #include "llvm/Support/Compiler.h"
21 
22 namespace clang {
23 namespace targets {
24 
25 class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
26   static const Builtin::Info BuiltinInfo[];
27 
28   enum SIMDEnum {
29     NoSIMD,
30     SIMD128,
31   } SIMDLevel;
32 
33   bool HasNontrappingFPToInt;
34   bool HasSignExt;
35 
36 public:
37   explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
38       : TargetInfo(T), SIMDLevel(NoSIMD), HasNontrappingFPToInt(false),
39         HasSignExt(false) {
40     NoAsmVariants = true;
41     SuitableAlign = 128;
42     LargeArrayMinWidth = 128;
43     LargeArrayAlign = 128;
44     SimdDefaultAlign = 128;
45     SigAtomicType = SignedLong;
46     LongDoubleWidth = LongDoubleAlign = 128;
47     LongDoubleFormat = &llvm::APFloat::IEEEquad();
48     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
49     SizeType = UnsignedInt;
50     PtrDiffType = SignedInt;
51     IntPtrType = SignedInt;
52   }
53 
54 protected:
55   void getTargetDefines(const LangOptions &Opts,
56                         MacroBuilder &Builder) const override;
57 
58 private:
59   bool
60   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
61                  StringRef CPU,
62                  const std::vector<std::string> &FeaturesVec) const override {
63     if (CPU == "bleeding-edge") {
64       Features["simd128"] = true;
65       Features["nontrapping-fptoint"] = true;
66       Features["sign-ext"] = true;
67     }
68     return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
69   }
70 
71   bool hasFeature(StringRef Feature) const final;
72 
73   bool handleTargetFeatures(std::vector<std::string> &Features,
74                             DiagnosticsEngine &Diags) final;
75 
76   bool isValidCPUName(StringRef Name) const final;
77   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const final;
78 
79   bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
80 
81   ArrayRef<Builtin::Info> getTargetBuiltins() const final;
82 
83   BuiltinVaListKind getBuiltinVaListKind() const final {
84     return VoidPtrBuiltinVaList;
85   }
86 
87   ArrayRef<const char *> getGCCRegNames() const final { return None; }
88 
89   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
90     return None;
91   }
92 
93   bool validateAsmConstraint(const char *&Name,
94                              TargetInfo::ConstraintInfo &Info) const final {
95     return false;
96   }
97 
98   const char *getClobbers() const final { return ""; }
99 
100   bool isCLZForZeroUndef() const final { return false; }
101 
102   bool hasInt128Type() const final { return true; }
103 
104   IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
105     // WebAssembly prefers long long for explicitly 64-bit integers.
106     return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong)
107                           : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
108   }
109 
110   IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
111     // WebAssembly uses long long for int_least64_t and int_fast64_t.
112     return BitWidth == 64
113                ? (IsSigned ? SignedLongLong : UnsignedLongLong)
114                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
115   }
116 };
117 class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
118     : public WebAssemblyTargetInfo {
119 public:
120   explicit WebAssembly32TargetInfo(const llvm::Triple &T,
121                                    const TargetOptions &Opts)
122       : WebAssemblyTargetInfo(T, Opts) {
123     resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128");
124   }
125 
126 protected:
127   void getTargetDefines(const LangOptions &Opts,
128                         MacroBuilder &Builder) const override;
129 };
130 
131 class LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo
132     : public WebAssemblyTargetInfo {
133 public:
134   explicit WebAssembly64TargetInfo(const llvm::Triple &T,
135                                    const TargetOptions &Opts)
136       : WebAssemblyTargetInfo(T, Opts) {
137     LongAlign = LongWidth = 64;
138     PointerAlign = PointerWidth = 64;
139     SizeType = UnsignedLong;
140     PtrDiffType = SignedLong;
141     IntPtrType = SignedLong;
142     resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128");
143   }
144 
145 protected:
146   void getTargetDefines(const LangOptions &Opts,
147                         MacroBuilder &Builder) const override;
148 };
149 } // namespace targets
150 } // namespace clang
151 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
152