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