blob: c198a262241fd70c526735f15de10f8c93fc9d4d [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
34WebAssemblyTargetAsmStreamer::WebAssemblyTargetAsmStreamer(
35 MCStreamer &S, formatted_raw_ostream &OS)
36 : WebAssemblyTargetStreamer(S), OS(OS) {}
37
38WebAssemblyTargetELFStreamer::WebAssemblyTargetELFStreamer(MCStreamer &S)
39 : WebAssemblyTargetStreamer(S) {}
40
Dan Gohman18eafb62017-02-22 01:23:18 +000041WebAssemblyTargetWasmStreamer::WebAssemblyTargetWasmStreamer(MCStreamer &S)
42 : WebAssemblyTargetStreamer(S) {}
43
Dan Gohman3469ee12016-01-12 20:30:51 +000044static void PrintTypes(formatted_raw_ostream &OS, ArrayRef<MVT> Types) {
45 bool First = true;
46 for (MVT Type : Types) {
47 if (First)
48 First = false;
49 else
50 OS << ", ";
51 OS << WebAssembly::TypeToString(Type);
52 }
53 OS << '\n';
54}
55
Dan Gohmand934cb82017-02-24 23:18:00 +000056void WebAssemblyTargetAsmStreamer::emitParam(MCSymbol *Symbol,
57 ArrayRef<MVT> Types) {
58 if (!Types.empty()) {
59 OS << "\t.param \t";
60
61 // FIXME: Currently this applies to the "current" function; it may
62 // be cleaner to specify an explicit symbol as part of the directive.
63
64 PrintTypes(OS, Types);
65 }
Dan Gohman3469ee12016-01-12 20:30:51 +000066}
67
Dan Gohmand934cb82017-02-24 23:18:00 +000068void WebAssemblyTargetAsmStreamer::emitResult(MCSymbol *Symbol,
69 ArrayRef<MVT> Types) {
70 if (!Types.empty()) {
71 OS << "\t.result \t";
72
73 // FIXME: Currently this applies to the "current" function; it may
74 // be cleaner to specify an explicit symbol as part of the directive.
75
76 PrintTypes(OS, Types);
77 }
Dan Gohman3469ee12016-01-12 20:30:51 +000078}
79
80void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<MVT> Types) {
Dan Gohman3acb1872016-10-24 23:27:49 +000081 if (!Types.empty()) {
82 OS << "\t.local \t";
83 PrintTypes(OS, Types);
84 }
Dan Gohman3469ee12016-01-12 20:30:51 +000085}
86
87void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
88
Derek Schuff5859a9ed2016-06-03 18:34:36 +000089void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType(
Dan Gohman2726b882016-10-06 22:29:32 +000090 StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
Derek Schuff5859a9ed2016-06-03 18:34:36 +000091 OS << "\t.functype\t" << name;
Dan Gohman2726b882016-10-06 22:29:32 +000092 if (Results.empty())
Derek Schuffc64d7652016-08-01 22:25:02 +000093 OS << ", void";
Dan Gohman2726b882016-10-06 22:29:32 +000094 else {
95 assert(Results.size() == 1);
96 OS << ", " << WebAssembly::TypeToString(Results.front());
Derek Schuff5859a9ed2016-06-03 18:34:36 +000097 }
Dan Gohman2726b882016-10-06 22:29:32 +000098 for (auto Ty : Params)
99 OS << ", " << WebAssembly::TypeToString(Ty);
100 OS << '\n';
Derek Schuff5859a9ed2016-06-03 18:34:36 +0000101}
102
Derek Schuff7747d703e2016-12-01 00:11:15 +0000103void WebAssemblyTargetAsmStreamer::emitGlobalImport(StringRef name) {
104 OS << "\t.import_global\t" << name << '\n';
105}
106
Derek Schuffc64d7652016-08-01 22:25:02 +0000107void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) {
108 OS << "\t.indidx \t" << *Value << '\n';
109}
110
Dan Gohmand934cb82017-02-24 23:18:00 +0000111void WebAssemblyTargetELFStreamer::emitParam(MCSymbol *Symbol,
112 ArrayRef<MVT> Types) {
Dan Gohman3acb1872016-10-24 23:27:49 +0000113 // Nothing to emit; params are declared as part of the function signature.
Dan Gohman3469ee12016-01-12 20:30:51 +0000114}
115
Dan Gohmand934cb82017-02-24 23:18:00 +0000116void WebAssemblyTargetELFStreamer::emitResult(MCSymbol *Symbol,
117 ArrayRef<MVT> Types) {
Dan Gohman3acb1872016-10-24 23:27:49 +0000118 // Nothing to emit; results are declared as part of the function signature.
Dan Gohman3469ee12016-01-12 20:30:51 +0000119}
120
121void WebAssemblyTargetELFStreamer::emitLocal(ArrayRef<MVT> Types) {
Dan Gohman3acb1872016-10-24 23:27:49 +0000122 Streamer.EmitULEB128IntValue(Types.size());
123 for (MVT Type : Types)
124 Streamer.EmitIntValue(int64_t(WebAssembly::toValType(Type)), 1);
Dan Gohman3469ee12016-01-12 20:30:51 +0000125}
126
127void WebAssemblyTargetELFStreamer::emitEndFunc() {
Dan Gohman3acb1872016-10-24 23:27:49 +0000128 Streamer.EmitIntValue(WebAssembly::End, 1);
Dan Gohman3469ee12016-01-12 20:30:51 +0000129}
Derek Schuffc64d7652016-08-01 22:25:02 +0000130
131void WebAssemblyTargetELFStreamer::emitIndIdx(const MCExpr *Value) {
Dan Gohman3acb1872016-10-24 23:27:49 +0000132 llvm_unreachable(".indidx encoding not yet implemented");
133}
134
135void WebAssemblyTargetELFStreamer::emitIndirectFunctionType(
136 StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
137 // Nothing to emit here. TODO: Re-design how linking works and re-evaluate
138 // whether it's necessary for .o files to declare indirect function types.
Derek Schuffc64d7652016-08-01 22:25:02 +0000139}
Derek Schuff7747d703e2016-12-01 00:11:15 +0000140
141void WebAssemblyTargetELFStreamer::emitGlobalImport(StringRef name) {
Dan Gohman18eafb62017-02-22 01:23:18 +0000142}
143
Dan Gohmand934cb82017-02-24 23:18:00 +0000144static unsigned MVT2WasmType(MVT Ty) {
145 switch (Ty.SimpleTy) {
146 case MVT::i32: return wasm::WASM_TYPE_I32;
147 case MVT::i64: return wasm::WASM_TYPE_I64;
148 case MVT::f32: return wasm::WASM_TYPE_F32;
149 case MVT::f64: return wasm::WASM_TYPE_F64;
150 default: llvm_unreachable("unsupported type");
151 }
Dan Gohman18eafb62017-02-22 01:23:18 +0000152}
153
Dan Gohmand934cb82017-02-24 23:18:00 +0000154void WebAssemblyTargetWasmStreamer::emitParam(MCSymbol *Symbol,
155 ArrayRef<MVT> Types) {
156 SmallVector<unsigned, 4> Params;
157 for (MVT Ty : Types)
158 Params.push_back(MVT2WasmType(Ty));
159
160 cast<MCSymbolWasm>(Symbol)->setParams(std::move(Params));
161}
162
163void WebAssemblyTargetWasmStreamer::emitResult(MCSymbol *Symbol,
164 ArrayRef<MVT> Types) {
165 SmallVector<unsigned, 4> Returns;
166 for (MVT Ty : Types)
167 Returns.push_back(MVT2WasmType(Ty));
168
169 cast<MCSymbolWasm>(Symbol)->setReturns(std::move(Returns));
Dan Gohman18eafb62017-02-22 01:23:18 +0000170}
171
172void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<MVT> Types) {
Dan Gohmand934cb82017-02-24 23:18:00 +0000173 SmallVector<std::pair<MVT, uint32_t>, 4> Grouped;
174 for (MVT Type : Types) {
175 if (Grouped.empty() || Grouped.back().first != Type)
176 Grouped.push_back(std::make_pair(Type, 1));
177 else
178 ++Grouped.back().second;
179 }
180
181 Streamer.EmitULEB128IntValue(Grouped.size());
182 for (auto Pair : Grouped) {
183 Streamer.EmitULEB128IntValue(Pair.second);
184 Streamer.EmitULEB128IntValue(uint64_t(WebAssembly::toValType(Pair.first)));
185 }
Dan Gohman18eafb62017-02-22 01:23:18 +0000186}
187
188void WebAssemblyTargetWasmStreamer::emitEndFunc() {
Dan Gohmand934cb82017-02-24 23:18:00 +0000189 llvm_unreachable(".end_func is not needed for direct wasm output");
Dan Gohman18eafb62017-02-22 01:23:18 +0000190}
191
192void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) {
193 llvm_unreachable(".indidx encoding not yet implemented");
194}
195
196void WebAssemblyTargetWasmStreamer::emitIndirectFunctionType(
197 StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
198 // Nothing to emit here. TODO: Re-design how linking works and re-evaluate
199 // whether it's necessary for .o files to declare indirect function types.
200}
201
202void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) {
203}