1*0b57cec5SDimitry Andric //==-- WebAssemblyTargetStreamer.cpp - WebAssembly Target Streamer Methods --=// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric /// 9*0b57cec5SDimitry Andric /// \file 10*0b57cec5SDimitry Andric /// This file defines WebAssembly-specific target streamer classes. 11*0b57cec5SDimitry Andric /// These are for implementing support for target-specific assembly directives. 12*0b57cec5SDimitry Andric /// 13*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 14*0b57cec5SDimitry Andric 15*0b57cec5SDimitry Andric #include "MCTargetDesc/WebAssemblyTargetStreamer.h" 16*0b57cec5SDimitry Andric #include "MCTargetDesc/WebAssemblyInstPrinter.h" 17*0b57cec5SDimitry Andric #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 18*0b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 19*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionWasm.h" 20*0b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 21*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbolWasm.h" 22*0b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 23*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 24*0b57cec5SDimitry Andric #include "llvm/Support/FormattedStream.h" 25*0b57cec5SDimitry Andric using namespace llvm; 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric WebAssemblyTargetStreamer::WebAssemblyTargetStreamer(MCStreamer &S) 28*0b57cec5SDimitry Andric : MCTargetStreamer(S) {} 29*0b57cec5SDimitry Andric 30*0b57cec5SDimitry Andric void WebAssemblyTargetStreamer::emitValueType(wasm::ValType Type) { 315ffd83dbSDimitry Andric Streamer.emitIntValue(uint8_t(Type), 1); 32*0b57cec5SDimitry Andric } 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric WebAssemblyTargetAsmStreamer::WebAssemblyTargetAsmStreamer( 35*0b57cec5SDimitry Andric MCStreamer &S, formatted_raw_ostream &OS) 36*0b57cec5SDimitry Andric : WebAssemblyTargetStreamer(S), OS(OS) {} 37*0b57cec5SDimitry Andric 38*0b57cec5SDimitry Andric WebAssemblyTargetWasmStreamer::WebAssemblyTargetWasmStreamer(MCStreamer &S) 39*0b57cec5SDimitry Andric : WebAssemblyTargetStreamer(S) {} 40*0b57cec5SDimitry Andric 41*0b57cec5SDimitry Andric static void printTypes(formatted_raw_ostream &OS, 42*0b57cec5SDimitry Andric ArrayRef<wasm::ValType> Types) { 43*0b57cec5SDimitry Andric bool First = true; 44*0b57cec5SDimitry Andric for (auto Type : Types) { 45*0b57cec5SDimitry Andric if (First) 46*0b57cec5SDimitry Andric First = false; 47*0b57cec5SDimitry Andric else 48*0b57cec5SDimitry Andric OS << ", "; 49*0b57cec5SDimitry Andric OS << WebAssembly::typeToString(Type); 50*0b57cec5SDimitry Andric } 51*0b57cec5SDimitry Andric OS << '\n'; 52*0b57cec5SDimitry Andric } 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) { 55*0b57cec5SDimitry Andric if (!Types.empty()) { 56*0b57cec5SDimitry Andric OS << "\t.local \t"; 57*0b57cec5SDimitry Andric printTypes(OS, Types); 58*0b57cec5SDimitry Andric } 59*0b57cec5SDimitry Andric } 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; } 62*0b57cec5SDimitry Andric 63*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitFunctionType(const MCSymbolWasm *Sym) { 64*0b57cec5SDimitry Andric assert(Sym->isFunction()); 65*0b57cec5SDimitry Andric OS << "\t.functype\t" << Sym->getName() << " "; 668bcb0991SDimitry Andric OS << WebAssembly::signatureToString(Sym->getSignature()); 67*0b57cec5SDimitry Andric OS << "\n"; 68*0b57cec5SDimitry Andric } 69*0b57cec5SDimitry Andric 70*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) { 71*0b57cec5SDimitry Andric assert(Sym->isGlobal()); 72*0b57cec5SDimitry Andric OS << "\t.globaltype\t" << Sym->getName() << ", " 73*0b57cec5SDimitry Andric << WebAssembly::typeToString( 74*0b57cec5SDimitry Andric static_cast<wasm::ValType>(Sym->getGlobalType().Type)) 75*0b57cec5SDimitry Andric << '\n'; 76*0b57cec5SDimitry Andric } 77*0b57cec5SDimitry Andric 78*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) { 79*0b57cec5SDimitry Andric assert(Sym->isEvent()); 80*0b57cec5SDimitry Andric OS << "\t.eventtype\t" << Sym->getName() << " "; 818bcb0991SDimitry Andric OS << WebAssembly::typeListToString(Sym->getSignature()->Params); 82*0b57cec5SDimitry Andric OS << "\n"; 83*0b57cec5SDimitry Andric } 84*0b57cec5SDimitry Andric 85*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym, 86*0b57cec5SDimitry Andric StringRef ImportModule) { 87*0b57cec5SDimitry Andric OS << "\t.import_module\t" << Sym->getName() << ", " 88*0b57cec5SDimitry Andric << ImportModule << '\n'; 89*0b57cec5SDimitry Andric } 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitImportName(const MCSymbolWasm *Sym, 92*0b57cec5SDimitry Andric StringRef ImportName) { 93*0b57cec5SDimitry Andric OS << "\t.import_name\t" << Sym->getName() << ", " 94*0b57cec5SDimitry Andric << ImportName << '\n'; 95*0b57cec5SDimitry Andric } 96*0b57cec5SDimitry Andric 97480093f4SDimitry Andric void WebAssemblyTargetAsmStreamer::emitExportName(const MCSymbolWasm *Sym, 98480093f4SDimitry Andric StringRef ExportName) { 99480093f4SDimitry Andric OS << "\t.export_name\t" << Sym->getName() << ", " 100480093f4SDimitry Andric << ExportName << '\n'; 101480093f4SDimitry Andric } 102480093f4SDimitry Andric 103*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) { 104*0b57cec5SDimitry Andric OS << "\t.indidx \t" << *Value << '\n'; 105*0b57cec5SDimitry Andric } 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) { 108*0b57cec5SDimitry Andric SmallVector<std::pair<wasm::ValType, uint32_t>, 4> Grouped; 109*0b57cec5SDimitry Andric for (auto Type : Types) { 110*0b57cec5SDimitry Andric if (Grouped.empty() || Grouped.back().first != Type) 111*0b57cec5SDimitry Andric Grouped.push_back(std::make_pair(Type, 1)); 112*0b57cec5SDimitry Andric else 113*0b57cec5SDimitry Andric ++Grouped.back().second; 114*0b57cec5SDimitry Andric } 115*0b57cec5SDimitry Andric 1165ffd83dbSDimitry Andric Streamer.emitULEB128IntValue(Grouped.size()); 117*0b57cec5SDimitry Andric for (auto Pair : Grouped) { 1185ffd83dbSDimitry Andric Streamer.emitULEB128IntValue(Pair.second); 119*0b57cec5SDimitry Andric emitValueType(Pair.first); 120*0b57cec5SDimitry Andric } 121*0b57cec5SDimitry Andric } 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric void WebAssemblyTargetWasmStreamer::emitEndFunc() { 124*0b57cec5SDimitry Andric llvm_unreachable(".end_func is not needed for direct wasm output"); 125*0b57cec5SDimitry Andric } 126*0b57cec5SDimitry Andric 127*0b57cec5SDimitry Andric void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) { 128*0b57cec5SDimitry Andric llvm_unreachable(".indidx encoding not yet implemented"); 129*0b57cec5SDimitry Andric } 130