blob: f3b6b100d65007eccbd1869b39eb7d0e50a7d6cb [file] [log] [blame]
Dan Gohman3469ee12016-01-12 20:30:51 +00001//==-- WebAssemblyTargetStreamer.cpp - WebAssembly Target Streamer Methods --=//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief This file defines WebAssembly-specific target streamer classes.
12/// These are for implementing support for target-specific assembly directives.
13///
14//===----------------------------------------------------------------------===//
15
16#include "WebAssemblyTargetStreamer.h"
17#include "InstPrinter/WebAssemblyInstPrinter.h"
18#include "WebAssemblyMCTargetDesc.h"
Dan Gohman3469ee12016-01-12 20:30:51 +000019#include "llvm/MC/MCContext.h"
20#include "llvm/MC/MCSectionELF.h"
Dan Gohman18eafb62017-02-22 01:23:18 +000021#include "llvm/MC/MCSectionWasm.h"
Dan Gohman3469ee12016-01-12 20:30:51 +000022#include "llvm/MC/MCSubtargetInfo.h"
23#include "llvm/MC/MCSymbolELF.h"
Dan Gohman18eafb62017-02-22 01:23:18 +000024#include "llvm/MC/MCSymbolWasm.h"
Dan Gohmand934cb82017-02-24 23:18:00 +000025#include "llvm/Support/Casting.h"
Dan Gohman3469ee12016-01-12 20:30:51 +000026#include "llvm/Support/ErrorHandling.h"
27#include "llvm/Support/FormattedStream.h"
Dan Gohmand934cb82017-02-24 23:18:00 +000028#include "llvm/Support/Wasm.h"
Dan Gohman3469ee12016-01-12 20:30:51 +000029using namespace llvm;
30
31WebAssemblyTargetStreamer::WebAssemblyTargetStreamer(MCStreamer &S)
32 : MCTargetStreamer(S) {}
33
Derek Schuffb8795392017-03-16 20:49:48 +000034void WebAssemblyTargetStreamer::emitValueType(wasm::ValType Type) {
35 Streamer.EmitSLEB128IntValue(int32_t(Type));
36}
37
Dan Gohman3469ee12016-01-12 20:30:51 +000038WebAssemblyTargetAsmStreamer::WebAssemblyTargetAsmStreamer(
39 MCStreamer &S, formatted_raw_ostream &OS)
40 : WebAssemblyTargetStreamer(S), OS(OS) {}
41
42WebAssemblyTargetELFStreamer::WebAssemblyTargetELFStreamer(MCStreamer &S)
43 : WebAssemblyTargetStreamer(S) {}
44
Dan Gohman18eafb62017-02-22 01:23:18 +000045WebAssemblyTargetWasmStreamer::WebAssemblyTargetWasmStreamer(MCStreamer &S)
46 : WebAssemblyTargetStreamer(S) {}
47
Dan Gohman3469ee12016-01-12 20:30:51 +000048static void PrintTypes(formatted_raw_ostream &OS, ArrayRef<MVT> Types) {
49 bool First = true;
50 for (MVT Type : Types) {
51 if (First)
52 First = false;
53 else
54 OS << ", ";
55 OS << WebAssembly::TypeToString(Type);
56 }
57 OS << '\n';
58}
59
Dan Gohmand934cb82017-02-24 23:18:00 +000060void WebAssemblyTargetAsmStreamer::emitParam(MCSymbol *Symbol,
61 ArrayRef<MVT> Types) {
62 if (!Types.empty()) {
63 OS << "\t.param \t";
64
65 // FIXME: Currently this applies to the "current" function; it may
66 // be cleaner to specify an explicit symbol as part of the directive.
67
68 PrintTypes(OS, Types);
69 }
Dan Gohman3469ee12016-01-12 20:30:51 +000070}
71
Dan Gohmand934cb82017-02-24 23:18:00 +000072void WebAssemblyTargetAsmStreamer::emitResult(MCSymbol *Symbol,
73 ArrayRef<MVT> Types) {
74 if (!Types.empty()) {
75 OS << "\t.result \t";
76
77 // FIXME: Currently this applies to the "current" function; it may
78 // be cleaner to specify an explicit symbol as part of the directive.
79
80 PrintTypes(OS, Types);
81 }
Dan Gohman3469ee12016-01-12 20:30:51 +000082}
83
84void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<MVT> Types) {
Dan Gohman3acb1872016-10-24 23:27:49 +000085 if (!Types.empty()) {
86 OS << "\t.local \t";
87 PrintTypes(OS, Types);
88 }
Dan Gohman3469ee12016-01-12 20:30:51 +000089}
90
Dan Gohman82607f52017-02-24 23:46:05 +000091void WebAssemblyTargetAsmStreamer::emitGlobal(ArrayRef<MVT> Types) {
92 if (!Types.empty()) {
93 OS << "\t.globalvar \t";
94 PrintTypes(OS, Types);
95 }
96}
97
Dan Gohman3469ee12016-01-12 20:30:51 +000098void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
99
Derek Schuff5859a9ed2016-06-03 18:34:36 +0000100void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType(
Dan Gohman2726b882016-10-06 22:29:32 +0000101 StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
Derek Schuff5859a9ed2016-06-03 18:34:36 +0000102 OS << "\t.functype\t" << name;
Dan Gohman2726b882016-10-06 22:29:32 +0000103 if (Results.empty())
Derek Schuffc64d7652016-08-01 22:25:02 +0000104 OS << ", void";
Dan Gohman2726b882016-10-06 22:29:32 +0000105 else {
106 assert(Results.size() == 1);
107 OS << ", " << WebAssembly::TypeToString(Results.front());
Derek Schuff5859a9ed2016-06-03 18:34:36 +0000108 }
Dan Gohman2726b882016-10-06 22:29:32 +0000109 for (auto Ty : Params)
110 OS << ", " << WebAssembly::TypeToString(Ty);
111 OS << '\n';
Derek Schuff5859a9ed2016-06-03 18:34:36 +0000112}
113
Derek Schuff7747d703e2016-12-01 00:11:15 +0000114void WebAssemblyTargetAsmStreamer::emitGlobalImport(StringRef name) {
115 OS << "\t.import_global\t" << name << '\n';
116}
117
Derek Schuffc64d7652016-08-01 22:25:02 +0000118void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) {
119 OS << "\t.indidx \t" << *Value << '\n';
120}
121
Dan Gohmand934cb82017-02-24 23:18:00 +0000122void WebAssemblyTargetELFStreamer::emitParam(MCSymbol *Symbol,
123 ArrayRef<MVT> Types) {
Dan Gohman3acb1872016-10-24 23:27:49 +0000124 // Nothing to emit; params are declared as part of the function signature.
Dan Gohman3469ee12016-01-12 20:30:51 +0000125}
126
Dan Gohmand934cb82017-02-24 23:18:00 +0000127void WebAssemblyTargetELFStreamer::emitResult(MCSymbol *Symbol,
128 ArrayRef<MVT> Types) {
Dan Gohman3acb1872016-10-24 23:27:49 +0000129 // Nothing to emit; results are declared as part of the function signature.
Dan Gohman3469ee12016-01-12 20:30:51 +0000130}
131
132void WebAssemblyTargetELFStreamer::emitLocal(ArrayRef<MVT> Types) {
Dan Gohman3acb1872016-10-24 23:27:49 +0000133 Streamer.EmitULEB128IntValue(Types.size());
134 for (MVT Type : Types)
Derek Schuffb8795392017-03-16 20:49:48 +0000135 emitValueType(WebAssembly::toValType(Type));
Dan Gohman3469ee12016-01-12 20:30:51 +0000136}
137
Dan Gohman82607f52017-02-24 23:46:05 +0000138void WebAssemblyTargetELFStreamer::emitGlobal(ArrayRef<MVT> Types) {
139 llvm_unreachable(".globalvar encoding not yet implemented");
140}
141
Dan Gohman3469ee12016-01-12 20:30:51 +0000142void WebAssemblyTargetELFStreamer::emitEndFunc() {
Dan Gohman3acb1872016-10-24 23:27:49 +0000143 Streamer.EmitIntValue(WebAssembly::End, 1);
Dan Gohman3469ee12016-01-12 20:30:51 +0000144}
Derek Schuffc64d7652016-08-01 22:25:02 +0000145
146void WebAssemblyTargetELFStreamer::emitIndIdx(const MCExpr *Value) {
Dan Gohman3acb1872016-10-24 23:27:49 +0000147 llvm_unreachable(".indidx encoding not yet implemented");
148}
149
150void WebAssemblyTargetELFStreamer::emitIndirectFunctionType(
151 StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
152 // Nothing to emit here. TODO: Re-design how linking works and re-evaluate
153 // whether it's necessary for .o files to declare indirect function types.
Derek Schuffc64d7652016-08-01 22:25:02 +0000154}
Derek Schuff7747d703e2016-12-01 00:11:15 +0000155
156void WebAssemblyTargetELFStreamer::emitGlobalImport(StringRef name) {
Dan Gohman18eafb62017-02-22 01:23:18 +0000157}
158
Dan Gohmand934cb82017-02-24 23:18:00 +0000159void WebAssemblyTargetWasmStreamer::emitParam(MCSymbol *Symbol,
160 ArrayRef<MVT> Types) {
Derek Schuffe2688c42017-03-14 20:23:22 +0000161 SmallVector<wasm::ValType, 4> Params;
Dan Gohmand934cb82017-02-24 23:18:00 +0000162 for (MVT Ty : Types)
Derek Schuffe2688c42017-03-14 20:23:22 +0000163 Params.push_back(WebAssembly::toValType(Ty));
Dan Gohmand934cb82017-02-24 23:18:00 +0000164
165 cast<MCSymbolWasm>(Symbol)->setParams(std::move(Params));
166}
167
168void WebAssemblyTargetWasmStreamer::emitResult(MCSymbol *Symbol,
169 ArrayRef<MVT> Types) {
Derek Schuffe2688c42017-03-14 20:23:22 +0000170 SmallVector<wasm::ValType, 4> Returns;
Dan Gohmand934cb82017-02-24 23:18:00 +0000171 for (MVT Ty : Types)
Derek Schuffe2688c42017-03-14 20:23:22 +0000172 Returns.push_back(WebAssembly::toValType(Ty));
Dan Gohmand934cb82017-02-24 23:18:00 +0000173
174 cast<MCSymbolWasm>(Symbol)->setReturns(std::move(Returns));
Dan Gohman18eafb62017-02-22 01:23:18 +0000175}
176
177void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<MVT> Types) {
Dan Gohmand934cb82017-02-24 23:18:00 +0000178 SmallVector<std::pair<MVT, uint32_t>, 4> Grouped;
179 for (MVT Type : Types) {
180 if (Grouped.empty() || Grouped.back().first != Type)
181 Grouped.push_back(std::make_pair(Type, 1));
182 else
183 ++Grouped.back().second;
184 }
185
186 Streamer.EmitULEB128IntValue(Grouped.size());
187 for (auto Pair : Grouped) {
188 Streamer.EmitULEB128IntValue(Pair.second);
Derek Schuffb8795392017-03-16 20:49:48 +0000189 emitValueType(WebAssembly::toValType(Pair.first));
Dan Gohmand934cb82017-02-24 23:18:00 +0000190 }
Dan Gohman18eafb62017-02-22 01:23:18 +0000191}
192
Dan Gohman82607f52017-02-24 23:46:05 +0000193void WebAssemblyTargetWasmStreamer::emitGlobal(ArrayRef<MVT> Types) {
194 // Encode the globals use by the funciton into the special .global_variables
195 // section. This will later be decoded and turned into contents for the
196 // Globals Section.
197 Streamer.PushSection();
198 Streamer.SwitchSection(Streamer.getContext()
199 .getWasmSection(".global_variables", 0, 0));
200 for (MVT Ty : Types)
Derek Schuffb8795392017-03-16 20:49:48 +0000201 Streamer.EmitIntValue(int64_t(WebAssembly::toValType(Ty)), 1);
Dan Gohman82607f52017-02-24 23:46:05 +0000202 Streamer.PopSection();
203}
204
Dan Gohman18eafb62017-02-22 01:23:18 +0000205void WebAssemblyTargetWasmStreamer::emitEndFunc() {
Dan Gohmand934cb82017-02-24 23:18:00 +0000206 llvm_unreachable(".end_func is not needed for direct wasm output");
Dan Gohman18eafb62017-02-22 01:23:18 +0000207}
208
209void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) {
210 llvm_unreachable(".indidx encoding not yet implemented");
211}
212
213void WebAssemblyTargetWasmStreamer::emitIndirectFunctionType(
214 StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
215 // Nothing to emit here. TODO: Re-design how linking works and re-evaluate
216 // whether it's necessary for .o files to declare indirect function types.
217}
218
219void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) {
220}