diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
commit | d8e91e46262bc44006913e6796843909f1ac7bcd (patch) | |
tree | 7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp | |
parent | b7eb8e35e481a74962664b63dfb09483b200209a (diff) |
Notes
Diffstat (limited to 'lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp')
-rw-r--r-- | lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp | 112 |
1 files changed, 79 insertions, 33 deletions
diff --git a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index 1f280e1d13fc..c4f03dfa7f9e 100644 --- a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -50,7 +50,7 @@ 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::v4f32}) + MVT::v4i32, MVT::v2i64, MVT::v4f32, MVT::v2f64}) if (TRI->isTypeLegalForClass(*TRC, T)) return T; LLVM_DEBUG(errs() << "Unknown type for register number: " << RegNo); @@ -78,24 +78,45 @@ WebAssemblyTargetStreamer *WebAssemblyAsmPrinter::getTargetStreamer() { //===----------------------------------------------------------------------===// void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) { + for (auto &It : OutContext.getSymbols()) { + // Emit a .globaltype and .eventtype declaration. + auto Sym = cast<MCSymbolWasm>(It.getValue()); + if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_GLOBAL) + getTargetStreamer()->emitGlobalType(Sym); + else if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_EVENT) + getTargetStreamer()->emitEventType(Sym); + } + for (const auto &F : M) { // Emit function type info for all undefined functions if (F.isDeclarationForLinker() && !F.isIntrinsic()) { SmallVector<MVT, 4> Results; SmallVector<MVT, 4> Params; - ComputeSignatureVTs(F, TM, Params, Results); - MCSymbol *Sym = getSymbol(&F); - getTargetStreamer()->emitIndirectFunctionType(Sym, Params, Results); + ComputeSignatureVTs(F.getFunctionType(), F, TM, Params, Results); + auto *Sym = cast<MCSymbolWasm>(getSymbol(&F)); + Sym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); + if (!Sym->getSignature()) { + auto Signature = SignatureFromMVTs(Results, Params); + Sym->setSignature(Signature.get()); + addSignature(std::move(Signature)); + } + // FIXME: this was originally intended for post-linking and was only used + // for imports that were only called indirectly (i.e. s2wasm could not + // infer the type from a call). With object files it applies to all + // imports. so fix the names and the tests, or rethink how import + // delcarations work in asm files. + getTargetStreamer()->emitFunctionType(Sym); if (TM.getTargetTriple().isOSBinFormatWasm() && F.hasFnAttribute("wasm-import-module")) { - MCSymbolWasm *WasmSym = cast<MCSymbolWasm>(Sym); - StringRef Name = F.getFnAttribute("wasm-import-module") - .getValueAsString(); - getTargetStreamer()->emitImportModule(WasmSym, Name); + StringRef Name = + F.getFnAttribute("wasm-import-module").getValueAsString(); + Sym->setModuleName(Name); + getTargetStreamer()->emitImportModule(Sym, Name); } } } + for (const auto &G : M.globals()) { if (!G.hasInitializer() && G.hasExternalLinkage()) { if (G.getValueType()->isSized()) { @@ -137,10 +158,18 @@ void WebAssemblyAsmPrinter::EmitJumpTableInfo() { } void WebAssemblyAsmPrinter::EmitFunctionBodyStart() { - getTargetStreamer()->emitParam(CurrentFnSym, MFI->getParams()); - - SmallVector<MVT, 4> ResultVTs; const Function &F = MF->getFunction(); + SmallVector<MVT, 1> ResultVTs; + SmallVector<MVT, 4> ParamVTs; + ComputeSignatureVTs(F.getFunctionType(), F, TM, ParamVTs, ResultVTs); + auto Signature = SignatureFromMVTs(ResultVTs, ParamVTs); + auto *WasmSym = cast<MCSymbolWasm>(CurrentFnSym); + WasmSym->setSignature(Signature.get()); + addSignature(std::move(Signature)); + WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); + + // FIXME: clean up how params and results are emitted (use signatures) + getTargetStreamer()->emitFunctionType(WasmSym); // Emit the function index. if (MDNode *Idx = F.getMetadata("wasm.index")) { @@ -150,16 +179,9 @@ void WebAssemblyAsmPrinter::EmitFunctionBodyStart() { cast<ConstantAsMetadata>(Idx->getOperand(0))->getValue())); } - ComputeLegalValueVTs(F, TM, F.getReturnType(), ResultVTs); - - // If the return type needs to be legalized it will get converted into - // passing a pointer. - if (ResultVTs.size() == 1) - getTargetStreamer()->emitResult(CurrentFnSym, ResultVTs); - else - getTargetStreamer()->emitResult(CurrentFnSym, ArrayRef<MVT>()); - - getTargetStreamer()->emitLocal(MFI->getLocals()); + SmallVector<wasm::ValType, 16> Locals; + ValTypesFromMVTs(MFI->getLocals(), Locals); + getTargetStreamer()->emitLocal(Locals); AsmPrinter::EmitFunctionBodyStart(); } @@ -168,42 +190,63 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) { LLVM_DEBUG(dbgs() << "EmitInstruction: " << *MI << '\n'); switch (MI->getOpcode()) { - case WebAssembly::ARGUMENT_I32: - case WebAssembly::ARGUMENT_I64: - case WebAssembly::ARGUMENT_F32: - case WebAssembly::ARGUMENT_F64: + 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: // These represent values which are live into the function entry, so there's // no instruction to emit. break; case WebAssembly::FALLTHROUGH_RETURN_I32: + case WebAssembly::FALLTHROUGH_RETURN_I32_S: case WebAssembly::FALLTHROUGH_RETURN_I64: + case WebAssembly::FALLTHROUGH_RETURN_I64_S: case WebAssembly::FALLTHROUGH_RETURN_F32: + case WebAssembly::FALLTHROUGH_RETURN_F32_S: case WebAssembly::FALLTHROUGH_RETURN_F64: + case WebAssembly::FALLTHROUGH_RETURN_F64_S: case WebAssembly::FALLTHROUGH_RETURN_v16i8: + case WebAssembly::FALLTHROUGH_RETURN_v16i8_S: case WebAssembly::FALLTHROUGH_RETURN_v8i16: + case WebAssembly::FALLTHROUGH_RETURN_v8i16_S: case WebAssembly::FALLTHROUGH_RETURN_v4i32: - case WebAssembly::FALLTHROUGH_RETURN_v4f32: { + case WebAssembly::FALLTHROUGH_RETURN_v4i32_S: + case WebAssembly::FALLTHROUGH_RETURN_v2i64: + case WebAssembly::FALLTHROUGH_RETURN_v2i64_S: + case WebAssembly::FALLTHROUGH_RETURN_v4f32: + case WebAssembly::FALLTHROUGH_RETURN_v4f32_S: + case WebAssembly::FALLTHROUGH_RETURN_v2f64: + case WebAssembly::FALLTHROUGH_RETURN_v2f64_S: { // These instructions represent the implicit return at the end of a - // function body. The operand is always a pop. - assert(MFI->isVRegStackified(MI->getOperand(0).getReg())); - + // function body. Always pops one value off the stack. if (isVerbose()) { - OutStreamer->AddComment("fallthrough-return: $pop" + - Twine(MFI->getWARegStackId( - MFI->getWAReg(MI->getOperand(0).getReg())))); + OutStreamer->AddComment("fallthrough-return-value"); OutStreamer->AddBlankLine(); } break; } case WebAssembly::FALLTHROUGH_RETURN_VOID: + case WebAssembly::FALLTHROUGH_RETURN_VOID_S: // This instruction represents the implicit return at the end of a // function body with no return value. if (isVerbose()) { - OutStreamer->AddComment("fallthrough-return"); + OutStreamer->AddComment("fallthrough-return-void"); OutStreamer->AddBlankLine(); } break; @@ -244,6 +287,9 @@ bool WebAssemblyAsmPrinter::PrintAsmOperand(const MachineInstr *MI, 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: |