aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/WebAssembly/MCTargetDesc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/WebAssembly/MCTargetDesc')
-rw-r--r--lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp10
-rw-r--r--lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp57
-rw-r--r--lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h3
-rw-r--r--lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp1
-rw-r--r--lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h74
-rw-r--r--lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp33
-rw-r--r--lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h3
-rw-r--r--lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp11
8 files changed, 108 insertions, 84 deletions
diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp
index 70b409cf4a90..8314de41021f 100644
--- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp
+++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp
@@ -31,10 +31,12 @@ namespace {
class WebAssemblyAsmBackend final : public MCAsmBackend {
bool Is64Bit;
+ bool IsEmscripten;
public:
- explicit WebAssemblyAsmBackend(bool Is64Bit)
- : MCAsmBackend(support::little), Is64Bit(Is64Bit) {}
+ explicit WebAssemblyAsmBackend(bool Is64Bit, bool IsEmscripten)
+ : MCAsmBackend(support::little), Is64Bit(Is64Bit),
+ IsEmscripten(IsEmscripten) {}
unsigned getNumFixupKinds() const override {
return WebAssembly::NumTargetFixupKinds;
@@ -123,11 +125,11 @@ void WebAssemblyAsmBackend::applyFixup(const MCAssembler &Asm,
std::unique_ptr<MCObjectTargetWriter>
WebAssemblyAsmBackend::createObjectTargetWriter() const {
- return createWebAssemblyWasmObjectWriter(Is64Bit);
+ return createWebAssemblyWasmObjectWriter(Is64Bit, IsEmscripten);
}
} // end anonymous namespace
MCAsmBackend *llvm::createWebAssemblyAsmBackend(const Triple &TT) {
- return new WebAssemblyAsmBackend(TT.isArch64Bit());
+ return new WebAssemblyAsmBackend(TT.isArch64Bit(), TT.isOSEmscripten());
}
diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index b5d4d369b726..221ac17b8336 100644
--- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -15,6 +15,7 @@
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssembly.h"
#include "WebAssemblyMachineFunctionInfo.h"
+#include "WebAssemblyUtilities.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
@@ -51,7 +52,9 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
// Print any additional variadic operands.
const MCInstrDesc &Desc = MII.get(MI->getOpcode());
- if (Desc.isVariadic())
+ if (Desc.isVariadic()) {
+ if (Desc.getNumOperands() == 0 && MI->getNumOperands() > 0)
+ OS << "\t";
for (auto I = Desc.getNumOperands(), E = MI->getNumOperands(); I < E; ++I) {
// FIXME: For CALL_INDIRECT_VOID, don't print a leading comma, because
// we have an extra flags operand which is not currently printed, for
@@ -62,6 +65,7 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
OS << ", ";
printOperand(MI, I, OS);
}
+ }
// Print any added annotation.
printAnnotation(OS, Annot);
@@ -232,7 +236,16 @@ void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
}
} else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
- Op.getExpr()->print(O, &MAI);
+ // call_indirect instructions have a TYPEINDEX operand that we print
+ // as a signature here, such that the assembler can recover this
+ // information.
+ auto SRE = static_cast<const MCSymbolRefExpr *>(Op.getExpr());
+ if (SRE->getKind() == MCSymbolRefExpr::VK_WASM_TYPEINDEX) {
+ auto &Sym = static_cast<const MCSymbolWasm &>(SRE->getSymbol());
+ O << WebAssembly::signatureToString(Sym.getSignature());
+ } else {
+ Op.getExpr()->print(O, &MAI);
+ }
}
}
@@ -259,14 +272,26 @@ void WebAssemblyInstPrinter::printWebAssemblyP2AlignOperand(const MCInst *MI,
void WebAssemblyInstPrinter::printWebAssemblySignatureOperand(const MCInst *MI,
unsigned OpNo,
raw_ostream &O) {
- auto Imm = static_cast<unsigned>(MI->getOperand(OpNo).getImm());
- if (Imm != wasm::WASM_TYPE_NORESULT)
- O << WebAssembly::anyTypeToString(Imm);
+ const MCOperand &Op = MI->getOperand(OpNo);
+ if (Op.isImm()) {
+ auto Imm = static_cast<unsigned>(Op.getImm());
+ if (Imm != wasm::WASM_TYPE_NORESULT)
+ O << WebAssembly::anyTypeToString(Imm);
+ } else {
+ auto Expr = cast<MCSymbolRefExpr>(Op.getExpr());
+ auto *Sym = cast<MCSymbolWasm>(&Expr->getSymbol());
+ if (Sym->getSignature()) {
+ O << WebAssembly::signatureToString(Sym->getSignature());
+ } else {
+ // Disassembler does not currently produce a signature
+ O << "unknown_type";
+ }
+ }
}
// We have various enums representing a subset of these types, use this
// function to convert any of them to text.
-const char *llvm::WebAssembly::anyTypeToString(unsigned Ty) {
+const char *WebAssembly::anyTypeToString(unsigned Ty) {
switch (Ty) {
case wasm::WASM_TYPE_I32:
return "i32";
@@ -291,6 +316,24 @@ const char *llvm::WebAssembly::anyTypeToString(unsigned Ty) {
}
}
-const char *llvm::WebAssembly::typeToString(wasm::ValType Ty) {
+const char *WebAssembly::typeToString(wasm::ValType Ty) {
return anyTypeToString(static_cast<unsigned>(Ty));
}
+
+std::string WebAssembly::typeListToString(ArrayRef<wasm::ValType> List) {
+ std::string S;
+ for (auto &Ty : List) {
+ if (&Ty != &List[0]) S += ", ";
+ S += WebAssembly::typeToString(Ty);
+ }
+ return S;
+}
+
+std::string WebAssembly::signatureToString(const wasm::WasmSignature *Sig) {
+ std::string S("(");
+ S += typeListToString(Sig->Params);
+ S += ") -> (";
+ S += typeListToString(Sig->Returns);
+ S += ")";
+ return S;
+}
diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h
index b979de5028bf..cf37778099a0 100644
--- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h
+++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h
@@ -58,6 +58,9 @@ namespace WebAssembly {
const char *typeToString(wasm::ValType Ty);
const char *anyTypeToString(unsigned Ty);
+std::string typeListToString(ArrayRef<wasm::ValType> List);
+std::string signatureToString(const wasm::WasmSignature *Sig);
+
} // end namespace WebAssembly
} // end namespace llvm
diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
index 44b6d6a968a9..1a4c57e66d2f 100644
--- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
+++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
@@ -152,6 +152,7 @@ void WebAssemblyMCCodeEmitter::encodeInstruction(
break;
case WebAssembly::OPERAND_FUNCTION32:
case WebAssembly::OPERAND_OFFSET32:
+ case WebAssembly::OPERAND_SIGNATURE:
case WebAssembly::OPERAND_TYPEINDEX:
case WebAssembly::OPERAND_GLOBAL:
case WebAssembly::OPERAND_EVENT:
diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
index 7a9f59b1a4f2..b339860a381d 100644
--- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -38,7 +38,7 @@ MCCodeEmitter *createWebAssemblyMCCodeEmitter(const MCInstrInfo &MCII);
MCAsmBackend *createWebAssemblyAsmBackend(const Triple &TT);
std::unique_ptr<MCObjectTargetWriter>
-createWebAssemblyWasmObjectWriter(bool Is64Bit);
+createWebAssemblyWasmObjectWriter(bool Is64Bit, bool IsEmscripten);
namespace WebAssembly {
enum OperandType {
@@ -122,16 +122,22 @@ enum TOF {
namespace llvm {
namespace WebAssembly {
-/// This is used to indicate block signatures.
-enum class ExprType : unsigned {
+/// Used as immediate MachineOperands for block signatures
+enum class BlockType : unsigned {
+ Invalid = 0x00,
Void = 0x40,
- I32 = 0x7F,
- I64 = 0x7E,
- F32 = 0x7D,
- F64 = 0x7C,
- V128 = 0x7B,
- Exnref = 0x68,
- Invalid = 0x00
+ I32 = unsigned(wasm::ValType::I32),
+ I64 = unsigned(wasm::ValType::I64),
+ F32 = unsigned(wasm::ValType::F32),
+ F64 = unsigned(wasm::ValType::F64),
+ V128 = unsigned(wasm::ValType::V128),
+ Exnref = unsigned(wasm::ValType::EXNREF),
+ // Multivalue blocks (and other non-void blocks) are only emitted when the
+ // blocks will never be exited and are at the ends of functions (see
+ // WebAssemblyCFGStackify::fixEndsAtEndOfFunction). They also are never made
+ // to pop values off the stack, so the exact multivalue signature can always
+ // be inferred from the return type of the parent function in MCInstLower.
+ Multivalue = 0xffff,
};
/// Instruction opcodes emitted via means other than CodeGen.
@@ -191,6 +197,8 @@ inline unsigned GetDefaultP2AlignAny(unsigned Opc) {
case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I32_S:
case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I64:
case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I64_S:
+ case WebAssembly::LOAD_SPLAT_v8x16:
+ case WebAssembly::LOAD_SPLAT_v8x16_S:
return 0;
case WebAssembly::LOAD16_S_I32:
case WebAssembly::LOAD16_S_I32_S:
@@ -240,6 +248,8 @@ inline unsigned GetDefaultP2AlignAny(unsigned Opc) {
case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I32_S:
case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I64:
case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I64_S:
+ case WebAssembly::LOAD_SPLAT_v16x8:
+ case WebAssembly::LOAD_SPLAT_v16x8_S:
return 1;
case WebAssembly::LOAD_I32:
case WebAssembly::LOAD_I32_S:
@@ -295,6 +305,8 @@ inline unsigned GetDefaultP2AlignAny(unsigned Opc) {
case WebAssembly::ATOMIC_NOTIFY_S:
case WebAssembly::ATOMIC_WAIT_I32:
case WebAssembly::ATOMIC_WAIT_I32_S:
+ case WebAssembly::LOAD_SPLAT_v32x4:
+ case WebAssembly::LOAD_SPLAT_v32x4_S:
return 2;
case WebAssembly::LOAD_I64:
case WebAssembly::LOAD_I64_S:
@@ -324,31 +336,25 @@ inline unsigned GetDefaultP2AlignAny(unsigned Opc) {
case WebAssembly::ATOMIC_RMW_CMPXCHG_I64_S:
case WebAssembly::ATOMIC_WAIT_I64:
case WebAssembly::ATOMIC_WAIT_I64_S:
+ case WebAssembly::LOAD_SPLAT_v64x2:
+ case WebAssembly::LOAD_SPLAT_v64x2_S:
+ case WebAssembly::LOAD_EXTEND_S_v8i16:
+ case WebAssembly::LOAD_EXTEND_S_v8i16_S:
+ case WebAssembly::LOAD_EXTEND_U_v8i16:
+ case WebAssembly::LOAD_EXTEND_U_v8i16_S:
+ case WebAssembly::LOAD_EXTEND_S_v4i32:
+ case WebAssembly::LOAD_EXTEND_S_v4i32_S:
+ case WebAssembly::LOAD_EXTEND_U_v4i32:
+ case WebAssembly::LOAD_EXTEND_U_v4i32_S:
+ case WebAssembly::LOAD_EXTEND_S_v2i64:
+ case WebAssembly::LOAD_EXTEND_S_v2i64_S:
+ case WebAssembly::LOAD_EXTEND_U_v2i64:
+ case WebAssembly::LOAD_EXTEND_U_v2i64_S:
return 3;
- case WebAssembly::LOAD_v16i8:
- case WebAssembly::LOAD_v16i8_S:
- case WebAssembly::LOAD_v8i16:
- case WebAssembly::LOAD_v8i16_S:
- case WebAssembly::LOAD_v4i32:
- case WebAssembly::LOAD_v4i32_S:
- case WebAssembly::LOAD_v2i64:
- case WebAssembly::LOAD_v2i64_S:
- case WebAssembly::LOAD_v4f32:
- case WebAssembly::LOAD_v4f32_S:
- case WebAssembly::LOAD_v2f64:
- case WebAssembly::LOAD_v2f64_S:
- case WebAssembly::STORE_v16i8:
- case WebAssembly::STORE_v16i8_S:
- case WebAssembly::STORE_v8i16:
- case WebAssembly::STORE_v8i16_S:
- case WebAssembly::STORE_v4i32:
- case WebAssembly::STORE_v4i32_S:
- case WebAssembly::STORE_v2i64:
- case WebAssembly::STORE_v2i64_S:
- case WebAssembly::STORE_v4f32:
- case WebAssembly::STORE_v4f32_S:
- case WebAssembly::STORE_v2f64:
- case WebAssembly::STORE_v2f64_S:
+ case WebAssembly::LOAD_V128:
+ case WebAssembly::LOAD_V128_S:
+ case WebAssembly::STORE_V128:
+ case WebAssembly::STORE_V128_S:
return 4;
default:
return -1;
diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
index e05efef7201b..40926201931a 100644
--- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
+++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
@@ -60,39 +60,10 @@ void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {
void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
-void WebAssemblyTargetAsmStreamer::emitSignature(
- const wasm::WasmSignature *Sig) {
- OS << "(";
- emitParamList(Sig);
- OS << ") -> (";
- emitReturnList(Sig);
- OS << ")";
-}
-
-void WebAssemblyTargetAsmStreamer::emitParamList(
- const wasm::WasmSignature *Sig) {
- auto &Params = Sig->Params;
- for (auto &Ty : Params) {
- if (&Ty != &Params[0])
- OS << ", ";
- OS << WebAssembly::typeToString(Ty);
- }
-}
-
-void WebAssemblyTargetAsmStreamer::emitReturnList(
- const wasm::WasmSignature *Sig) {
- auto &Returns = Sig->Returns;
- for (auto &Ty : Returns) {
- if (&Ty != &Returns[0])
- OS << ", ";
- OS << WebAssembly::typeToString(Ty);
- }
-}
-
void WebAssemblyTargetAsmStreamer::emitFunctionType(const MCSymbolWasm *Sym) {
assert(Sym->isFunction());
OS << "\t.functype\t" << Sym->getName() << " ";
- emitSignature(Sym->getSignature());
+ OS << WebAssembly::signatureToString(Sym->getSignature());
OS << "\n";
}
@@ -107,7 +78,7 @@ void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) {
void WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) {
assert(Sym->isEvent());
OS << "\t.eventtype\t" << Sym->getName() << " ";
- emitParamList(Sym->getSignature());
+ OS << WebAssembly::typeListToString(Sym->getSignature()->Params);
OS << "\n";
}
diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
index 5ea62b179d22..0164f8e572ef 100644
--- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
+++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
@@ -56,9 +56,6 @@ protected:
/// This part is for ascii assembly output
class WebAssemblyTargetAsmStreamer final : public WebAssemblyTargetStreamer {
formatted_raw_ostream &OS;
- void emitSignature(const wasm::WasmSignature *Sig);
- void emitParamList(const wasm::WasmSignature *Sig);
- void emitReturnList(const wasm::WasmSignature *Sig);
public:
WebAssemblyTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
index a1cc3e268e8f..e7a599e3e175 100644
--- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
+++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
@@ -31,7 +31,7 @@ using namespace llvm;
namespace {
class WebAssemblyWasmObjectWriter final : public MCWasmObjectTargetWriter {
public:
- explicit WebAssemblyWasmObjectWriter(bool Is64Bit);
+ explicit WebAssemblyWasmObjectWriter(bool Is64Bit, bool IsEmscripten);
private:
unsigned getRelocType(const MCValue &Target,
@@ -39,8 +39,9 @@ private:
};
} // end anonymous namespace
-WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit)
- : MCWasmObjectTargetWriter(Is64Bit) {}
+WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit,
+ bool IsEmscripten)
+ : MCWasmObjectTargetWriter(Is64Bit, IsEmscripten) {}
static const MCSection *getFixupSection(const MCExpr *Expr) {
if (auto SyExp = dyn_cast<MCSymbolRefExpr>(Expr)) {
@@ -116,6 +117,6 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
}
std::unique_ptr<MCObjectTargetWriter>
-llvm::createWebAssemblyWasmObjectWriter(bool Is64Bit) {
- return llvm::make_unique<WebAssemblyWasmObjectWriter>(Is64Bit);
+llvm::createWebAssemblyWasmObjectWriter(bool Is64Bit, bool IsEmscripten) {
+ return std::make_unique<WebAssemblyWasmObjectWriter>(Is64Bit, IsEmscripten);
}