[WebAssembly] Add WebAssemblyMCInstLower.cpp.
authorDan Gohman <dan433584@gmail.com>
Thu, 5 Nov 2015 19:28:16 +0000 (19:28 +0000)
committerDan Gohman <dan433584@gmail.com>
Thu, 5 Nov 2015 19:28:16 +0000 (19:28 +0000)
This isn't used yet; it's just a start towards eventually using MC to
do instruction printing, and eventually binary encoding.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252194 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/WebAssembly/CMakeLists.txt
lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp [new file with mode: 0644]
lib/Target/WebAssembly/WebAssemblyMCInstLower.h [new file with mode: 0644]

index 44e536a..96f039b 100644 (file)
@@ -19,6 +19,7 @@ add_llvm_target(WebAssemblyCodeGen
   WebAssemblyISelLowering.cpp
   WebAssemblyInstrInfo.cpp
   WebAssemblyMachineFunctionInfo.cpp
+  WebAssemblyMCInstLower.cpp
   WebAssemblyRegisterInfo.cpp
   WebAssemblySelectionDAGInfo.cpp
   WebAssemblySubtarget.cpp
index cbd2f7d..bb10f20 100644 (file)
@@ -21,6 +21,7 @@
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FormattedStream.h"
+#include "llvm/Target/TargetRegisterInfo.h"
 #include <cctype>
 using namespace llvm;
 
@@ -35,7 +36,10 @@ WebAssemblyInstPrinter::WebAssemblyInstPrinter(const MCAsmInfo &MAI,
 
 void WebAssemblyInstPrinter::printRegName(raw_ostream &OS,
                                           unsigned RegNo) const {
-  OS << getRegisterName(RegNo);
+  if (TargetRegisterInfo::isPhysicalRegister(RegNo))
+    OS << getRegisterName(RegNo);
+  else
+    OS << TargetRegisterInfo::virtReg2Index(RegNo);
 }
 
 void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
@@ -43,15 +47,31 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
                                        const MCSubtargetInfo &STI) {
   printInstruction(MI, OS);
   printAnnotation(OS, Annot);
+
+  unsigned NumDefs = MII.get(MI->getOpcode()).getNumDefs();
+  assert(NumDefs <= 1 &&
+         "Instructions with multiple result values not implemented");
+
+  if (NumDefs != 0) {
+    OS << "\n"
+          "\t" "set_local ";
+    printRegName(OS, MI->getOperand(0).getReg());
+    OS << ", pop";
+  }
 }
 
 void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
                                           raw_ostream &O) {
   const MCOperand &Op = MI->getOperand(OpNo);
-  if (Op.isReg())
-    O << getRegisterName(Op.getReg());
-  else if (Op.isImm())
+  if (Op.isReg()) {
+    if (OpNo < MII.get(MI->getOpcode()).getNumDefs())
+      O << "push";
+    else
+      printRegName(O, Op.getReg());
+  } else if (Op.isImm())
     O << '#' << Op.getImm();
+  else if (Op.isFPImm())
+    O << '#' << Op.getFPImm();
   else {
     assert(Op.isExpr() && "unknown operand kind in printOperand");
     Op.getExpr()->print(O, &MAI);
index 0644fd8..fcd4c29 100644 (file)
@@ -40,6 +40,12 @@ static MCAsmInfo *createWebAssemblyMCAsmInfo(const MCRegisterInfo &MRI,
   return new WebAssemblyMCAsmInfo(TT);
 }
 
+static MCInstrInfo *createWebAssemblyMCInstrInfo() {
+  MCInstrInfo *X = new MCInstrInfo();
+  InitWebAssemblyMCInstrInfo(X);
+  return X;
+}
+
 static MCInstPrinter *
 createWebAssemblyMCInstPrinter(const Triple &T, unsigned SyntaxVariant,
                                const MCAsmInfo &MAI, const MCInstrInfo &MII,
@@ -54,6 +60,9 @@ extern "C" void LLVMInitializeWebAssemblyTargetMC() {
     // Register the MC asm info.
     RegisterMCAsmInfoFn X(*T, createWebAssemblyMCAsmInfo);
 
+    // Register the MC instruction info.
+    TargetRegistry::RegisterMCInstrInfo(*T, createWebAssemblyMCInstrInfo);
+
     // Register the MCInstPrinter.
     TargetRegistry::RegisterMCInstPrinter(*T, createWebAssemblyMCInstPrinter);
   }
diff --git a/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
new file mode 100644 (file)
index 0000000..59acbdb
--- /dev/null
@@ -0,0 +1,84 @@
+// WebAssemblyMCInstLower.cpp - Convert WebAssembly MachineInstr to an MCInst //
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file contains code to lower WebAssembly MachineInstrs to their
+/// corresponding MCInst records.
+///
+//===----------------------------------------------------------------------===//
+
+#include "WebAssemblyMCInstLower.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+MCSymbol *
+WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
+  return Printer.getSymbol(MO.getGlobal());
+}
+
+MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
+                                                     MCSymbol *Sym) const {
+
+  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
+
+  if (!MO.isJTI() && MO.getOffset())
+    llvm_unreachable("unknown symbol op");
+
+  return MCOperand::createExpr(Expr);
+}
+
+void WebAssemblyMCInstLower::Lower(const MachineInstr *MI,
+                                   MCInst &OutMI) const {
+  OutMI.setOpcode(MI->getOpcode());
+
+  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+    const MachineOperand &MO = MI->getOperand(i);
+
+    MCOperand MCOp;
+    switch (MO.getType()) {
+    default:
+      MI->dump();
+      llvm_unreachable("unknown operand type");
+    case MachineOperand::MO_Register:
+      // Ignore all implicit register operands.
+      if (MO.isImplicit())
+        continue;
+      MCOp = MCOperand::createReg(MO.getReg());
+      break;
+    case MachineOperand::MO_Immediate:
+      MCOp = MCOperand::createImm(MO.getImm());
+      break;
+    case MachineOperand::MO_FPImmediate:
+      MCOp = MCOperand::createFPImm(
+          MO.getFPImm()->getValueAPF().convertToDouble());
+      break;
+    case MachineOperand::MO_MachineBasicBlock:
+      MCOp = MCOperand::createExpr(
+          MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx));
+      break;
+    case MachineOperand::MO_RegisterMask:
+      continue;
+    case MachineOperand::MO_GlobalAddress:
+      MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
+      break;
+    }
+
+    OutMI.addOperand(MCOp);
+  }
+}
diff --git a/lib/Target/WebAssembly/WebAssemblyMCInstLower.h b/lib/Target/WebAssembly/WebAssemblyMCInstLower.h
new file mode 100644 (file)
index 0000000..c622c02
--- /dev/null
@@ -0,0 +1,50 @@
+//===-- WebAssemblyMCInstLower.h - Lower MachineInstr to MCInst -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file declares the class to lower WebAssembly MachineInstrs to
+/// their corresponding MCInst records.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMCINSTLOWER_H
+#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMCINSTLOWER_H
+
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+class AsmPrinter;
+class MCContext;
+class MCInst;
+class MCOperand;
+class MCSymbol;
+class MachineInstr;
+class MachineModuleInfoMachO;
+class MachineOperand;
+class Mangler;
+
+// WebAssemblyMCInstLower - This class is used to lower an MachineInstr into an
+// MCInst.
+class LLVM_LIBRARY_VISIBILITY WebAssemblyMCInstLower {
+  MCContext &Ctx;
+
+  AsmPrinter &Printer;
+
+public:
+  WebAssemblyMCInstLower(MCContext &ctx, AsmPrinter &printer)
+      : Ctx(ctx), Printer(printer) {}
+  void Lower(const MachineInstr *MI, MCInst &OutMI) const;
+
+  MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const;
+
+  MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO) const;
+};
+}
+
+#endif