summaryrefslogtreecommitdiffstats
path: root/clang/lib/Basic/Targets.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Basic/Targets.cpp')
-rw-r--r--clang/lib/Basic/Targets.cpp176
1 files changed, 176 insertions, 0 deletions
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index c29a8001fd8..8b87ffde9d2 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -734,6 +734,35 @@ public:
}
};
+namespace {
+// WebAssembly target
+template <typename Target>
+class WebAssemblyOSTargetInfo : public OSTargetInfo<Target> {
+ void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+ MacroBuilder &Builder) const override final {
+ // A common platform macro.
+ if (Opts.POSIXThreads)
+ Builder.defineMacro("_REENTRANT");
+ // Follow g++ convention and predefine _GNU_SOURCE for C++.
+ if (Opts.CPlusPlus)
+ Builder.defineMacro("_GNU_SOURCE");
+ }
+
+ // As an optimization, group static init code together in a section.
+ const char *getStaticInitSectionSpecifier() const override final {
+ return ".text.__startup";
+ }
+
+public:
+ explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple)
+ : OSTargetInfo<Target>(Triple) {
+ this->MCountName = "__mcount";
+ this->UserLabelPrefix = "";
+ this->TheCXXABI.set(TargetCXXABI::WebAssembly);
+ }
+};
+} // end anonymous namespace
+
//===----------------------------------------------------------------------===//
// Specific target implementations.
//===----------------------------------------------------------------------===//
@@ -6955,6 +6984,145 @@ public:
bool hasProtectedVisibility() const override { return false; }
};
+
+class WebAssemblyTargetInfo : public TargetInfo {
+ static const Builtin::Info BuiltinInfo[];
+
+ enum SIMDEnum {
+ NoSIMD,
+ SIMD128,
+ } SIMDLevel;
+
+public:
+ explicit WebAssemblyTargetInfo(const llvm::Triple &T)
+ : TargetInfo(T), SIMDLevel(NoSIMD) {
+ BigEndian = false;
+ NoAsmVariants = true;
+ SuitableAlign = 128;
+ LargeArrayMinWidth = 128;
+ LargeArrayAlign = 128;
+ SimdDefaultAlign = 128;
+ }
+
+protected:
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override {
+ defineCPUMacros(Builder, "wasm", /*Tuning=*/false);
+ if (SIMDLevel >= SIMD128)
+ Builder.defineMacro("__wasm_simd128__");
+ }
+
+private:
+ bool initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
+ StringRef CPU,
+ std::vector<std::string> &FeaturesVec) const override {
+ if (CPU == "bleeding-edge")
+ Features["simd128"] = true;
+ return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
+ }
+ bool hasFeature(StringRef Feature) const override final {
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("simd128", SIMDLevel >= SIMD128)
+ .Default(false);
+ }
+ bool handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) override final {
+ for (const auto &Feature : Features) {
+ if (Feature == "+simd128") {
+ SIMDLevel = std::max(SIMDLevel, SIMD128);
+ continue;
+ }
+ if (Feature == "-simd128") {
+ SIMDLevel = std::min(SIMDLevel, SIMDEnum(SIMD128 - 1));
+ continue;
+ }
+
+ Diags.Report(diag::err_opt_not_valid_with_opt) << Feature
+ << "-target-feature";
+ return false;
+ }
+ return true;
+ }
+ bool setCPU(const std::string &Name) override final {
+ return llvm::StringSwitch<bool>(Name)
+ .Case("mvp", true)
+ .Case("bleeding-edge", true)
+ .Case("generic", true)
+ .Default(false);
+ }
+ void getTargetBuiltins(const Builtin::Info *&Records,
+ unsigned &NumRecords) const override final {
+ Records = BuiltinInfo;
+ NumRecords = clang::WebAssembly::LastTSBuiltin - Builtin::FirstTSBuiltin;
+ }
+ BuiltinVaListKind getBuiltinVaListKind() const override final {
+ // TODO: Implement va_list properly.
+ return VoidPtrBuiltinVaList;
+ }
+ void getGCCRegNames(const char *const *&Names,
+ unsigned &NumNames) const override final {
+ Names = nullptr;
+ NumNames = 0;
+ }
+ void getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const override final {
+ Aliases = nullptr;
+ NumAliases = 0;
+ }
+ bool
+ validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info) const override final {
+ return false;
+ }
+ const char *getClobbers() const override final { return ""; }
+ bool isCLZForZeroUndef() const override final { return false; }
+ bool hasInt128Type() const override final { return true; }
+};
+
+const Builtin::Info WebAssemblyTargetInfo::BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) \
+ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
+ { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
+#include "clang/Basic/BuiltinsWebAssembly.def"
+};
+
+class WebAssembly32TargetInfo : public WebAssemblyTargetInfo {
+public:
+ explicit WebAssembly32TargetInfo(const llvm::Triple &T)
+ : WebAssemblyTargetInfo(T) {
+ // TODO: Set this to the correct value once the spec issues are resolved.
+ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
+ DataLayoutString = "e-p:32:32-i64:64-n32:64-S128";
+ }
+
+protected:
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override {
+ WebAssemblyTargetInfo::getTargetDefines(Opts, Builder);
+ defineCPUMacros(Builder, "wasm32", /*Tuning=*/false);
+ }
+};
+
+class WebAssembly64TargetInfo : public WebAssemblyTargetInfo {
+public:
+ explicit WebAssembly64TargetInfo(const llvm::Triple &T)
+ : WebAssemblyTargetInfo(T) {
+ LongAlign = LongWidth = 64;
+ PointerAlign = PointerWidth = 64;
+ // TODO: Set this to the correct value once the spec issues are resolved.
+ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
+ DataLayoutString = "e-p:64:64-i64:64-n32:64-S128";
+ }
+
+protected:
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override {
+ WebAssemblyTargetInfo::getTargetDefines(Opts, Builder);
+ defineCPUMacros(Builder, "wasm64", /*Tuning=*/false);
+ }
+};
+
} // end anonymous namespace.
const Builtin::Info Le64TargetInfo::BuiltinInfo[] = {
@@ -7559,6 +7727,14 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
return nullptr;
return new SPIR64TargetInfo(Triple);
}
+ case llvm::Triple::wasm32:
+ if (!(Triple == llvm::Triple("wasm32-unknown-unknown")))
+ return nullptr;
+ return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple);
+ case llvm::Triple::wasm64:
+ if (!(Triple == llvm::Triple("wasm64-unknown-unknown")))
+ return nullptr;
+ return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple);
}
}
OpenPOWER on IntegriCloud