summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp58
1 files changed, 58 insertions, 0 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index b0a80b0ca79..c8a53ebd4cc 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -21,8 +21,10 @@
#include "WebAssemblyMCInstLower.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblyRegisterInfo.h"
+#include "WebAssemblyTargetMachine.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
@@ -159,6 +161,7 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
}
EmitProducerInfo(M);
+ EmitTargetFeatures();
}
void WebAssemblyAsmPrinter::EmitProducerInfo(Module &M) {
@@ -212,6 +215,61 @@ void WebAssemblyAsmPrinter::EmitProducerInfo(Module &M) {
}
}
+void WebAssemblyAsmPrinter::EmitTargetFeatures() {
+ static const std::pair<unsigned, const char *> FeaturePairs[] = {
+ {WebAssembly::FeatureAtomics, "atomics"},
+ {WebAssembly::FeatureBulkMemory, "bulk-memory"},
+ {WebAssembly::FeatureExceptionHandling, "exception-handling"},
+ {WebAssembly::FeatureNontrappingFPToInt, "nontrapping-fptoint"},
+ {WebAssembly::FeatureSignExt, "sign-ext"},
+ {WebAssembly::FeatureSIMD128, "simd128"},
+ };
+
+ struct FeatureEntry {
+ uint8_t Prefix;
+ StringRef Name;
+ };
+
+ FeatureBitset UsedFeatures =
+ static_cast<WebAssemblyTargetMachine &>(TM).getUsedFeatures();
+
+ // Calculate the features and linkage policies to emit
+ SmallVector<FeatureEntry, 4> EmittedFeatures;
+ for (auto &F : FeaturePairs) {
+ FeatureEntry Entry;
+ Entry.Name = F.second;
+ if (F.first == WebAssembly::FeatureAtomics) {
+ // "atomics" is special: code compiled without atomics may have had its
+ // atomics lowered to nonatomic operations. Such code would be dangerous
+ // to mix with proper atomics, so it is always Required or Disallowed.
+ Entry.Prefix = UsedFeatures[F.first] ? wasm::WASM_FEATURE_PREFIX_REQUIRED
+ : wasm::WASM_FEATURE_PREFIX_DISALLOWED;
+ EmittedFeatures.push_back(Entry);
+ } else {
+ // Other features are marked Used or not mentioned
+ if (UsedFeatures[F.first]) {
+ Entry.Prefix = wasm::WASM_FEATURE_PREFIX_USED;
+ EmittedFeatures.push_back(Entry);
+ }
+ }
+ }
+
+ // Emit features and linkage policies into the "target_features" section
+ MCSectionWasm *FeaturesSection = OutContext.getWasmSection(
+ ".custom_section.target_features", SectionKind::getMetadata());
+ OutStreamer->PushSection();
+ OutStreamer->SwitchSection(FeaturesSection);
+
+ OutStreamer->EmitULEB128IntValue(EmittedFeatures.size());
+ for (auto &F : EmittedFeatures) {
+ OutStreamer->EmitIntValue(F.Prefix, 1);
+ OutStreamer->EmitULEB128IntValue(F.Name.size());
+ OutStreamer->EmitBytes(F.Name);
+ }
+
+ OutStreamer->PopSection();
+}
+
void WebAssemblyAsmPrinter::EmitConstantPool() {
assert(MF->getConstantPool()->getConstants().empty() &&
"WebAssembly disables constant pools");
OpenPOWER on IntegriCloud