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 public:
34   explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
35       : TargetInfo(T), SIMDLevel(NoSIMD) {
36     NoAsmVariants = true;
37     SuitableAlign = 128;
38     LargeArrayMinWidth = 128;
39     LargeArrayAlign = 128;
40     SimdDefaultAlign = 128;
41     SigAtomicType = SignedLong;
42     LongDoubleWidth = LongDoubleAlign = 128;
43     LongDoubleFormat = &llvm::APFloat::IEEEquad();
44     SizeType = UnsignedInt;
45     PtrDiffType = SignedInt;
46     IntPtrType = SignedInt;
47   }
48 
49 protected:
50   void getTargetDefines(const LangOptions &Opts,
51                         MacroBuilder &Builder) const override;
52 
53 private:
54   bool
55   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
56                  StringRef CPU,
57                  const std::vector<std::string> &FeaturesVec) const override {
58     if (CPU == "bleeding-edge")
59       Features["simd128"] = true;
60     return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
61   }
62 
63   bool hasFeature(StringRef Feature) const final;
64 
65   bool handleTargetFeatures(std::vector<std::string> &Features,
66                             DiagnosticsEngine &Diags) final;
67 
68   bool isValidCPUName(StringRef Name) const final;
69 
70   bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
71 
72   ArrayRef<Builtin::Info> getTargetBuiltins() const final;
73 
74   BuiltinVaListKind getBuiltinVaListKind() const final {
75     return VoidPtrBuiltinVaList;
76   }
77 
78   ArrayRef<const char *> getGCCRegNames() const final { return None; }
79 
80   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
81     return None;
82   }
83 
84   bool validateAsmConstraint(const char *&Name,
85                              TargetInfo::ConstraintInfo &Info) const final {
86     return false;
87   }
88 
89   const char *getClobbers() const final { return ""; }
90 
91   bool isCLZForZeroUndef() const final { return false; }
92 
93   bool hasInt128Type() const final { return true; }
94 
95   IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
96     // WebAssembly prefers long long for explicitly 64-bit integers.
97     return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong)
98                           : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
99   }
100 
101   IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
102     // WebAssembly uses long long for int_least64_t and int_fast64_t.
103     return BitWidth == 64
104                ? (IsSigned ? SignedLongLong : UnsignedLongLong)
105                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
106   }
107 };
108 class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
109     : public WebAssemblyTargetInfo {
110 public:
111   explicit WebAssembly32TargetInfo(const llvm::Triple &T,
112                                    const TargetOptions &Opts)
113       : WebAssemblyTargetInfo(T, Opts) {
114     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
115     resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128");
116   }
117 
118 protected:
119   void getTargetDefines(const LangOptions &Opts,
120                         MacroBuilder &Builder) const override;
121 };
122 
123 class LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo
124     : public WebAssemblyTargetInfo {
125 public:
126   explicit WebAssembly64TargetInfo(const llvm::Triple &T,
127                                    const TargetOptions &Opts)
128       : WebAssemblyTargetInfo(T, Opts) {
129     LongAlign = LongWidth = 64;
130     PointerAlign = PointerWidth = 64;
131     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
132     SizeType = UnsignedLong;
133     PtrDiffType = SignedLong;
134     IntPtrType = SignedLong;
135     resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128");
136   }
137 
138 protected:
139   void getTargetDefines(const LangOptions &Opts,
140                         MacroBuilder &Builder) const override;
141 };
142 } // namespace targets
143 } // namespace clang
144 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
145