summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp')
-rw-r--r--contrib/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp92
1 files changed, 40 insertions, 52 deletions
diff --git a/contrib/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/contrib/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index 54e9f7f..5b4b82e 100644
--- a/contrib/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/contrib/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -14,10 +14,10 @@
///
//===----------------------------------------------------------------------===//
-#include "WebAssembly.h"
#include "InstPrinter/WebAssemblyInstPrinter.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "MCTargetDesc/WebAssemblyTargetStreamer.h"
+#include "WebAssembly.h"
#include "WebAssemblyMCInstLower.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblyRegisterInfo.h"
@@ -42,14 +42,14 @@ namespace {
class WebAssemblyAsmPrinter final : public AsmPrinter {
const MachineRegisterInfo *MRI;
- const WebAssemblyFunctionInfo *MFI;
+ WebAssemblyFunctionInfo *MFI;
public:
WebAssemblyAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
: AsmPrinter(TM, std::move(Streamer)), MRI(nullptr), MFI(nullptr) {}
private:
- const char *getPassName() const override {
+ StringRef getPassName() const override {
return "WebAssembly Assembly Printer";
}
@@ -82,7 +82,6 @@ private:
raw_ostream &OS) override;
MVT getRegType(unsigned RegNo) const;
- const char *toString(MVT VT) const;
std::string regToString(const MachineOperand &MO);
WebAssemblyTargetStreamer *getTargetStreamer();
};
@@ -95,7 +94,8 @@ private:
MVT WebAssemblyAsmPrinter::getRegType(unsigned RegNo) const {
const TargetRegisterClass *TRC = MRI->getRegClass(RegNo);
- for (MVT T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64})
+ for (MVT T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64, MVT::v16i8, MVT::v8i16,
+ MVT::v4i32, MVT::v4f32})
if (TRC->hasType(T))
return T;
DEBUG(errs() << "Unknown type for register number: " << RegNo);
@@ -103,10 +103,6 @@ MVT WebAssemblyAsmPrinter::getRegType(unsigned RegNo) const {
return MVT::Other;
}
-const char *WebAssemblyAsmPrinter::toString(MVT VT) const {
- return WebAssembly::TypeToString(VT);
-}
-
std::string WebAssemblyAsmPrinter::regToString(const MachineOperand &MO) {
unsigned RegNo = MO.getReg();
assert(TargetRegisterInfo::isVirtualRegister(RegNo) &&
@@ -125,45 +121,21 @@ WebAssemblyTargetStreamer *WebAssemblyAsmPrinter::getTargetStreamer() {
//===----------------------------------------------------------------------===//
// WebAssemblyAsmPrinter Implementation.
//===----------------------------------------------------------------------===//
-static void ComputeLegalValueVTs(const Function &F, const TargetMachine &TM,
- Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {
- const DataLayout &DL(F.getParent()->getDataLayout());
- const WebAssemblyTargetLowering &TLI =
- *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();
- SmallVector<EVT, 4> VTs;
- ComputeValueVTs(TLI, DL, Ty, VTs);
-
- for (EVT VT : VTs) {
- unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT);
- MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT);
- for (unsigned i = 0; i != NumRegs; ++i)
- ValueVTs.push_back(RegisterVT);
- }
-}
void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
for (const auto &F : M) {
// Emit function type info for all undefined functions
if (F.isDeclarationForLinker() && !F.isIntrinsic()) {
- SmallVector<MVT, 4> SignatureVTs;
- ComputeLegalValueVTs(F, TM, F.getReturnType(), SignatureVTs);
- size_t NumResults = SignatureVTs.size();
- if (SignatureVTs.size() > 1) {
- // WebAssembly currently can't lower returns of multiple values without
- // demoting to sret (see WebAssemblyTargetLowering::CanLowerReturn). So
- // replace multiple return values with a pointer parameter.
- SignatureVTs.clear();
- SignatureVTs.push_back(
- MVT::getIntegerVT(M.getDataLayout().getPointerSizeInBits()));
- NumResults = 0;
- }
-
- for (auto &Arg : F.args()) {
- ComputeLegalValueVTs(F, TM, Arg.getType(), SignatureVTs);
- }
-
- getTargetStreamer()->emitIndirectFunctionType(F.getName(), SignatureVTs,
- NumResults);
+ SmallVector<MVT, 4> Results;
+ SmallVector<MVT, 4> Params;
+ ComputeSignatureVTs(F, TM, Params, Results);
+ getTargetStreamer()->emitIndirectFunctionType(F.getName(), Params,
+ Results);
+ }
+ }
+ for (const auto &G : M.globals()) {
+ if (!G.hasInitializer() && G.hasExternalLinkage()) {
+ getTargetStreamer()->emitGlobalImport(G.getGlobalIdentifier());
}
}
}
@@ -183,6 +155,15 @@ void WebAssemblyAsmPrinter::EmitFunctionBodyStart() {
SmallVector<MVT, 4> ResultVTs;
const Function &F(*MF->getFunction());
+
+ // Emit the function index.
+ if (MDNode *Idx = F.getMetadata("wasm.index")) {
+ assert(Idx->getNumOperands() == 1);
+
+ getTargetStreamer()->emitIndIdx(AsmPrinter::lowerConstant(
+ 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
@@ -190,8 +171,8 @@ void WebAssemblyAsmPrinter::EmitFunctionBodyStart() {
if (ResultVTs.size() == 1)
getTargetStreamer()->emitResult(ResultVTs);
- bool AnyWARegs = false;
- SmallVector<MVT, 16> LocalTypes;
+ // FIXME: When ExplicitLocals is enabled by default, we won't need
+ // to define the locals here (and MFI can go back to being pointer-to-const).
for (unsigned Idx = 0, IdxE = MRI->getNumVirtRegs(); Idx != IdxE; ++Idx) {
unsigned VReg = TargetRegisterInfo::index2VirtReg(Idx);
unsigned WAReg = MFI->getWAReg(VReg);
@@ -204,11 +185,10 @@ void WebAssemblyAsmPrinter::EmitFunctionBodyStart() {
// Don't declare stackified registers.
if (int(WAReg) < 0)
continue;
- LocalTypes.push_back(getRegType(VReg));
- AnyWARegs = true;
+ MFI->addLocal(getRegType(VReg));
}
- if (AnyWARegs)
- getTargetStreamer()->emitLocal(LocalTypes);
+
+ getTargetStreamer()->emitLocal(MFI->getLocals());
AsmPrinter::EmitFunctionBodyStart();
}
@@ -225,13 +205,21 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
case WebAssembly::ARGUMENT_I64:
case WebAssembly::ARGUMENT_F32:
case WebAssembly::ARGUMENT_F64:
+ case WebAssembly::ARGUMENT_v16i8:
+ case WebAssembly::ARGUMENT_v8i16:
+ case WebAssembly::ARGUMENT_v4i32:
+ case WebAssembly::ARGUMENT_v4f32:
// 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_I64:
case WebAssembly::FALLTHROUGH_RETURN_F32:
- case WebAssembly::FALLTHROUGH_RETURN_F64: {
+ case WebAssembly::FALLTHROUGH_RETURN_F64:
+ case WebAssembly::FALLTHROUGH_RETURN_v16i8:
+ case WebAssembly::FALLTHROUGH_RETURN_v8i16:
+ case WebAssembly::FALLTHROUGH_RETURN_v4i32:
+ case WebAssembly::FALLTHROUGH_RETURN_v4f32: {
// 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()));
@@ -329,6 +317,6 @@ bool WebAssemblyAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
// Force static initialization.
extern "C" void LLVMInitializeWebAssemblyAsmPrinter() {
- RegisterAsmPrinter<WebAssemblyAsmPrinter> X(TheWebAssemblyTarget32);
- RegisterAsmPrinter<WebAssemblyAsmPrinter> Y(TheWebAssemblyTarget64);
+ RegisterAsmPrinter<WebAssemblyAsmPrinter> X(getTheWebAssemblyTarget32());
+ RegisterAsmPrinter<WebAssemblyAsmPrinter> Y(getTheWebAssemblyTarget64());
}
OpenPOWER on IntegriCloud