1 //==-- WebAssemblyTargetStreamer.cpp - WebAssembly Target Streamer Methods --=// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file defines WebAssembly-specific target streamer classes. 11 /// These are for implementing support for target-specific assembly directives. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "MCTargetDesc/WebAssemblyTargetStreamer.h" 16 #include "MCTargetDesc/WebAssemblyMCAsmInfo.h" 17 #include "MCTargetDesc/WebAssemblyMCTypeUtilities.h" 18 #include "llvm/MC/MCContext.h" 19 #include "llvm/MC/MCSectionWasm.h" 20 #include "llvm/MC/MCSymbolWasm.h" 21 #include "llvm/Support/ErrorHandling.h" 22 #include "llvm/Support/FormattedStream.h" 23 using namespace llvm; 24 25 WebAssemblyTargetStreamer::WebAssemblyTargetStreamer(MCStreamer &S) 26 : MCTargetStreamer(S) {} 27 28 void WebAssemblyTargetStreamer::emitValueType(wasm::ValType Type) { 29 Streamer.emitIntValue(uint8_t(Type), 1); 30 } 31 32 WebAssemblyTargetAsmStreamer::WebAssemblyTargetAsmStreamer( 33 MCStreamer &S, formatted_raw_ostream &OS) 34 : WebAssemblyTargetStreamer(S), OS(OS) {} 35 36 WebAssemblyTargetWasmStreamer::WebAssemblyTargetWasmStreamer(MCStreamer &S) 37 : WebAssemblyTargetStreamer(S) {} 38 39 static void printTypes(formatted_raw_ostream &OS, 40 ArrayRef<wasm::ValType> Types) { 41 bool First = true; 42 for (auto Type : Types) { 43 if (First) 44 First = false; 45 else 46 OS << ", "; 47 OS << WebAssembly::typeToString(Type); 48 } 49 OS << '\n'; 50 } 51 52 void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) { 53 if (!Types.empty()) { 54 OS << "\t.local \t"; 55 printTypes(OS, Types); 56 } 57 } 58 59 void WebAssemblyTargetAsmStreamer::emitFunctionType(const MCSymbolWasm *Sym) { 60 assert(Sym->isFunction()); 61 OS << "\t.functype\t" << Sym->getName() << " "; 62 OS << WebAssembly::signatureToString(Sym->getSignature()); 63 OS << "\n"; 64 } 65 66 void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) { 67 assert(Sym->isGlobal()); 68 OS << "\t.globaltype\t" << Sym->getName() << ", " 69 << WebAssembly::typeToString( 70 static_cast<wasm::ValType>(Sym->getGlobalType().Type)); 71 if (!Sym->getGlobalType().Mutable) 72 OS << ", immutable"; 73 OS << '\n'; 74 } 75 76 void WebAssemblyTargetAsmStreamer::emitTableType(const MCSymbolWasm *Sym) { 77 assert(Sym->isTable()); 78 const wasm::WasmTableType &Type = Sym->getTableType(); 79 OS << "\t.tabletype\t" << Sym->getName() << ", " 80 << WebAssembly::typeToString(static_cast<wasm::ValType>(Type.ElemType)); 81 bool HasMaximum = Type.Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX; 82 if (Type.Limits.Minimum != 0 || HasMaximum) { 83 OS << ", " << Type.Limits.Minimum; 84 if (HasMaximum) 85 OS << ", " << Type.Limits.Maximum; 86 } 87 OS << '\n'; 88 } 89 90 void WebAssemblyTargetAsmStreamer::emitTagType(const MCSymbolWasm *Sym) { 91 assert(Sym->isTag()); 92 OS << "\t.tagtype\t" << Sym->getName() << " "; 93 OS << WebAssembly::typeListToString(Sym->getSignature()->Params); 94 OS << "\n"; 95 } 96 97 void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym, 98 StringRef ImportModule) { 99 OS << "\t.import_module\t" << Sym->getName() << ", " 100 << ImportModule << '\n'; 101 } 102 103 void WebAssemblyTargetAsmStreamer::emitImportName(const MCSymbolWasm *Sym, 104 StringRef ImportName) { 105 OS << "\t.import_name\t" << Sym->getName() << ", " 106 << ImportName << '\n'; 107 } 108 109 void WebAssemblyTargetAsmStreamer::emitExportName(const MCSymbolWasm *Sym, 110 StringRef ExportName) { 111 OS << "\t.export_name\t" << Sym->getName() << ", " 112 << ExportName << '\n'; 113 } 114 115 void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) { 116 OS << "\t.indidx\t"; 117 getContext().getAsmInfo()->printExpr(OS, *Value); 118 OS << '\n'; 119 } 120 121 void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) { 122 SmallVector<std::pair<wasm::ValType, uint32_t>, 4> Grouped; 123 for (auto Type : Types) { 124 if (Grouped.empty() || Grouped.back().first != Type) 125 Grouped.push_back(std::make_pair(Type, 1)); 126 else 127 ++Grouped.back().second; 128 } 129 130 Streamer.emitULEB128IntValue(Grouped.size()); 131 for (auto Pair : Grouped) { 132 Streamer.emitULEB128IntValue(Pair.second); 133 emitValueType(Pair.first); 134 } 135 } 136 137 void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) { 138 llvm_unreachable(".indidx encoding not yet implemented"); 139 } 140