1293838Sdim//==-- WebAssemblyTargetStreamer.cpp - WebAssembly Target Streamer Methods --=//
2293838Sdim//
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
6293838Sdim//
7293838Sdim//===----------------------------------------------------------------------===//
8293838Sdim///
9293838Sdim/// \file
10341825Sdim/// This file defines WebAssembly-specific target streamer classes.
11293838Sdim/// These are for implementing support for target-specific assembly directives.
12293838Sdim///
13293838Sdim//===----------------------------------------------------------------------===//
14293838Sdim
15353358Sdim#include "MCTargetDesc/WebAssemblyTargetStreamer.h"
16353358Sdim#include "MCTargetDesc/WebAssemblyInstPrinter.h"
17353358Sdim#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
18293838Sdim#include "llvm/MC/MCContext.h"
19321369Sdim#include "llvm/MC/MCSectionWasm.h"
20293838Sdim#include "llvm/MC/MCSubtargetInfo.h"
21321369Sdim#include "llvm/MC/MCSymbolWasm.h"
22321369Sdim#include "llvm/Support/Casting.h"
23293838Sdim#include "llvm/Support/ErrorHandling.h"
24293838Sdim#include "llvm/Support/FormattedStream.h"
25293838Sdimusing namespace llvm;
26293838Sdim
27293838SdimWebAssemblyTargetStreamer::WebAssemblyTargetStreamer(MCStreamer &S)
28293838Sdim    : MCTargetStreamer(S) {}
29293838Sdim
30321369Sdimvoid WebAssemblyTargetStreamer::emitValueType(wasm::ValType Type) {
31341825Sdim  Streamer.EmitIntValue(uint8_t(Type), 1);
32321369Sdim}
33321369Sdim
34293838SdimWebAssemblyTargetAsmStreamer::WebAssemblyTargetAsmStreamer(
35293838Sdim    MCStreamer &S, formatted_raw_ostream &OS)
36293838Sdim    : WebAssemblyTargetStreamer(S), OS(OS) {}
37293838Sdim
38321369SdimWebAssemblyTargetWasmStreamer::WebAssemblyTargetWasmStreamer(MCStreamer &S)
39321369Sdim    : WebAssemblyTargetStreamer(S) {}
40321369Sdim
41344779Sdimstatic void printTypes(formatted_raw_ostream &OS,
42344779Sdim                       ArrayRef<wasm::ValType> Types) {
43293838Sdim  bool First = true;
44344779Sdim  for (auto Type : Types) {
45293838Sdim    if (First)
46293838Sdim      First = false;
47293838Sdim    else
48293838Sdim      OS << ", ";
49344779Sdim    OS << WebAssembly::typeToString(Type);
50293838Sdim  }
51293838Sdim  OS << '\n';
52293838Sdim}
53293838Sdim
54344779Sdimvoid WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {
55321369Sdim  if (!Types.empty()) {
56344779Sdim    OS << "\t.local  \t";
57344779Sdim    printTypes(OS, Types);
58321369Sdim  }
59293838Sdim}
60293838Sdim
61344779Sdimvoid WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
62321369Sdim
63344779Sdimvoid WebAssemblyTargetAsmStreamer::emitFunctionType(const MCSymbolWasm *Sym) {
64344779Sdim  assert(Sym->isFunction());
65344779Sdim  OS << "\t.functype\t" << Sym->getName() << " ";
66360784Sdim  OS << WebAssembly::signatureToString(Sym->getSignature());
67344779Sdim  OS << "\n";
68309124Sdim}
69309124Sdim
70344779Sdimvoid WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) {
71344779Sdim  assert(Sym->isGlobal());
72344779Sdim  OS << "\t.globaltype\t" << Sym->getName() << ", "
73344779Sdim     << WebAssembly::typeToString(
74344779Sdim            static_cast<wasm::ValType>(Sym->getGlobalType().Type))
75344779Sdim     << '\n';
76314564Sdim}
77293838Sdim
78344779Sdimvoid WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) {
79344779Sdim  assert(Sym->isEvent());
80344779Sdim  OS << "\t.eventtype\t" << Sym->getName() << " ";
81360784Sdim  OS << WebAssembly::typeListToString(Sym->getSignature()->Params);
82344779Sdim  OS << "\n";
83341825Sdim}
84341825Sdim
85344779Sdimvoid WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym,
86344779Sdim                                                    StringRef ImportModule) {
87344779Sdim  OS << "\t.import_module\t" << Sym->getName() << ", "
88344779Sdim                             << ImportModule << '\n';
89293838Sdim}
90293838Sdim
91344779Sdimvoid WebAssemblyTargetAsmStreamer::emitImportName(const MCSymbolWasm *Sym,
92344779Sdim                                                  StringRef ImportName) {
93344779Sdim  OS << "\t.import_name\t" << Sym->getName() << ", "
94344779Sdim                           << ImportName << '\n';
95321369Sdim}
96321369Sdim
97360784Sdimvoid WebAssemblyTargetAsmStreamer::emitExportName(const MCSymbolWasm *Sym,
98360784Sdim                                                  StringRef ExportName) {
99360784Sdim  OS << "\t.export_name\t" << Sym->getName() << ", "
100360784Sdim                           << ExportName << '\n';
101360784Sdim}
102360784Sdim
103344779Sdimvoid WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) {
104344779Sdim  OS << "\t.indidx  \t" << *Value << '\n';
105321369Sdim}
106321369Sdim
107344779Sdimvoid WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {
108344779Sdim  SmallVector<std::pair<wasm::ValType, uint32_t>, 4> Grouped;
109344779Sdim  for (auto Type : Types) {
110321369Sdim    if (Grouped.empty() || Grouped.back().first != Type)
111321369Sdim      Grouped.push_back(std::make_pair(Type, 1));
112321369Sdim    else
113321369Sdim      ++Grouped.back().second;
114321369Sdim  }
115321369Sdim
116321369Sdim  Streamer.EmitULEB128IntValue(Grouped.size());
117321369Sdim  for (auto Pair : Grouped) {
118321369Sdim    Streamer.EmitULEB128IntValue(Pair.second);
119344779Sdim    emitValueType(Pair.first);
120321369Sdim  }
121321369Sdim}
122321369Sdim
123321369Sdimvoid WebAssemblyTargetWasmStreamer::emitEndFunc() {
124321369Sdim  llvm_unreachable(".end_func is not needed for direct wasm output");
125321369Sdim}
126321369Sdim
127321369Sdimvoid WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) {
128321369Sdim  llvm_unreachable(".indidx encoding not yet implemented");
129321369Sdim}
130