140 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// 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"23using namespace llvm;24 25WebAssemblyTargetStreamer::WebAssemblyTargetStreamer(MCStreamer &S)26 : MCTargetStreamer(S) {}27 28void WebAssemblyTargetStreamer::emitValueType(wasm::ValType Type) {29 Streamer.emitIntValue(uint8_t(Type), 1);30}31 32WebAssemblyTargetAsmStreamer::WebAssemblyTargetAsmStreamer(33 MCStreamer &S, formatted_raw_ostream &OS)34 : WebAssemblyTargetStreamer(S), OS(OS) {}35 36WebAssemblyTargetWasmStreamer::WebAssemblyTargetWasmStreamer(MCStreamer &S)37 : WebAssemblyTargetStreamer(S) {}38 39static 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 else46 OS << ", ";47 OS << WebAssembly::typeToString(Type);48 }49 OS << '\n';50}51 52void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {53 if (!Types.empty()) {54 OS << "\t.local \t";55 printTypes(OS, Types);56 }57}58 59void 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 66void 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 76void 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 90void 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 97void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym,98 StringRef ImportModule) {99 OS << "\t.import_module\t" << Sym->getName() << ", "100 << ImportModule << '\n';101}102 103void WebAssemblyTargetAsmStreamer::emitImportName(const MCSymbolWasm *Sym,104 StringRef ImportName) {105 OS << "\t.import_name\t" << Sym->getName() << ", "106 << ImportName << '\n';107}108 109void WebAssemblyTargetAsmStreamer::emitExportName(const MCSymbolWasm *Sym,110 StringRef ExportName) {111 OS << "\t.export_name\t" << Sym->getName() << ", "112 << ExportName << '\n';113}114 115void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) {116 OS << "\t.indidx\t";117 getContext().getAsmInfo()->printExpr(OS, *Value);118 OS << '\n';119}120 121void 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 else127 ++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 137void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) {138 llvm_unreachable(".indidx encoding not yet implemented");139}140