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( 74e8d8bef9SDimitry Andric static_cast<wasm::ValType>(Sym->getGlobalType().Type)); 75e8d8bef9SDimitry Andric if (!Sym->getGlobalType().Mutable) 76e8d8bef9SDimitry Andric OS << ", immutable"; 77e8d8bef9SDimitry Andric OS << '\n'; 78e8d8bef9SDimitry Andric } 79e8d8bef9SDimitry Andric 80e8d8bef9SDimitry Andric void WebAssemblyTargetAsmStreamer::emitTableType(const MCSymbolWasm *Sym) { 81e8d8bef9SDimitry Andric assert(Sym->isTable()); 82e8d8bef9SDimitry Andric OS << "\t.tabletype\t" << Sym->getName() << ", " 83e8d8bef9SDimitry Andric << WebAssembly::typeToString(Sym->getTableType()); 84e8d8bef9SDimitry Andric OS << '\n'; 85*0b57cec5SDimitry Andric } 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) { 88*0b57cec5SDimitry Andric assert(Sym->isEvent()); 89*0b57cec5SDimitry Andric OS << "\t.eventtype\t" << Sym->getName() << " "; 908bcb0991SDimitry Andric OS << WebAssembly::typeListToString(Sym->getSignature()->Params); 91*0b57cec5SDimitry Andric OS << "\n"; 92*0b57cec5SDimitry Andric } 93*0b57cec5SDimitry Andric 94*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym, 95*0b57cec5SDimitry Andric StringRef ImportModule) { 96*0b57cec5SDimitry Andric OS << "\t.import_module\t" << Sym->getName() << ", " 97*0b57cec5SDimitry Andric << ImportModule << '\n'; 98*0b57cec5SDimitry Andric } 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitImportName(const MCSymbolWasm *Sym, 101*0b57cec5SDimitry Andric StringRef ImportName) { 102*0b57cec5SDimitry Andric OS << "\t.import_name\t" << Sym->getName() << ", " 103*0b57cec5SDimitry Andric << ImportName << '\n'; 104*0b57cec5SDimitry Andric } 105*0b57cec5SDimitry Andric 106480093f4SDimitry Andric void WebAssemblyTargetAsmStreamer::emitExportName(const MCSymbolWasm *Sym, 107480093f4SDimitry Andric StringRef ExportName) { 108480093f4SDimitry Andric OS << "\t.export_name\t" << Sym->getName() << ", " 109480093f4SDimitry Andric << ExportName << '\n'; 110480093f4SDimitry Andric } 111480093f4SDimitry Andric 112*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) { 113*0b57cec5SDimitry Andric OS << "\t.indidx \t" << *Value << '\n'; 114*0b57cec5SDimitry Andric } 115*0b57cec5SDimitry Andric 116*0b57cec5SDimitry Andric void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) { 117*0b57cec5SDimitry Andric SmallVector<std::pair<wasm::ValType, uint32_t>, 4> Grouped; 118*0b57cec5SDimitry Andric for (auto Type : Types) { 119*0b57cec5SDimitry Andric if (Grouped.empty() || Grouped.back().first != Type) 120*0b57cec5SDimitry Andric Grouped.push_back(std::make_pair(Type, 1)); 121*0b57cec5SDimitry Andric else 122*0b57cec5SDimitry Andric ++Grouped.back().second; 123*0b57cec5SDimitry Andric } 124*0b57cec5SDimitry Andric 1255ffd83dbSDimitry Andric Streamer.emitULEB128IntValue(Grouped.size()); 126*0b57cec5SDimitry Andric for (auto Pair : Grouped) { 1275ffd83dbSDimitry Andric Streamer.emitULEB128IntValue(Pair.second); 128*0b57cec5SDimitry Andric emitValueType(Pair.first); 129*0b57cec5SDimitry Andric } 130*0b57cec5SDimitry Andric } 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andric void WebAssemblyTargetWasmStreamer::emitEndFunc() { 133*0b57cec5SDimitry Andric llvm_unreachable(".end_func is not needed for direct wasm output"); 134*0b57cec5SDimitry Andric } 135*0b57cec5SDimitry Andric 136*0b57cec5SDimitry Andric void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) { 137*0b57cec5SDimitry Andric llvm_unreachable(".indidx encoding not yet implemented"); 138*0b57cec5SDimitry Andric } 139