WebAssemblyMCInstLower.cpp revision 292915
1139743Simp// WebAssemblyMCInstLower.cpp - Convert WebAssembly MachineInstr to an MCInst //
2184691Sdes//
365577Sdes//                     The LLVM Compiler Infrastructure
459412Smsmith//
559412Smsmith// This file is distributed under the University of Illinois Open Source
659412Smsmith// License. See LICENSE.TXT for details.
759412Smsmith//
859412Smsmith//===----------------------------------------------------------------------===//
959412Smsmith///
1059412Smsmith/// \file
1159412Smsmith/// \brief This file contains code to lower WebAssembly MachineInstrs to their
1259412Smsmith/// corresponding MCInst records.
1359412Smsmith///
1459412Smsmith//===----------------------------------------------------------------------===//
1559412Smsmith
1659412Smsmith#include "WebAssemblyMCInstLower.h"
1759412Smsmith#include "WebAssemblyMachineFunctionInfo.h"
1859412Smsmith#include "llvm/CodeGen/AsmPrinter.h"
1959412Smsmith#include "llvm/CodeGen/MachineFunction.h"
2059412Smsmith#include "llvm/IR/Constants.h"
2159412Smsmith#include "llvm/MC/MCAsmInfo.h"
2259412Smsmith#include "llvm/MC/MCContext.h"
2359412Smsmith#include "llvm/MC/MCExpr.h"
2459412Smsmith#include "llvm/MC/MCInst.h"
2559412Smsmith#include "llvm/Support/ErrorHandling.h"
2659412Smsmith#include "llvm/Support/raw_ostream.h"
2759412Smsmithusing namespace llvm;
2859412Smsmith
2959412SmsmithMCSymbol *
3059412SmsmithWebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
3159412Smsmith  return Printer.getSymbol(MO.getGlobal());
3259412Smsmith}
3359412Smsmith
3459412SmsmithMCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol(
3559412Smsmith    const MachineOperand &MO) const {
3659412Smsmith  return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
3759412Smsmith}
3859412Smsmith
3959412SmsmithMCOperand WebAssemblyMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
4059412Smsmith                                                     MCSymbol *Sym) const {
4159412Smsmith  assert(MO.getTargetFlags() == 0 && "WebAssembly does not use target flags");
42182141Sjulian
43182141Sjulian  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
44116173Sobrien
45116173Sobrien  int64_t Offset = MO.getOffset();
46116173Sobrien  if (Offset != 0) {
4759412Smsmith    assert(!MO.isJTI() && "Unexpected offset with jump table index");
4883926Sdes    Expr =
4976166Smarkm        MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, Ctx), Ctx);
5074135Sjlemon  }
5183926Sdes
52177785Skib  return MCOperand::createExpr(Expr);
53119911Sdes}
5476166Smarkm
5565633Sdesvoid WebAssemblyMCInstLower::Lower(const MachineInstr *MI,
5683926Sdes                                   MCInst &OutMI) const {
5776166Smarkm  OutMI.setOpcode(MI->getOpcode());
5874135Sjlemon
5978025Sdes  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
60168067Sjkim    const MachineOperand &MO = MI->getOperand(i);
6176827Salfred
6285289Sdes    MCOperand MCOp;
6365633Sdes    switch (MO.getType()) {
6465633Sdes    default:
6569995Sdes      MI->dump();
66168067Sjkim      llvm_unreachable("unknown operand type");
67123246Sdes    case MachineOperand::MO_Register: {
6883926Sdes      // Ignore all implicit register operands.
6976839Sjlemon      if (MO.isImplicit())
7083926Sdes        continue;
71159995Snetchild      const WebAssemblyFunctionInfo &MFI =
7265633Sdes          *MI->getParent()->getParent()->getInfo<WebAssemblyFunctionInfo>();
7383926Sdes      unsigned WAReg = MFI.getWAReg(MO.getReg());
7483926Sdes      MCOp = MCOperand::createReg(WAReg);
7559412Smsmith      break;
76181803Sbz    }
7759412Smsmith    case MachineOperand::MO_Immediate:
7883926Sdes      MCOp = MCOperand::createImm(MO.getImm());
79185571Sbz      break;
8083926Sdes    case MachineOperand::MO_FPImmediate: {
8159412Smsmith      // TODO: MC converts all floating point immediate operands to double.
8259412Smsmith      // This is fine for numeric values, but may cause NaNs to change bits.
8367588Sdes      const ConstantFP *Imm = MO.getFPImm();
8459412Smsmith      if (Imm->getType()->isFloatTy())
8560860Sdes        MCOp = MCOperand::createFPImm(Imm->getValueAPF().convertToFloat());
8659412Smsmith      else if (Imm->getType()->isDoubleTy())
8769799Sdes        MCOp = MCOperand::createFPImm(Imm->getValueAPF().convertToDouble());
8867589Sdes      else
8978113Sdes        llvm_unreachable("unknown floating point immediate type");
90133822Stjr      break;
9167589Sdes    }
9259412Smsmith    case MachineOperand::MO_MachineBasicBlock:
93133822Stjr      MCOp = MCOperand::createExpr(
9459412Smsmith          MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx));
95140214Sobrien      break;
96140214Sobrien    case MachineOperand::MO_GlobalAddress:
97140214Sobrien      MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
9887275Srwatson      break;
99133822Stjr    case MachineOperand::MO_ExternalSymbol:
10085129Sdes      MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
10169995Sdes      break;
10285289Sdes    }
10378025Sdes
10484248Sdes    OutMI.addOperand(MCOp);
10559412Smsmith  }
10667588Sdes}
10767588Sdes