//===-- WebAssemblyAsmPrinter.cpp - WebAssembly LLVM assembly writer ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains a printer that converts from our internal
/// representation of machine-dependent LLVM code to the WebAssembly assembly
/// language.
///
//===----------------------------------------------------------------------===//

#include "WebAssemblyAsmPrinter.h"
#include "MCTargetDesc/WebAssemblyMCAsmInfo.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "MCTargetDesc/WebAssemblyTargetStreamer.h"
#include "TargetInfo/WebAssemblyTargetInfo.h"
#include "Utils/WebAssemblyTypeUtilities.h"
#include "WebAssembly.h"
#include "WebAssemblyMCInstLower.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblyRegisterInfo.h"
#include "WebAssemblyRuntimeLibcallSignatures.h"
#include "WebAssemblyTargetMachine.h"
#include "WebAssemblyUtilities.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionWasm.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolWasm.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "asm-printer"

extern cl::opt<bool> WasmKeepRegisters;

//===----------------------------------------------------------------------===//
// Helpers.
//===----------------------------------------------------------------------===//

MVT WebAssemblyAsmPrinter::getRegType(unsigned RegNo) const {
  const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
  const TargetRegisterClass *TRC = MRI->getRegClass(RegNo);
  for (MVT T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64, MVT::v16i8, MVT::v8i16,
                MVT::v4i32, MVT::v2i64, MVT::v4f32, MVT::v2f64, MVT::v8f16})
    if (TRI->isTypeLegalForClass(*TRC, T))
      return T;
  LLVM_DEBUG(errs() << "Unknown type for register number: " << RegNo);
  llvm_unreachable("Unknown register type");
  return MVT::Other;
}

std::string WebAssemblyAsmPrinter::regToString(const MachineOperand &MO) {
  Register RegNo = MO.getReg();
  assert(RegNo.isVirtual() &&
         "Unlowered physical register encountered during assembly printing");
  assert(!MFI->isVRegStackified(RegNo));
  unsigned WAReg = MFI->getWAReg(RegNo);
  assert(WAReg != WebAssembly::UnusedReg);
  return '$' + utostr(WAReg);
}

WebAssemblyTargetStreamer *WebAssemblyAsmPrinter::getTargetStreamer() {
  MCTargetStreamer *TS = OutStreamer->getTargetStreamer();
  return static_cast<WebAssemblyTargetStreamer *>(TS);
}

// Emscripten exception handling helpers
//
// This converts invoke names generated by LowerEmscriptenEHSjLj to real names
// that are expected by JavaScript glue code. The invoke names generated by
// Emscripten JS glue code are based on their argument and return types; for
// example, for a function that takes an i32 and returns nothing, it is
// 'invoke_vi'. But the format of invoke generated by LowerEmscriptenEHSjLj pass
// contains a mangled string generated from their IR types, for example,
// "__invoke_void_%struct.mystruct*_int", because final wasm types are not
// available in the IR pass. So we convert those names to the form that
// Emscripten JS code expects.
//
// Refer to LowerEmscriptenEHSjLj pass for more details.

// Returns true if the given function name is an invoke name generated by
// LowerEmscriptenEHSjLj pass.
static bool isEmscriptenInvokeName(StringRef Name) {
  if (Name.front() == '"' && Name.back() == '"')
    Name = Name.substr(1, Name.size() - 2);
  return Name.starts_with("__invoke_");
}

// Returns a character that represents the given wasm value type in invoke
// signatures.
static char getInvokeSig(wasm::ValType VT) {
  switch (VT) {
  case wasm::ValType::I32:
    return 'i';
  case wasm::ValType::I64:
    return 'j';
  case wasm::ValType::F32:
    return 'f';
  case wasm::ValType::F64:
    return 'd';
  case wasm::ValType::V128:
    return 'V';
  case wasm::ValType::FUNCREF:
    return 'F';
  case wasm::ValType::EXTERNREF:
    return 'X';
  case wasm::ValType::EXNREF:
    return 'E';
  default:
    llvm_unreachable("Unhandled wasm::ValType enum");
  }
}

// Given the wasm signature, generate the invoke name in the format JS glue code
// expects.
static std::string getEmscriptenInvokeSymbolName(wasm::WasmSignature *Sig) {
  assert(Sig->Returns.size() <= 1);
  std::string Ret = "invoke_";
  if (!Sig->Returns.empty())
    for (auto VT : Sig->Returns)
      Ret += getInvokeSig(VT);
  else
    Ret += 'v';
  // Invokes' first argument is a pointer to the original function, so skip it
  for (unsigned I = 1, E = Sig->Params.size(); I < E; I++)
    Ret += getInvokeSig(Sig->Params[I]);
  return Ret;
}

//===----------------------------------------------------------------------===//
// WebAssemblyAsmPrinter Implementation.
//===----------------------------------------------------------------------===//

MCSymbolWasm *WebAssemblyAsmPrinter::getMCSymbolForFunction(
    const Function *F, wasm::WasmSignature *Sig, bool &InvokeDetected) {
  MCSymbolWasm *WasmSym = nullptr;

  const bool EnableEmEH =
      WebAssembly::WasmEnableEmEH || WebAssembly::WasmEnableEmSjLj;
  if (EnableEmEH && isEmscriptenInvokeName(F->getName())) {
    assert(Sig);
    InvokeDetected = true;
    if (Sig->Returns.size() > 1) {
      std::string Msg =
          "Emscripten EH/SjLj does not support multivalue returns: " +
          std::string(F->getName()) + ": " +
          WebAssembly::signatureToString(Sig);
      report_fatal_error(Twine(Msg));
    }
    WasmSym = static_cast<MCSymbolWasm *>(
        GetExternalSymbolSymbol(getEmscriptenInvokeSymbolName(Sig)));
  } else {
    WasmSym = static_cast<MCSymbolWasm *>(getSymbol(F));
  }
  return WasmSym;
}

void WebAssemblyAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
  if (!WebAssembly::isWasmVarAddressSpace(GV->getAddressSpace())) {
    AsmPrinter::emitGlobalVariable(GV);
    return;
  }

  assert(!GV->isThreadLocal());
  auto *Sym = static_cast<MCSymbolWasm *>(getSymbol(GV));
  if (!Sym->getType()) {
    SmallVector<MVT, 1> VTs;
    Type *GlobalVT = GV->getValueType();
    if (Subtarget) {
      // Subtarget is only set when a function is defined, because
      // each function can declare a different subtarget. For example,
      // on ARM a compilation unit might have a function on ARM and
      // another on Thumb. Therefore only if Subtarget is non-null we
      // can actually calculate the legal VTs.
      const WebAssemblyTargetLowering &TLI = *Subtarget->getTargetLowering();
      computeLegalValueVTs(TLI, GV->getParent()->getContext(),
                           GV->getDataLayout(), GlobalVT, VTs);
    }
    WebAssembly::wasmSymbolSetType(Sym, GlobalVT, VTs);
  }

  emitVisibility(Sym, GV->getVisibility(), !GV->isDeclaration());
  emitSymbolType(Sym);
  if (GV->hasInitializer()) {
    assert(getSymbolPreferLocal(*GV) == Sym);
    emitLinkage(GV, Sym);
    OutStreamer->emitLabel(Sym);
    // TODO: Actually emit the initializer value.  Otherwise the global has the
    // default value for its type (0, ref.null, etc).
    OutStreamer->addBlankLine();
  }
}

MCSymbol *WebAssemblyAsmPrinter::getOrCreateWasmSymbol(StringRef Name) {
  auto *WasmSym = static_cast<MCSymbolWasm *>(GetExternalSymbolSymbol(Name));
  // May be called multiple times, so early out.
  if (WasmSym->getType())
    return WasmSym;

  const WebAssemblySubtarget &Subtarget = getSubtarget();

  // Except for certain known symbols, all symbols used by CodeGen are
  // functions. It's OK to hardcode knowledge of specific symbols here; this
  // method is precisely there for fetching the signatures of known
  // Clang-provided symbols.
  if (Name == "__stack_pointer" || Name == "__tls_base" ||
      Name == "__memory_base" || Name == "__table_base" ||
      Name == "__tls_size" || Name == "__tls_align") {
    bool Mutable =
        Name == "__stack_pointer" || Name == "__tls_base";
    WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
    WasmSym->setGlobalType(wasm::WasmGlobalType{
        uint8_t(Subtarget.hasAddr64() ? wasm::WASM_TYPE_I64
                                      : wasm::WASM_TYPE_I32),
        Mutable});
    return WasmSym;
  }

  if (Name.starts_with("GCC_except_table")) {
    WasmSym->setType(wasm::WASM_SYMBOL_TYPE_DATA);
    return WasmSym;
  }

  SmallVector<wasm::ValType, 4> Returns;
  SmallVector<wasm::ValType, 4> Params;
  if (Name == "__cpp_exception" || Name == "__c_longjmp") {
    WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TAG);
    WasmSym->setExternal(true);

    // Currently both C++ exceptions and C longjmps have a single pointer type
    // param. For C++ exceptions it is a pointer to an exception object, and for
    // C longjmps it is pointer to a struct that contains a setjmp buffer and a
    // longjmp return value. We may consider using multiple value parameters for
    // longjmps later when multivalue support is ready.
    wasm::ValType AddrType =
        Subtarget.hasAddr64() ? wasm::ValType::I64 : wasm::ValType::I32;
    Params.push_back(AddrType);
  } else { // Function symbols
    WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
    WebAssembly::getLibcallSignature(Subtarget, Name, Returns, Params);
  }
  auto Signature = OutContext.createWasmSignature();
  Signature->Returns = std::move(Returns);
  Signature->Params = std::move(Params);
  WasmSym->setSignature(Signature);

  return WasmSym;
}

void WebAssemblyAsmPrinter::emitSymbolType(const MCSymbolWasm *Sym) {
  std::optional<wasm::WasmSymbolType> WasmTy = Sym->getType();
  if (!WasmTy)
    return;

  switch (*WasmTy) {
  case wasm::WASM_SYMBOL_TYPE_GLOBAL:
    getTargetStreamer()->emitGlobalType(Sym);
    break;
  case wasm::WASM_SYMBOL_TYPE_TAG:
    getTargetStreamer()->emitTagType(Sym);
    break;
  case wasm::WASM_SYMBOL_TYPE_TABLE:
    getTargetStreamer()->emitTableType(Sym);
    break;
  default:
    break; // We only handle globals, tags and tables here
  }
}

void WebAssemblyAsmPrinter::emitDecls(const Module &M) {
  if (signaturesEmitted)
    return;
  signaturesEmitted = true;

  // Normally symbols for globals get discovered as the MI gets lowered,
  // but we need to know about them ahead of time. This will however,
  // only find symbols that have been used. Unused symbols from globals will
  // not be found here.
  MachineModuleInfoWasm &MMIW = MMI->getObjFileInfo<MachineModuleInfoWasm>();
  for (StringRef Name : MMIW.MachineSymbolsUsed) {
    auto *WasmSym = static_cast<MCSymbolWasm *>(getOrCreateWasmSymbol(Name));
    if (WasmSym->isFunction()) {
      // TODO(wvo): is there any case where this overlaps with the call to
      // emitFunctionType in the loop below?
      getTargetStreamer()->emitFunctionType(WasmSym);
    }
  }

  for (auto &It : OutContext.getSymbols()) {
    // Emit .globaltype, .tagtype, or .tabletype declarations for extern
    // declarations, i.e. those that have only been declared (but not defined)
    // in the current module
    auto Sym = static_cast<MCSymbolWasm *>(It.getValue().Symbol);
    if (Sym && !Sym->isDefined())
      emitSymbolType(Sym);
  }

  DenseSet<MCSymbol *> InvokeSymbols;
  for (const auto &F : M) {
    if (F.isIntrinsic())
      continue;

    // Emit function type info for all functions. This will emit duplicate
    // information for defined functions (which already have function type
    // info emitted alongside their definition), but this is necessary in
    // order to enable the single-pass WebAssemblyAsmTypeCheck to succeed.
    SmallVector<MVT, 4> Results;
    SmallVector<MVT, 4> Params;
    computeSignatureVTs(F.getFunctionType(), &F, F, TM, Params, Results);
    // At this point these MCSymbols may or may not have been created already
    // and thus also contain a signature, but we need to get the signature
    // anyway here in case it is an invoke that has not yet been created. We
    // will discard it later if it turns out not to be necessary.
    auto Signature = signatureFromMVTs(OutContext, Results, Params);
    bool InvokeDetected = false;
    auto *Sym = getMCSymbolForFunction(&F, Signature, InvokeDetected);

    // Multiple functions can be mapped to the same invoke symbol. For
    // example, two IR functions '__invoke_void_i8*' and '__invoke_void_i32'
    // are both mapped to '__invoke_vi'. We keep them in a set once we emit an
    // Emscripten EH symbol so we don't emit the same symbol twice.
    if (InvokeDetected && !InvokeSymbols.insert(Sym).second)
      continue;

    Sym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
    if (!Sym->getSignature()) {
      Sym->setSignature(Signature);
    }

    getTargetStreamer()->emitFunctionType(Sym);

    if (F.hasFnAttribute("wasm-import-module")) {
      StringRef Name =
          F.getFnAttribute("wasm-import-module").getValueAsString();
      Sym->setImportModule(OutContext.allocateString(Name));
      getTargetStreamer()->emitImportModule(Sym, Name);
    }
    if (F.hasFnAttribute("wasm-import-name")) {
      // If this is a converted Emscripten EH/SjLj symbol, we shouldn't use
      // the original function name but the converted symbol name.
      StringRef Name =
          InvokeDetected
              ? Sym->getName()
              : F.getFnAttribute("wasm-import-name").getValueAsString();
      Sym->setImportName(OutContext.allocateString(Name));
      getTargetStreamer()->emitImportName(Sym, Name);
    }

    if (F.hasFnAttribute("wasm-export-name")) {
      auto *Sym = static_cast<MCSymbolWasm *>(getSymbol(&F));
      StringRef Name = F.getFnAttribute("wasm-export-name").getValueAsString();
      Sym->setExportName(OutContext.allocateString(Name));
      getTargetStreamer()->emitExportName(Sym, Name);
    }
  }
}

void WebAssemblyAsmPrinter::emitEndOfAsmFile(Module &M) {
  // This is required to emit external declarations (like .functypes) when
  // no functions are defined in the compilation unit and therefore,
  // emitDecls() is not called until now.
  emitDecls(M);

  // When a function's address is taken, a TABLE_INDEX relocation is emitted
  // against the function symbol at the use site.  However the relocation
  // doesn't explicitly refer to the table.  In the future we may want to
  // define a new kind of reloc against both the function and the table, so
  // that the linker can see that the function symbol keeps the table alive,
  // but for now manually mark the table as live.
  for (const auto &F : M) {
    if (!F.isIntrinsic() && F.hasAddressTaken()) {
      MCSymbolWasm *FunctionTable =
          WebAssembly::getOrCreateFunctionTableSymbol(OutContext, Subtarget);
      OutStreamer->emitSymbolAttribute(FunctionTable, MCSA_NoDeadStrip);
      break;
    }
  }

  for (const auto &G : M.globals()) {
    if (!G.hasInitializer() && G.hasExternalLinkage() &&
        !WebAssembly::isWasmVarAddressSpace(G.getAddressSpace()) &&
        G.getValueType()->isSized()) {
      uint16_t Size = M.getDataLayout().getTypeAllocSize(G.getValueType());
      OutStreamer->emitELFSize(getSymbol(&G),
                               MCConstantExpr::create(Size, OutContext));
    }
  }

  if (const NamedMDNode *Named = M.getNamedMetadata("wasm.custom_sections")) {
    for (const Metadata *MD : Named->operands()) {
      const auto *Tuple = dyn_cast<MDTuple>(MD);
      if (!Tuple || Tuple->getNumOperands() != 2)
        continue;
      const MDString *Name = dyn_cast<MDString>(Tuple->getOperand(0));
      const MDString *Contents = dyn_cast<MDString>(Tuple->getOperand(1));
      if (!Name || !Contents)
        continue;

      OutStreamer->pushSection();
      std::string SectionName = (".custom_section." + Name->getString()).str();
      MCSectionWasm *MySection =
          OutContext.getWasmSection(SectionName, SectionKind::getMetadata());
      OutStreamer->switchSection(MySection);
      OutStreamer->emitBytes(Contents->getString());
      OutStreamer->popSection();
    }
  }

  EmitProducerInfo(M);
  EmitTargetFeatures(M);
  EmitFunctionAttributes(M);
}

void WebAssemblyAsmPrinter::EmitProducerInfo(Module &M) {
  llvm::SmallVector<std::pair<std::string, std::string>, 4> Languages;
  if (const NamedMDNode *Debug = M.getNamedMetadata("llvm.dbg.cu")) {
    llvm::SmallSet<StringRef, 4> SeenLanguages;
    for (size_t I = 0, E = Debug->getNumOperands(); I < E; ++I) {
      const auto *CU = cast<DICompileUnit>(Debug->getOperand(I));
      StringRef Language =
          dwarf::LanguageString(CU->getSourceLanguage().getUnversionedName());

      Language.consume_front("DW_LANG_");
      if (SeenLanguages.insert(Language).second)
        Languages.emplace_back(Language.str(), "");
    }
  }

  llvm::SmallVector<std::pair<std::string, std::string>, 4> Tools;
  if (const NamedMDNode *Ident = M.getNamedMetadata("llvm.ident")) {
    llvm::SmallSet<StringRef, 4> SeenTools;
    for (size_t I = 0, E = Ident->getNumOperands(); I < E; ++I) {
      const auto *S = cast<MDString>(Ident->getOperand(I)->getOperand(0));
      std::pair<StringRef, StringRef> Field = S->getString().split("version");
      StringRef Name = Field.first.trim();
      StringRef Version = Field.second.trim();
      if (SeenTools.insert(Name).second)
        Tools.emplace_back(Name.str(), Version.str());
    }
  }

  int FieldCount = int(!Languages.empty()) + int(!Tools.empty());
  if (FieldCount != 0) {
    MCSectionWasm *Producers = OutContext.getWasmSection(
        ".custom_section.producers", SectionKind::getMetadata());
    OutStreamer->pushSection();
    OutStreamer->switchSection(Producers);
    OutStreamer->emitULEB128IntValue(FieldCount);
    for (auto &Producers : {std::make_pair("language", &Languages),
            std::make_pair("processed-by", &Tools)}) {
      if (Producers.second->empty())
        continue;
      OutStreamer->emitULEB128IntValue(strlen(Producers.first));
      OutStreamer->emitBytes(Producers.first);
      OutStreamer->emitULEB128IntValue(Producers.second->size());
      for (auto &Producer : *Producers.second) {
        OutStreamer->emitULEB128IntValue(Producer.first.size());
        OutStreamer->emitBytes(Producer.first);
        OutStreamer->emitULEB128IntValue(Producer.second.size());
        OutStreamer->emitBytes(Producer.second);
      }
    }
    OutStreamer->popSection();
  }
}

void WebAssemblyAsmPrinter::EmitTargetFeatures(Module &M) {
  struct FeatureEntry {
    uint8_t Prefix;
    std::string Name;
  };

  // Read target features and linkage policies from module metadata
  SmallVector<FeatureEntry, 4> EmittedFeatures;
  auto EmitFeature = [&](std::string Feature) {
    std::string MDKey = (StringRef("wasm-feature-") + Feature).str();
    Metadata *Policy = M.getModuleFlag(MDKey);
    if (Policy == nullptr)
      return;

    FeatureEntry Entry;
    Entry.Prefix = 0;
    Entry.Name = Feature;

    if (auto *MD = cast<ConstantAsMetadata>(Policy))
      if (auto *I = cast<ConstantInt>(MD->getValue()))
        Entry.Prefix = I->getZExtValue();

    // Silently ignore invalid metadata
    if (Entry.Prefix != wasm::WASM_FEATURE_PREFIX_USED &&
        Entry.Prefix != wasm::WASM_FEATURE_PREFIX_DISALLOWED)
      return;

    EmittedFeatures.push_back(Entry);
  };

  for (const SubtargetFeatureKV &KV : WebAssemblyFeatureKV) {
    EmitFeature(KV.Key);
  }
  // This pseudo-feature tells the linker whether shared memory would be safe
  EmitFeature("shared-mem");

  // This is an "architecture", not a "feature", but we emit it as such for
  // the benefit of tools like Binaryen and consistency with other producers.
  // FIXME: Subtarget is null here, so can't Subtarget->hasAddr64() ?
  if (M.getDataLayout().getPointerSize() == 8) {
    // Can't use EmitFeature since "wasm-feature-memory64" is not a module
    // flag.
    EmittedFeatures.push_back({wasm::WASM_FEATURE_PREFIX_USED, "memory64"});
  }

  if (EmittedFeatures.size() == 0)
    return;

  // Emit features and linkage policies into the "target_features" section
  MCSectionWasm *FeaturesSection = OutContext.getWasmSection(
      ".custom_section.target_features", SectionKind::getMetadata());
  OutStreamer->pushSection();
  OutStreamer->switchSection(FeaturesSection);

  OutStreamer->emitULEB128IntValue(EmittedFeatures.size());
  for (auto &F : EmittedFeatures) {
    OutStreamer->emitIntValue(F.Prefix, 1);
    OutStreamer->emitULEB128IntValue(F.Name.size());
    OutStreamer->emitBytes(F.Name);
  }

  OutStreamer->popSection();
}

void WebAssemblyAsmPrinter::EmitFunctionAttributes(Module &M) {
  auto V = M.getNamedGlobal("llvm.global.annotations");
  if (!V)
    return;

  // Group all the custom attributes by name.
  MapVector<StringRef, SmallVector<MCSymbol *, 4>> CustomSections;
  const ConstantArray *CA = cast<ConstantArray>(V->getOperand(0));
  for (Value *Op : CA->operands()) {
    auto *CS = cast<ConstantStruct>(Op);
    // The first field is a pointer to the annotated variable.
    Value *AnnotatedVar = CS->getOperand(0)->stripPointerCasts();
    // Only annotated functions are supported for now.
    if (!isa<Function>(AnnotatedVar))
      continue;
    auto *F = cast<Function>(AnnotatedVar);

    // The second field is a pointer to a global annotation string.
    auto *GV = cast<GlobalVariable>(CS->getOperand(1)->stripPointerCasts());
    StringRef AnnotationString;
    getConstantStringInfo(GV, AnnotationString);
    auto *Sym = static_cast<MCSymbolWasm *>(getSymbol(F));
    CustomSections[AnnotationString].push_back(Sym);
  }

  // Emit a custom section for each unique attribute.
  for (const auto &[Name, Symbols] : CustomSections) {
    MCSectionWasm *CustomSection = OutContext.getWasmSection(
        ".custom_section.llvm.func_attr.annotate." + Name, SectionKind::getMetadata());
    OutStreamer->pushSection();
    OutStreamer->switchSection(CustomSection);

    for (auto &Sym : Symbols) {
      OutStreamer->emitValue(
          MCSymbolRefExpr::create(Sym, WebAssembly::S_FUNCINDEX, OutContext),
          4);
    }
    OutStreamer->popSection();
  }
}

void WebAssemblyAsmPrinter::emitConstantPool() {
  emitDecls(*MMI->getModule());
  assert(MF->getConstantPool()->getConstants().empty() &&
         "WebAssembly disables constant pools");
}

void WebAssemblyAsmPrinter::emitJumpTableInfo() {
  // Nothing to do; jump tables are incorporated into the instruction stream.
}

void WebAssemblyAsmPrinter::emitFunctionBodyStart() {
  const Function &F = MF->getFunction();
  SmallVector<MVT, 1> ResultVTs;
  SmallVector<MVT, 4> ParamVTs;
  computeSignatureVTs(F.getFunctionType(), &F, F, TM, ParamVTs, ResultVTs);

  auto Signature = signatureFromMVTs(OutContext, ResultVTs, ParamVTs);
  auto *WasmSym = static_cast<MCSymbolWasm *>(CurrentFnSym);
  WasmSym->setSignature(Signature);
  WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);

  getTargetStreamer()->emitFunctionType(WasmSym);

  // Emit the function index.
  if (MDNode *Idx = F.getMetadata("wasm.index")) {
    assert(Idx->getNumOperands() == 1);

    getTargetStreamer()->emitIndIdx(AsmPrinter::lowerConstant(
        cast<ConstantAsMetadata>(Idx->getOperand(0))->getValue()));
  }

  SmallVector<wasm::ValType, 16> Locals;
  valTypesFromMVTs(MFI->getLocals(), Locals);
  getTargetStreamer()->emitLocal(Locals);

  AsmPrinter::emitFunctionBodyStart();
}

void WebAssemblyAsmPrinter::emitInstruction(const MachineInstr *MI) {
  LLVM_DEBUG(dbgs() << "EmitInstruction: " << *MI << '\n');
  WebAssembly_MC::verifyInstructionPredicates(MI->getOpcode(),
                                              Subtarget->getFeatureBits());

  switch (MI->getOpcode()) {
  case WebAssembly::ARGUMENT_i32:
  case WebAssembly::ARGUMENT_i32_S:
  case WebAssembly::ARGUMENT_i64:
  case WebAssembly::ARGUMENT_i64_S:
  case WebAssembly::ARGUMENT_f32:
  case WebAssembly::ARGUMENT_f32_S:
  case WebAssembly::ARGUMENT_f64:
  case WebAssembly::ARGUMENT_f64_S:
  case WebAssembly::ARGUMENT_v16i8:
  case WebAssembly::ARGUMENT_v16i8_S:
  case WebAssembly::ARGUMENT_v8i16:
  case WebAssembly::ARGUMENT_v8i16_S:
  case WebAssembly::ARGUMENT_v4i32:
  case WebAssembly::ARGUMENT_v4i32_S:
  case WebAssembly::ARGUMENT_v2i64:
  case WebAssembly::ARGUMENT_v2i64_S:
  case WebAssembly::ARGUMENT_v4f32:
  case WebAssembly::ARGUMENT_v4f32_S:
  case WebAssembly::ARGUMENT_v2f64:
  case WebAssembly::ARGUMENT_v2f64_S:
  case WebAssembly::ARGUMENT_v8f16:
  case WebAssembly::ARGUMENT_v8f16_S:
    // These represent values which are live into the function entry, so there's
    // no instruction to emit.
    break;
  case WebAssembly::FALLTHROUGH_RETURN: {
    // These instructions represent the implicit return at the end of a
    // function body.
    if (isVerbose()) {
      OutStreamer->AddComment("fallthrough-return");
      OutStreamer->addBlankLine();
    }
    break;
  }
  case WebAssembly::COMPILER_FENCE:
    // This is a compiler barrier that prevents instruction reordering during
    // backend compilation, and should not be emitted.
    break;
  case WebAssembly::CATCH:
  case WebAssembly::CATCH_S:
  case WebAssembly::CATCH_REF:
  case WebAssembly::CATCH_REF_S:
  case WebAssembly::CATCH_ALL:
  case WebAssembly::CATCH_ALL_S:
  case WebAssembly::CATCH_ALL_REF:
  case WebAssembly::CATCH_ALL_REF_S:
    // These are pseudo instructions to represent catch clauses in try_table
    // instruction to simulate block return values.
    break;
  default: {
    WebAssemblyMCInstLower MCInstLowering(OutContext, *this);
    MCInst TmpInst;
    MCInstLowering.lower(MI, TmpInst);
    EmitToStreamer(*OutStreamer, TmpInst);
    break;
  }
  }
}

bool WebAssemblyAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
                                            unsigned OpNo,
                                            const char *ExtraCode,
                                            raw_ostream &OS) {
  // First try the generic code, which knows about modifiers like 'c' and 'n'.
  if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS))
    return false;

  if (!ExtraCode) {
    const MachineOperand &MO = MI->getOperand(OpNo);
    switch (MO.getType()) {
    case MachineOperand::MO_Immediate:
      OS << MO.getImm();
      return false;
    case MachineOperand::MO_Register:
      // FIXME: only opcode that still contains registers, as required by
      // MachineInstr::getDebugVariable().
      assert(MI->getOpcode() == WebAssembly::INLINEASM);
      OS << regToString(MO);
      return false;
    case MachineOperand::MO_GlobalAddress:
      PrintSymbolOperand(MO, OS);
      return false;
    case MachineOperand::MO_ExternalSymbol:
      GetExternalSymbolSymbol(MO.getSymbolName())->print(OS, MAI);
      printOffset(MO.getOffset(), OS);
      return false;
    case MachineOperand::MO_MachineBasicBlock:
      MO.getMBB()->getSymbol()->print(OS, MAI);
      return false;
    default:
      break;
    }
  }

  return true;
}

bool WebAssemblyAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
                                                  unsigned OpNo,
                                                  const char *ExtraCode,
                                                  raw_ostream &OS) {
  // The current approach to inline asm is that "r" constraints are expressed
  // as local indices, rather than values on the operand stack. This simplifies
  // using "r" as it eliminates the need to push and pop the values in a
  // particular order, however it also makes it impossible to have an "m"
  // constraint. So we don't support it.

  return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, ExtraCode, OS);
}

char WebAssemblyAsmPrinter::ID = 0;

INITIALIZE_PASS(WebAssemblyAsmPrinter, "webassembly-asm-printer",
                "WebAssembly Assmebly Printer", false, false)

// Force static initialization.
extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeWebAssemblyAsmPrinter() {
  RegisterAsmPrinter<WebAssemblyAsmPrinter> X(getTheWebAssemblyTarget32());
  RegisterAsmPrinter<WebAssemblyAsmPrinter> Y(getTheWebAssemblyTarget64());
}
