1444ed5c5SDimitry Andric //==-- WebAssemblyTargetStreamer.cpp - WebAssembly Target Streamer Methods --=//
2444ed5c5SDimitry Andric //
3444ed5c5SDimitry Andric // The LLVM Compiler Infrastructure
4444ed5c5SDimitry Andric //
5444ed5c5SDimitry Andric // This file is distributed under the University of Illinois Open Source
6444ed5c5SDimitry Andric // License. See LICENSE.TXT for details.
7444ed5c5SDimitry Andric //
8444ed5c5SDimitry Andric //===----------------------------------------------------------------------===//
9444ed5c5SDimitry Andric ///
10444ed5c5SDimitry Andric /// \file
114ba319b5SDimitry Andric /// This file defines WebAssembly-specific target streamer classes.
12444ed5c5SDimitry Andric /// These are for implementing support for target-specific assembly directives.
13444ed5c5SDimitry Andric ///
14444ed5c5SDimitry Andric //===----------------------------------------------------------------------===//
15444ed5c5SDimitry Andric
16444ed5c5SDimitry Andric #include "WebAssemblyTargetStreamer.h"
17444ed5c5SDimitry Andric #include "InstPrinter/WebAssemblyInstPrinter.h"
18444ed5c5SDimitry Andric #include "WebAssemblyMCTargetDesc.h"
19444ed5c5SDimitry Andric #include "llvm/MC/MCContext.h"
207a7e6055SDimitry Andric #include "llvm/MC/MCSectionWasm.h"
21444ed5c5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
227a7e6055SDimitry Andric #include "llvm/MC/MCSymbolWasm.h"
237a7e6055SDimitry Andric #include "llvm/Support/Casting.h"
24444ed5c5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
25444ed5c5SDimitry Andric #include "llvm/Support/FormattedStream.h"
26444ed5c5SDimitry Andric using namespace llvm;
27444ed5c5SDimitry Andric
WebAssemblyTargetStreamer(MCStreamer & S)28444ed5c5SDimitry Andric WebAssemblyTargetStreamer::WebAssemblyTargetStreamer(MCStreamer &S)
29444ed5c5SDimitry Andric : MCTargetStreamer(S) {}
30444ed5c5SDimitry Andric
emitValueType(wasm::ValType Type)317a7e6055SDimitry Andric void WebAssemblyTargetStreamer::emitValueType(wasm::ValType Type) {
324ba319b5SDimitry Andric Streamer.EmitIntValue(uint8_t(Type), 1);
337a7e6055SDimitry Andric }
347a7e6055SDimitry Andric
WebAssemblyTargetAsmStreamer(MCStreamer & S,formatted_raw_ostream & OS)35444ed5c5SDimitry Andric WebAssemblyTargetAsmStreamer::WebAssemblyTargetAsmStreamer(
36444ed5c5SDimitry Andric MCStreamer &S, formatted_raw_ostream &OS)
37444ed5c5SDimitry Andric : WebAssemblyTargetStreamer(S), OS(OS) {}
38444ed5c5SDimitry Andric
WebAssemblyTargetWasmStreamer(MCStreamer & S)397a7e6055SDimitry Andric WebAssemblyTargetWasmStreamer::WebAssemblyTargetWasmStreamer(MCStreamer &S)
407a7e6055SDimitry Andric : WebAssemblyTargetStreamer(S) {}
417a7e6055SDimitry Andric
printTypes(formatted_raw_ostream & OS,ArrayRef<wasm::ValType> Types)42*b5893f02SDimitry Andric static void printTypes(formatted_raw_ostream &OS,
43*b5893f02SDimitry Andric ArrayRef<wasm::ValType> Types) {
44444ed5c5SDimitry Andric bool First = true;
45*b5893f02SDimitry Andric for (auto Type : Types) {
46444ed5c5SDimitry Andric if (First)
47444ed5c5SDimitry Andric First = false;
48444ed5c5SDimitry Andric else
49444ed5c5SDimitry Andric OS << ", ";
50*b5893f02SDimitry Andric OS << WebAssembly::typeToString(Type);
51444ed5c5SDimitry Andric }
52444ed5c5SDimitry Andric OS << '\n';
53444ed5c5SDimitry Andric }
54444ed5c5SDimitry Andric
emitLocal(ArrayRef<wasm::ValType> Types)55*b5893f02SDimitry Andric void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {
56d88c1a5aSDimitry Andric if (!Types.empty()) {
57444ed5c5SDimitry Andric OS << "\t.local \t";
58*b5893f02SDimitry Andric printTypes(OS, Types);
59444ed5c5SDimitry Andric }
60d88c1a5aSDimitry Andric }
61444ed5c5SDimitry Andric
emitEndFunc()62444ed5c5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
63444ed5c5SDimitry Andric
emitSignature(const wasm::WasmSignature * Sig)64*b5893f02SDimitry Andric void WebAssemblyTargetAsmStreamer::emitSignature(
65*b5893f02SDimitry Andric const wasm::WasmSignature *Sig) {
66*b5893f02SDimitry Andric OS << "(";
67*b5893f02SDimitry Andric emitParamList(Sig);
68*b5893f02SDimitry Andric OS << ") -> (";
69*b5893f02SDimitry Andric emitReturnList(Sig);
70*b5893f02SDimitry Andric OS << ")";
713ca95b02SDimitry Andric }
723ca95b02SDimitry Andric
emitParamList(const wasm::WasmSignature * Sig)73*b5893f02SDimitry Andric void WebAssemblyTargetAsmStreamer::emitParamList(
74*b5893f02SDimitry Andric const wasm::WasmSignature *Sig) {
75*b5893f02SDimitry Andric auto &Params = Sig->Params;
76*b5893f02SDimitry Andric for (auto &Ty : Params) {
77*b5893f02SDimitry Andric if (&Ty != &Params[0])
78*b5893f02SDimitry Andric OS << ", ";
79*b5893f02SDimitry Andric OS << WebAssembly::typeToString(Ty);
80*b5893f02SDimitry Andric }
81d88c1a5aSDimitry Andric }
82444ed5c5SDimitry Andric
emitReturnList(const wasm::WasmSignature * Sig)83*b5893f02SDimitry Andric void WebAssemblyTargetAsmStreamer::emitReturnList(
84*b5893f02SDimitry Andric const wasm::WasmSignature *Sig) {
85*b5893f02SDimitry Andric auto &Returns = Sig->Returns;
86*b5893f02SDimitry Andric for (auto &Ty : Returns) {
87*b5893f02SDimitry Andric if (&Ty != &Returns[0])
88*b5893f02SDimitry Andric OS << ", ";
89*b5893f02SDimitry Andric OS << WebAssembly::typeToString(Ty);
90*b5893f02SDimitry Andric }
91*b5893f02SDimitry Andric }
92*b5893f02SDimitry Andric
emitFunctionType(const MCSymbolWasm * Sym)93*b5893f02SDimitry Andric void WebAssemblyTargetAsmStreamer::emitFunctionType(const MCSymbolWasm *Sym) {
94*b5893f02SDimitry Andric assert(Sym->isFunction());
95*b5893f02SDimitry Andric OS << "\t.functype\t" << Sym->getName() << " ";
96*b5893f02SDimitry Andric emitSignature(Sym->getSignature());
97*b5893f02SDimitry Andric OS << "\n";
98*b5893f02SDimitry Andric }
99*b5893f02SDimitry Andric
emitGlobalType(const MCSymbolWasm * Sym)100*b5893f02SDimitry Andric void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) {
101*b5893f02SDimitry Andric assert(Sym->isGlobal());
102*b5893f02SDimitry Andric OS << "\t.globaltype\t" << Sym->getName() << ", "
103*b5893f02SDimitry Andric << WebAssembly::typeToString(
104*b5893f02SDimitry Andric static_cast<wasm::ValType>(Sym->getGlobalType().Type))
105*b5893f02SDimitry Andric << '\n';
106*b5893f02SDimitry Andric }
107*b5893f02SDimitry Andric
emitEventType(const MCSymbolWasm * Sym)108*b5893f02SDimitry Andric void WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) {
109*b5893f02SDimitry Andric assert(Sym->isEvent());
110*b5893f02SDimitry Andric OS << "\t.eventtype\t" << Sym->getName() << " ";
111*b5893f02SDimitry Andric emitParamList(Sym->getSignature());
112*b5893f02SDimitry Andric OS << "\n";
113*b5893f02SDimitry Andric }
114*b5893f02SDimitry Andric
emitImportModule(const MCSymbolWasm * Sym,StringRef ImportModule)115*b5893f02SDimitry Andric void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym,
116*b5893f02SDimitry Andric StringRef ImportModule) {
117*b5893f02SDimitry Andric OS << "\t.import_module\t" << Sym->getName() << ", "
118*b5893f02SDimitry Andric << ImportModule << '\n';
119*b5893f02SDimitry Andric }
120*b5893f02SDimitry Andric
emitImportName(const MCSymbolWasm * Sym,StringRef ImportName)121*b5893f02SDimitry Andric void WebAssemblyTargetAsmStreamer::emitImportName(const MCSymbolWasm *Sym,
122*b5893f02SDimitry Andric StringRef ImportName) {
123*b5893f02SDimitry Andric OS << "\t.import_name\t" << Sym->getName() << ", "
124*b5893f02SDimitry Andric << ImportName << '\n';
1254ba319b5SDimitry Andric }
1264ba319b5SDimitry Andric
emitIndIdx(const MCExpr * Value)127d88c1a5aSDimitry Andric void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) {
128d88c1a5aSDimitry Andric OS << "\t.indidx \t" << *Value << '\n';
129444ed5c5SDimitry Andric }
130444ed5c5SDimitry Andric
emitLocal(ArrayRef<wasm::ValType> Types)131*b5893f02SDimitry Andric void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {
132*b5893f02SDimitry Andric SmallVector<std::pair<wasm::ValType, uint32_t>, 4> Grouped;
133*b5893f02SDimitry Andric for (auto Type : Types) {
1347a7e6055SDimitry Andric if (Grouped.empty() || Grouped.back().first != Type)
1357a7e6055SDimitry Andric Grouped.push_back(std::make_pair(Type, 1));
1367a7e6055SDimitry Andric else
1377a7e6055SDimitry Andric ++Grouped.back().second;
1387a7e6055SDimitry Andric }
1397a7e6055SDimitry Andric
1407a7e6055SDimitry Andric Streamer.EmitULEB128IntValue(Grouped.size());
1417a7e6055SDimitry Andric for (auto Pair : Grouped) {
1427a7e6055SDimitry Andric Streamer.EmitULEB128IntValue(Pair.second);
143*b5893f02SDimitry Andric emitValueType(Pair.first);
1447a7e6055SDimitry Andric }
1457a7e6055SDimitry Andric }
1467a7e6055SDimitry Andric
emitEndFunc()1477a7e6055SDimitry Andric void WebAssemblyTargetWasmStreamer::emitEndFunc() {
1487a7e6055SDimitry Andric llvm_unreachable(".end_func is not needed for direct wasm output");
1497a7e6055SDimitry Andric }
1507a7e6055SDimitry Andric
emitIndIdx(const MCExpr * Value)1517a7e6055SDimitry Andric void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) {
1527a7e6055SDimitry Andric llvm_unreachable(".indidx encoding not yet implemented");
1537a7e6055SDimitry Andric }
154