1202379Srdivacky//=== WebAssembly.h - Declare WebAssembly target feature support *- C++ -*-===//
2202379Srdivacky//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6202379Srdivacky//
7202379Srdivacky//===----------------------------------------------------------------------===//
8202379Srdivacky//
9202379Srdivacky// This file declares WebAssembly TargetInfo objects.
10202379Srdivacky//
11202379Srdivacky//===----------------------------------------------------------------------===//
12202379Srdivacky
13202379Srdivacky#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
14280031Sdim#define LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
15280031Sdim
16202379Srdivacky#include "clang/Basic/TargetInfo.h"
17327952Sdim#include "clang/Basic/TargetOptions.h"
18280031Sdim#include "llvm/ADT/Triple.h"
19249423Sdim#include "llvm/Support/Compiler.h"
20226633Sdim
21327952Sdimnamespace clang {
22276479Sdimnamespace targets {
23218893Sdim
24218893Sdimclass LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
25202379Srdivacky  static const Builtin::Info BuiltinInfo[];
26276479Sdim
27276479Sdim  enum SIMDEnum {
28276479Sdim    NoSIMD,
29276479Sdim    SIMD128,
30202379Srdivacky    UnimplementedSIMD128,
31202379Srdivacky  } SIMDLevel = NoSIMD;
32202379Srdivacky
33276479Sdim  bool HasNontrappingFPToInt = false;
34202379Srdivacky  bool HasSignExt = false;
35276479Sdim  bool HasExceptionHandling = false;
36309124Sdim  bool HasBulkMemory = false;
37276479Sdim  bool HasAtomics = false;
38276479Sdim  bool HasMutableGlobals = false;
39327952Sdim  bool HasMultivalue = false;
40276479Sdim  bool HasTailCall = false;
41202379Srdivacky
42276479Sdimpublic:
43276479Sdim  explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
44276479Sdim      : TargetInfo(T) {
45276479Sdim    NoAsmVariants = true;
46276479Sdim    SuitableAlign = 128;
47202379Srdivacky    LargeArrayMinWidth = 128;
48276479Sdim    LargeArrayAlign = 128;
49276479Sdim    SimdDefaultAlign = 128;
50296417Sdim    SigAtomicType = SignedLong;
51276479Sdim    LongDoubleWidth = LongDoubleAlign = 128;
52202379Srdivacky    LongDoubleFormat = &llvm::APFloat::IEEEquad();
53276479Sdim    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
54276479Sdim    // size_t being unsigned long for both wasm32 and wasm64 makes mangled names
55204643Srdivacky    // more consistent between the two.
56288943Sdim    SizeType = UnsignedLong;
57276479Sdim    PtrDiffType = SignedLong;
58288943Sdim    IntPtrType = SignedLong;
59341825Sdim  }
60212904Sdim
61288943Sdimprotected:
62276479Sdim  void getTargetDefines(const LangOptions &Opts,
63276479Sdim                        MacroBuilder &Builder) const override;
64276479Sdim
65204643Srdivackyprivate:
66276479Sdim  static void setSIMDLevel(llvm::StringMap<bool> &Features, SIMDEnum Level);
67276479Sdim
68276479Sdim  bool
69276479Sdim  initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
70276479Sdim                 StringRef CPU,
71276479Sdim                 const std::vector<std::string> &FeaturesVec) const override;
72276479Sdim  bool hasFeature(StringRef Feature) const final;
73276479Sdim
74276479Sdim  bool handleTargetFeatures(std::vector<std::string> &Features,
75204793Srdivacky                            DiagnosticsEngine &Diags) final;
76276479Sdim
77276479Sdim  bool isValidCPUName(StringRef Name) const final;
78276479Sdim  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const final;
79276479Sdim
80276479Sdim  bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
81276479Sdim
82276479Sdim  ArrayRef<Builtin::Info> getTargetBuiltins() const final;
83276479Sdim
84204793Srdivacky  BuiltinVaListKind getBuiltinVaListKind() const final {
85276479Sdim    return VoidPtrBuiltinVaList;
86276479Sdim  }
87276479Sdim
88276479Sdim  ArrayRef<const char *> getGCCRegNames() const final { return None; }
89276479Sdim
90276479Sdim  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
91276479Sdim    return None;
92204643Srdivacky  }
93276479Sdim
94276479Sdim  bool validateAsmConstraint(const char *&Name,
95276479Sdim                             TargetInfo::ConstraintInfo &Info) const final {
96276479Sdim    return false;
97276479Sdim  }
98276479Sdim
99276479Sdim  const char *getClobbers() const final { return ""; }
100276479Sdim
101218893Sdim  bool isCLZForZeroUndef() const final { return false; }
102276479Sdim
103276479Sdim  bool hasInt128Type() const final { return true; }
104276479Sdim
105276479Sdim  IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
106276479Sdim    // WebAssembly prefers long long for explicitly 64-bit integers.
107276479Sdim    return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong)
108276479Sdim                          : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
109276479Sdim  }
110276479Sdim
111224145Sdim  IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
112276479Sdim    // WebAssembly uses long long for int_least64_t and int_fast64_t.
113276479Sdim    return BitWidth == 64
114276479Sdim               ? (IsSigned ? SignedLongLong : UnsignedLongLong)
115276479Sdim               : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
116276479Sdim  }
117276479Sdim};
118276479Sdimclass LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
119276479Sdim    : public WebAssemblyTargetInfo {
120276479Sdimpublic:
121226633Sdim  explicit WebAssembly32TargetInfo(const llvm::Triple &T,
122276479Sdim                                   const TargetOptions &Opts)
123276479Sdim      : WebAssemblyTargetInfo(T, Opts) {
124276479Sdim    resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128");
125276479Sdim  }
126276479Sdim
127276479Sdimprotected:
128276479Sdim  void getTargetDefines(const LangOptions &Opts,
129276479Sdim                        MacroBuilder &Builder) const override;
130276479Sdim};
131276479Sdim
132261991Sdimclass LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo
133280031Sdim    : public WebAssemblyTargetInfo {
134280031Sdimpublic:
135280031Sdim  explicit WebAssembly64TargetInfo(const llvm::Triple &T,
136280031Sdim                                   const TargetOptions &Opts)
137280031Sdim      : WebAssemblyTargetInfo(T, Opts) {
138280031Sdim    LongAlign = LongWidth = 64;
139280031Sdim    PointerAlign = PointerWidth = 64;
140280031Sdim    SizeType = UnsignedLong;
141276479Sdim    PtrDiffType = SignedLong;
142276479Sdim    IntPtrType = SignedLong;
143276479Sdim    resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128");
144261991Sdim  }
145276479Sdim
146276479Sdimprotected:
147276479Sdim  void getTargetDefines(const LangOptions &Opts,
148276479Sdim                        MacroBuilder &Builder) const override;
149276479Sdim};
150276479Sdim} // namespace targets
151276479Sdim} // namespace clang
152276479Sdim#endif // LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
153276479Sdim