WebAssemblyTargetStreamer.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. #include "MCTargetDesc/WebAssemblyTargetStreamer.h"
  15. #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
  16. #include "Utils/WebAssemblyTypeUtilities.h"
  17. #include "llvm/MC/MCContext.h"
  18. #include "llvm/MC/MCSectionWasm.h"
  19. #include "llvm/MC/MCSubtargetInfo.h"
  20. #include "llvm/MC/MCSymbolWasm.h"
  21. #include "llvm/Support/Casting.h"
  22. #include "llvm/Support/ErrorHandling.h"
  23. #include "llvm/Support/FormattedStream.h"
  24. using namespace llvm;
  25. WebAssemblyTargetStreamer::WebAssemblyTargetStreamer(MCStreamer &S)
  26. : MCTargetStreamer(S) {}
  27. void WebAssemblyTargetStreamer::emitValueType(wasm::ValType Type) {
  28. Streamer.emitIntValue(uint8_t(Type), 1);
  29. }
  30. WebAssemblyTargetAsmStreamer::WebAssemblyTargetAsmStreamer(
  31. MCStreamer &S, formatted_raw_ostream &OS)
  32. : WebAssemblyTargetStreamer(S), OS(OS) {}
  33. WebAssemblyTargetWasmStreamer::WebAssemblyTargetWasmStreamer(MCStreamer &S)
  34. : WebAssemblyTargetStreamer(S) {}
  35. static void printTypes(formatted_raw_ostream &OS,
  36. ArrayRef<wasm::ValType> Types) {
  37. bool First = true;
  38. for (auto Type : Types) {
  39. if (First)
  40. First = false;
  41. else
  42. OS << ", ";
  43. OS << WebAssembly::typeToString(Type);
  44. }
  45. OS << '\n';
  46. }
  47. void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {
  48. if (!Types.empty()) {
  49. OS << "\t.local \t";
  50. printTypes(OS, Types);
  51. }
  52. }
  53. void WebAssemblyTargetAsmStreamer::emitFunctionType(const MCSymbolWasm *Sym) {
  54. assert(Sym->isFunction());
  55. OS << "\t.functype\t" << Sym->getName() << " ";
  56. OS << WebAssembly::signatureToString(Sym->getSignature());
  57. OS << "\n";
  58. }
  59. void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) {
  60. assert(Sym->isGlobal());
  61. OS << "\t.globaltype\t" << Sym->getName() << ", "
  62. << WebAssembly::typeToString(
  63. static_cast<wasm::ValType>(Sym->getGlobalType().Type));
  64. if (!Sym->getGlobalType().Mutable)
  65. OS << ", immutable";
  66. OS << '\n';
  67. }
  68. void WebAssemblyTargetAsmStreamer::emitTableType(const MCSymbolWasm *Sym) {
  69. assert(Sym->isTable());
  70. const wasm::WasmTableType &Type = Sym->getTableType();
  71. OS << "\t.tabletype\t" << Sym->getName() << ", "
  72. << WebAssembly::typeToString(static_cast<wasm::ValType>(Type.ElemType));
  73. bool HasMaximum = Type.Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX;
  74. if (Type.Limits.Minimum != 0 || HasMaximum) {
  75. OS << ", " << Type.Limits.Minimum;
  76. if (HasMaximum)
  77. OS << ", " << Type.Limits.Maximum;
  78. }
  79. OS << '\n';
  80. }
  81. void WebAssemblyTargetAsmStreamer::emitTagType(const MCSymbolWasm *Sym) {
  82. assert(Sym->isTag());
  83. OS << "\t.tagtype\t" << Sym->getName() << " ";
  84. OS << WebAssembly::typeListToString(Sym->getSignature()->Params);
  85. OS << "\n";
  86. }
  87. void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym,
  88. StringRef ImportModule) {
  89. OS << "\t.import_module\t" << Sym->getName() << ", "
  90. << ImportModule << '\n';
  91. }
  92. void WebAssemblyTargetAsmStreamer::emitImportName(const MCSymbolWasm *Sym,
  93. StringRef ImportName) {
  94. OS << "\t.import_name\t" << Sym->getName() << ", "
  95. << ImportName << '\n';
  96. }
  97. void WebAssemblyTargetAsmStreamer::emitExportName(const MCSymbolWasm *Sym,
  98. StringRef ExportName) {
  99. OS << "\t.export_name\t" << Sym->getName() << ", "
  100. << ExportName << '\n';
  101. }
  102. void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) {
  103. OS << "\t.indidx \t" << *Value << '\n';
  104. }
  105. void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {
  106. SmallVector<std::pair<wasm::ValType, uint32_t>, 4> Grouped;
  107. for (auto Type : Types) {
  108. if (Grouped.empty() || Grouped.back().first != Type)
  109. Grouped.push_back(std::make_pair(Type, 1));
  110. else
  111. ++Grouped.back().second;
  112. }
  113. Streamer.emitULEB128IntValue(Grouped.size());
  114. for (auto Pair : Grouped) {
  115. Streamer.emitULEB128IntValue(Pair.second);
  116. emitValueType(Pair.first);
  117. }
  118. }
  119. void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) {
  120. llvm_unreachable(".indidx encoding not yet implemented");
  121. }