13469ee12SDan Gohman //==-- WebAssemblyTargetStreamer.cpp - WebAssembly Target Streamer Methods --=//
23469ee12SDan Gohman //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63469ee12SDan Gohman //
73469ee12SDan Gohman //===----------------------------------------------------------------------===//
83469ee12SDan Gohman ///
93469ee12SDan Gohman /// \file
105f8f34e4SAdrian Prantl /// This file defines WebAssembly-specific target streamer classes.
113469ee12SDan Gohman /// These are for implementing support for target-specific assembly directives.
123469ee12SDan Gohman ///
133469ee12SDan Gohman //===----------------------------------------------------------------------===//
143469ee12SDan Gohman 
15a263aa25SDavid L. Jones #include "MCTargetDesc/WebAssemblyTargetStreamer.h"
16a263aa25SDavid L. Jones #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
170b2bc69bSHeejin Ahn #include "Utils/WebAssemblyTypeUtilities.h"
183469ee12SDan Gohman #include "llvm/MC/MCContext.h"
1918eafb6cSDan Gohman #include "llvm/MC/MCSectionWasm.h"
203469ee12SDan Gohman #include "llvm/MC/MCSubtargetInfo.h"
2118eafb6cSDan Gohman #include "llvm/MC/MCSymbolWasm.h"
22d934cb88SDan Gohman #include "llvm/Support/Casting.h"
233469ee12SDan Gohman #include "llvm/Support/ErrorHandling.h"
243469ee12SDan Gohman #include "llvm/Support/FormattedStream.h"
253469ee12SDan Gohman using namespace llvm;
263469ee12SDan Gohman 
WebAssemblyTargetStreamer(MCStreamer & S)273469ee12SDan Gohman WebAssemblyTargetStreamer::WebAssemblyTargetStreamer(MCStreamer &S)
283469ee12SDan Gohman     : MCTargetStreamer(S) {}
293469ee12SDan Gohman 
emitValueType(wasm::ValType Type)30b879539aSDerek Schuff void WebAssemblyTargetStreamer::emitValueType(wasm::ValType Type) {
3177497103SFangrui Song   Streamer.emitIntValue(uint8_t(Type), 1);
32b879539aSDerek Schuff }
33b879539aSDerek Schuff 
WebAssemblyTargetAsmStreamer(MCStreamer & S,formatted_raw_ostream & OS)343469ee12SDan Gohman WebAssemblyTargetAsmStreamer::WebAssemblyTargetAsmStreamer(
353469ee12SDan Gohman     MCStreamer &S, formatted_raw_ostream &OS)
363469ee12SDan Gohman     : WebAssemblyTargetStreamer(S), OS(OS) {}
373469ee12SDan Gohman 
WebAssemblyTargetWasmStreamer(MCStreamer & S)3818eafb6cSDan Gohman WebAssemblyTargetWasmStreamer::WebAssemblyTargetWasmStreamer(MCStreamer &S)
3918eafb6cSDan Gohman     : WebAssemblyTargetStreamer(S) {}
4018eafb6cSDan Gohman 
printTypes(formatted_raw_ostream & OS,ArrayRef<wasm::ValType> Types)4121d45a2cSHeejin Ahn static void printTypes(formatted_raw_ostream &OS,
4221d45a2cSHeejin Ahn                        ArrayRef<wasm::ValType> Types) {
433469ee12SDan Gohman   bool First = true;
4449482f82SWouter van Oortmerssen   for (auto Type : Types) {
453469ee12SDan Gohman     if (First)
463469ee12SDan Gohman       First = false;
473469ee12SDan Gohman     else
483469ee12SDan Gohman       OS << ", ";
4998432956SWouter van Oortmerssen     OS << WebAssembly::typeToString(Type);
503469ee12SDan Gohman   }
513469ee12SDan Gohman   OS << '\n';
523469ee12SDan Gohman }
533469ee12SDan Gohman 
emitLocal(ArrayRef<wasm::ValType> Types)5449482f82SWouter van Oortmerssen void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {
553acb187dSDan Gohman   if (!Types.empty()) {
563469ee12SDan Gohman     OS << "\t.local  \t";
5721d45a2cSHeejin Ahn     printTypes(OS, Types);
583469ee12SDan Gohman   }
593acb187dSDan Gohman }
603469ee12SDan Gohman 
emitFunctionType(const MCSymbolWasm * Sym)6121d45a2cSHeejin Ahn void WebAssemblyTargetAsmStreamer::emitFunctionType(const MCSymbolWasm *Sym) {
6221d45a2cSHeejin Ahn   assert(Sym->isFunction());
63be5e5874SHeejin Ahn   OS << "\t.functype\t" << Sym->getName() << " ";
6487af0b19SWouter van Oortmerssen   OS << WebAssembly::signatureToString(Sym->getSignature());
65be5e5874SHeejin Ahn   OS << "\n";
665859a9edSDerek Schuff }
675859a9edSDerek Schuff 
emitGlobalType(const MCSymbolWasm * Sym)6821d45a2cSHeejin Ahn void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) {
69da419bdbSHeejin Ahn   assert(Sym->isGlobal());
7098432956SWouter van Oortmerssen   OS << "\t.globaltype\t" << Sym->getName() << ", "
7198432956SWouter van Oortmerssen      << WebAssembly::typeToString(
72fa2a8accSSam Clegg             static_cast<wasm::ValType>(Sym->getGlobalType().Type));
73fa2a8accSSam Clegg   if (!Sym->getGlobalType().Mutable)
74fa2a8accSSam Clegg     OS << ", immutable";
75fa2a8accSSam Clegg   OS << '\n';
767747d703SDerek Schuff }
777747d703SDerek Schuff 
emitTableType(const MCSymbolWasm * Sym)78388fb67bSPaulo Matos void WebAssemblyTargetAsmStreamer::emitTableType(const MCSymbolWasm *Sym) {
79388fb67bSPaulo Matos   assert(Sym->isTable());
80c9801db2SAndy Wingo   const wasm::WasmTableType &Type = Sym->getTableType();
81388fb67bSPaulo Matos   OS << "\t.tabletype\t" << Sym->getName() << ", "
82c9801db2SAndy Wingo      << WebAssembly::typeToString(static_cast<wasm::ValType>(Type.ElemType));
83c9801db2SAndy Wingo   bool HasMaximum = Type.Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX;
84c9801db2SAndy Wingo   if (Type.Limits.Minimum != 0 || HasMaximum) {
85c9801db2SAndy Wingo     OS << ", " << Type.Limits.Minimum;
86c9801db2SAndy Wingo     if (HasMaximum)
87c9801db2SAndy Wingo       OS << ", " << Type.Limits.Maximum;
88c9801db2SAndy Wingo   }
89388fb67bSPaulo Matos   OS << '\n';
90388fb67bSPaulo Matos }
91388fb67bSPaulo Matos 
emitTagType(const MCSymbolWasm * Sym)92*1d891d44SHeejin Ahn void WebAssemblyTargetAsmStreamer::emitTagType(const MCSymbolWasm *Sym) {
93*1d891d44SHeejin Ahn   assert(Sym->isTag());
94*1d891d44SHeejin Ahn   OS << "\t.tagtype\t" << Sym->getName() << " ";
9587af0b19SWouter van Oortmerssen   OS << WebAssembly::typeListToString(Sym->getSignature()->Params);
96be5e5874SHeejin Ahn   OS << "\n";
97da419bdbSHeejin Ahn }
98da419bdbSHeejin Ahn 
emitImportModule(const MCSymbolWasm * Sym,StringRef ImportModule)9921d45a2cSHeejin Ahn void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym,
100f726e445SDan Gohman                                                     StringRef ImportModule) {
101f726e445SDan Gohman   OS << "\t.import_module\t" << Sym->getName() << ", "
102f726e445SDan Gohman                              << ImportModule << '\n';
103f726e445SDan Gohman }
104f726e445SDan Gohman 
emitImportName(const MCSymbolWasm * Sym,StringRef ImportName)105f726e445SDan Gohman void WebAssemblyTargetAsmStreamer::emitImportName(const MCSymbolWasm *Sym,
106f726e445SDan Gohman                                                   StringRef ImportName) {
107f726e445SDan Gohman   OS << "\t.import_name\t" << Sym->getName() << ", "
108f726e445SDan Gohman                            << ImportName << '\n';
109db1916a6SDan Gohman }
110db1916a6SDan Gohman 
emitExportName(const MCSymbolWasm * Sym,StringRef ExportName)111881d8778SSam Clegg void WebAssemblyTargetAsmStreamer::emitExportName(const MCSymbolWasm *Sym,
112881d8778SSam Clegg                                                   StringRef ExportName) {
113881d8778SSam Clegg   OS << "\t.export_name\t" << Sym->getName() << ", "
114881d8778SSam Clegg                            << ExportName << '\n';
115881d8778SSam Clegg }
116881d8778SSam Clegg 
emitIndIdx(const MCExpr * Value)117c64d7655SDerek Schuff void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) {
118c64d7655SDerek Schuff   OS << "\t.indidx  \t" << *Value << '\n';
119c64d7655SDerek Schuff }
120c64d7655SDerek Schuff 
emitLocal(ArrayRef<wasm::ValType> Types)12149482f82SWouter van Oortmerssen void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {
12249482f82SWouter van Oortmerssen   SmallVector<std::pair<wasm::ValType, uint32_t>, 4> Grouped;
12349482f82SWouter van Oortmerssen   for (auto Type : Types) {
124d934cb88SDan Gohman     if (Grouped.empty() || Grouped.back().first != Type)
125d934cb88SDan Gohman       Grouped.push_back(std::make_pair(Type, 1));
126d934cb88SDan Gohman     else
127d934cb88SDan Gohman       ++Grouped.back().second;
128d934cb88SDan Gohman   }
129d934cb88SDan Gohman 
1300bc77a0fSFangrui Song   Streamer.emitULEB128IntValue(Grouped.size());
131d934cb88SDan Gohman   for (auto Pair : Grouped) {
1320bc77a0fSFangrui Song     Streamer.emitULEB128IntValue(Pair.second);
13349482f82SWouter van Oortmerssen     emitValueType(Pair.first);
134d934cb88SDan Gohman   }
13518eafb6cSDan Gohman }
13618eafb6cSDan Gohman 
emitIndIdx(const MCExpr * Value)13718eafb6cSDan Gohman void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) {
13818eafb6cSDan Gohman   llvm_unreachable(".indidx encoding not yet implemented");
13918eafb6cSDan Gohman }
140