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/WebAssemblyMCTargetDesc.h" 17fe6060f1SDimitry Andric #include "Utils/WebAssemblyTypeUtilities.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()); 82fe6060f1SDimitry Andric const wasm::WasmTableType &Type = Sym->getTableType(); 83e8d8bef9SDimitry Andric OS << "\t.tabletype\t" << Sym->getName() << ", " 84fe6060f1SDimitry Andric << WebAssembly::typeToString(static_cast<wasm::ValType>(Type.ElemType)); 85fe6060f1SDimitry Andric bool HasMaximum = Type.Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX; 86fe6060f1SDimitry Andric if (Type.Limits.Minimum != 0 || HasMaximum) { 87fe6060f1SDimitry Andric OS << ", " << Type.Limits.Minimum; 88fe6060f1SDimitry Andric if (HasMaximum) 89fe6060f1SDimitry Andric OS << ", " << Type.Limits.Maximum; 90fe6060f1SDimitry Andric } 91e8d8bef9SDimitry Andric OS << '\n'; 92*0b57cec5SDimitry Andric } 93*0b57cec5SDimitry Andric 94fe6060f1SDimitry Andric void WebAssemblyTargetAsmStreamer::emitTagType(const MCSymbolWasm *Sym) { 95fe6060f1SDimitry Andric assert(Sym->isTag()); 96fe6060f1SDimitry Andric OS << "\t.tagtype\t" << Sym->getName() << " "; 978bcb0991SDimitry Andric OS << WebAssembly::typeListToString(Sym->getSignature()->Params); 98*0b57cec5SDimitry Andric OS << "\n"; 99*0b57cec5SDimitry Andric } 100*0b57cec5SDimitry Andric 101*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym, 102*0b57cec5SDimitry Andric StringRef ImportModule) { 103*0b57cec5SDimitry Andric OS << "\t.import_module\t" << Sym->getName() << ", " 104*0b57cec5SDimitry Andric << ImportModule << '\n'; 105*0b57cec5SDimitry Andric } 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitImportName(const MCSymbolWasm *Sym, 108*0b57cec5SDimitry Andric StringRef ImportName) { 109*0b57cec5SDimitry Andric OS << "\t.import_name\t" << Sym->getName() << ", " 110*0b57cec5SDimitry Andric << ImportName << '\n'; 111*0b57cec5SDimitry Andric } 112*0b57cec5SDimitry Andric 113480093f4SDimitry Andric void WebAssemblyTargetAsmStreamer::emitExportName(const MCSymbolWasm *Sym, 114480093f4SDimitry Andric StringRef ExportName) { 115480093f4SDimitry Andric OS << "\t.export_name\t" << Sym->getName() << ", " 116480093f4SDimitry Andric << ExportName << '\n'; 117480093f4SDimitry Andric } 118480093f4SDimitry Andric 119*0b57cec5SDimitry Andric void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) { 120*0b57cec5SDimitry Andric OS << "\t.indidx \t" << *Value << '\n'; 121*0b57cec5SDimitry Andric } 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) { 124*0b57cec5SDimitry Andric SmallVector<std::pair<wasm::ValType, uint32_t>, 4> Grouped; 125*0b57cec5SDimitry Andric for (auto Type : Types) { 126*0b57cec5SDimitry Andric if (Grouped.empty() || Grouped.back().first != Type) 127*0b57cec5SDimitry Andric Grouped.push_back(std::make_pair(Type, 1)); 128*0b57cec5SDimitry Andric else 129*0b57cec5SDimitry Andric ++Grouped.back().second; 130*0b57cec5SDimitry Andric } 131*0b57cec5SDimitry Andric 1325ffd83dbSDimitry Andric Streamer.emitULEB128IntValue(Grouped.size()); 133*0b57cec5SDimitry Andric for (auto Pair : Grouped) { 1345ffd83dbSDimitry Andric Streamer.emitULEB128IntValue(Pair.second); 135*0b57cec5SDimitry Andric emitValueType(Pair.first); 136*0b57cec5SDimitry Andric } 137*0b57cec5SDimitry Andric } 138*0b57cec5SDimitry Andric 139*0b57cec5SDimitry Andric void WebAssemblyTargetWasmStreamer::emitEndFunc() { 140*0b57cec5SDimitry Andric llvm_unreachable(".end_func is not needed for direct wasm output"); 141*0b57cec5SDimitry Andric } 142*0b57cec5SDimitry Andric 143*0b57cec5SDimitry Andric void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) { 144*0b57cec5SDimitry Andric llvm_unreachable(".indidx encoding not yet implemented"); 145*0b57cec5SDimitry Andric } 146