• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // WebAssemblyMCInstLower.cpp - Convert WebAssembly MachineInstr to an MCInst //
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 contains code to lower WebAssembly MachineInstrs to their
12  /// corresponding MCInst records.
13  ///
14  //===----------------------------------------------------------------------===//
15  
16  #include "WebAssemblyMCInstLower.h"
17  #include "WebAssemblyMachineFunctionInfo.h"
18  #include "llvm/ADT/SmallString.h"
19  #include "llvm/CodeGen/AsmPrinter.h"
20  #include "llvm/CodeGen/MachineFunction.h"
21  #include "llvm/IR/Constants.h"
22  #include "llvm/MC/MCAsmInfo.h"
23  #include "llvm/MC/MCContext.h"
24  #include "llvm/MC/MCExpr.h"
25  #include "llvm/MC/MCInst.h"
26  #include "llvm/Support/ErrorHandling.h"
27  #include "llvm/Support/raw_ostream.h"
28  using namespace llvm;
29  
30  MCSymbol *
GetGlobalAddressSymbol(const MachineOperand & MO) const31  WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
32    return Printer.getSymbol(MO.getGlobal());
33  }
34  
GetExternalSymbolSymbol(const MachineOperand & MO) const35  MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol(
36      const MachineOperand &MO) const {
37    return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
38  }
39  
LowerSymbolOperand(const MachineOperand & MO,MCSymbol * Sym) const40  MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
41                                                       MCSymbol *Sym) const {
42    assert(MO.getTargetFlags() == 0 && "WebAssembly does not use target flags");
43  
44    const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
45  
46    int64_t Offset = MO.getOffset();
47    if (Offset != 0) {
48      assert(!MO.isJTI() && "Unexpected offset with jump table index");
49      Expr =
50          MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, Ctx), Ctx);
51    }
52  
53    return MCOperand::createExpr(Expr);
54  }
55  
Lower(const MachineInstr * MI,MCInst & OutMI) const56  void WebAssemblyMCInstLower::Lower(const MachineInstr *MI,
57                                     MCInst &OutMI) const {
58    OutMI.setOpcode(MI->getOpcode());
59  
60    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
61      const MachineOperand &MO = MI->getOperand(i);
62  
63      MCOperand MCOp;
64      switch (MO.getType()) {
65      default:
66        MI->dump();
67        llvm_unreachable("unknown operand type");
68      case MachineOperand::MO_Register: {
69        // Ignore all implicit register operands.
70        if (MO.isImplicit())
71          continue;
72        const WebAssemblyFunctionInfo &MFI =
73            *MI->getParent()->getParent()->getInfo<WebAssemblyFunctionInfo>();
74        unsigned WAReg = MFI.getWAReg(MO.getReg());
75        MCOp = MCOperand::createReg(WAReg);
76        break;
77      }
78      case MachineOperand::MO_Immediate:
79        MCOp = MCOperand::createImm(MO.getImm());
80        break;
81      case MachineOperand::MO_FPImmediate: {
82        // TODO: MC converts all floating point immediate operands to double.
83        // This is fine for numeric values, but may cause NaNs to change bits.
84        const ConstantFP *Imm = MO.getFPImm();
85        if (Imm->getType()->isFloatTy())
86          MCOp = MCOperand::createFPImm(Imm->getValueAPF().convertToFloat());
87        else if (Imm->getType()->isDoubleTy())
88          MCOp = MCOperand::createFPImm(Imm->getValueAPF().convertToDouble());
89        else
90          llvm_unreachable("unknown floating point immediate type");
91        break;
92      }
93      case MachineOperand::MO_MachineBasicBlock:
94        MCOp = MCOperand::createExpr(
95            MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx));
96        break;
97      case MachineOperand::MO_GlobalAddress:
98        MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
99        break;
100      case MachineOperand::MO_ExternalSymbol:
101        MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
102        break;
103      }
104  
105      OutMI.addOperand(MCOp);
106    }
107  }
108