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