131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- MSP430MCInstLower.cpp - Convert MSP430 MachineInstr to an MCInst --===//
20e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky//
30e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky//                     The LLVM Compiler Infrastructure
40e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky//
50e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky// This file is distributed under the University of Illinois Open Source
60e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky// License. See LICENSE.TXT for details.
70e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky//
80e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky//===----------------------------------------------------------------------===//
90e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky//
100e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky// This file contains code to lower MSP430 MachineInstrs to their corresponding
110e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky// MCInst records.
120e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky//
130e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky//===----------------------------------------------------------------------===//
140e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
150e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky#include "MSP430MCInstLower.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallString.h"
170e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky#include "llvm/CodeGen/AsmPrinter.h"
180e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky#include "llvm/CodeGen/MachineBasicBlock.h"
190e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky#include "llvm/CodeGen/MachineInstr.h"
200e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky#include "llvm/MC/MCAsmInfo.h"
210e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky#include "llvm/MC/MCContext.h"
220e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky#include "llvm/MC/MCExpr.h"
230e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky#include "llvm/MC/MCInst.h"
240e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky#include "llvm/Support/ErrorHandling.h"
25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/raw_ostream.h"
26d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/Mangler.h"
270e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewyckyusing namespace llvm;
280e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
290e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick LewyckyMCSymbol *MSP430MCInstLower::
300e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick LewyckyGetGlobalAddressSymbol(const MachineOperand &MO) const {
310e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  switch (MO.getTargetFlags()) {
320e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  default: llvm_unreachable("Unknown target flag on GV operand");
330e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  case 0: break;
340e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  }
350e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
360e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  return Printer.Mang->getSymbol(MO.getGlobal());
370e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky}
380e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
390e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick LewyckyMCSymbol *MSP430MCInstLower::
400e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick LewyckyGetExternalSymbolSymbol(const MachineOperand &MO) const {
410e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  switch (MO.getTargetFlags()) {
42bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Unknown target flag on GV operand");
430e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  case 0: break;
440e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  }
450e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
460e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
470e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky}
480e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
490e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick LewyckyMCSymbol *MSP430MCInstLower::
500e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick LewyckyGetJumpTableSymbol(const MachineOperand &MO) const {
510e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  SmallString<256> Name;
520e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "JTI"
530e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky                            << Printer.getFunctionNumber() << '_'
540e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky                            << MO.getIndex();
550e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
560e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  switch (MO.getTargetFlags()) {
570e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  default: llvm_unreachable("Unknown target flag on GV operand");
580e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  case 0: break;
590e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  }
600e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
610e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  // Create a symbol for the name.
620e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  return Ctx.GetOrCreateSymbol(Name.str());
630e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky}
640e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
650e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick LewyckyMCSymbol *MSP430MCInstLower::
660e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick LewyckyGetConstantPoolIndexSymbol(const MachineOperand &MO) const {
670e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  SmallString<256> Name;
680e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "CPI"
690e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky                            << Printer.getFunctionNumber() << '_'
700e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky                            << MO.getIndex();
710e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
720e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  switch (MO.getTargetFlags()) {
730e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  default: llvm_unreachable("Unknown target flag on GV operand");
740e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  case 0: break;
750e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  }
760e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
770e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  // Create a symbol for the name.
780e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  return Ctx.GetOrCreateSymbol(Name.str());
790e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky}
800e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
810e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick LewyckyMCSymbol *MSP430MCInstLower::
820e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick LewyckyGetBlockAddressSymbol(const MachineOperand &MO) const {
830e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  switch (MO.getTargetFlags()) {
84bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Unknown target flag on GV operand");
850e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  case 0: break;
860e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  }
870e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
880e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  return Printer.GetBlockAddressSymbol(MO.getBlockAddress());
890e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky}
900e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
910e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick LewyckyMCOperand MSP430MCInstLower::
920e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick LewyckyLowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const {
930e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  // FIXME: We would like an efficient form for this, so we don't have to do a
940e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  // lot of extra uniquing.
950e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);
960e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
970e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  switch (MO.getTargetFlags()) {
980e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  default: llvm_unreachable("Unknown target flag on GV operand");
990e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  case 0: break;
1000e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  }
1010e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
1020e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  if (!MO.isJTI() && MO.getOffset())
1030e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    Expr = MCBinaryExpr::CreateAdd(Expr,
1040e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky                                   MCConstantExpr::Create(MO.getOffset(), Ctx),
1050e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky                                   Ctx);
1060e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  return MCOperand::CreateExpr(Expr);
1070e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky}
1080e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
1090e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewyckyvoid MSP430MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
1100e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  OutMI.setOpcode(MI->getOpcode());
1110e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
1120e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
1130e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    const MachineOperand &MO = MI->getOperand(i);
1140e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
1150e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    MCOperand MCOp;
1160e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    switch (MO.getType()) {
1170e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    default:
1180e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      MI->dump();
119bc2198133a1836598b54b943420748e75d5dea94Craig Topper      llvm_unreachable("unknown operand type");
1200e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    case MachineOperand::MO_Register:
1210e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      // Ignore all implicit register operands.
1220e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      if (MO.isImplicit()) continue;
1230e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      MCOp = MCOperand::CreateReg(MO.getReg());
1240e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      break;
1250e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    case MachineOperand::MO_Immediate:
1260e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      MCOp = MCOperand::CreateImm(MO.getImm());
1270e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      break;
1280e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    case MachineOperand::MO_MachineBasicBlock:
1290e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
1300e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky                         MO.getMBB()->getSymbol(), Ctx));
1310e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      break;
1320e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    case MachineOperand::MO_GlobalAddress:
1330e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
1340e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      break;
1350e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    case MachineOperand::MO_ExternalSymbol:
1360e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
1370e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      break;
1380e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    case MachineOperand::MO_JumpTableIndex:
1390e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO));
1400e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      break;
1410e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    case MachineOperand::MO_ConstantPoolIndex:
1420e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
1430e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      break;
1440e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    case MachineOperand::MO_BlockAddress:
1450e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky      MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO));
14671f0fc1ca88965b69b4b2c8794a7144bc93d4bbaJakob Stoklund Olesen      break;
14771f0fc1ca88965b69b4b2c8794a7144bc93d4bbaJakob Stoklund Olesen    case MachineOperand::MO_RegisterMask:
14871f0fc1ca88965b69b4b2c8794a7144bc93d4bbaJakob Stoklund Olesen      continue;
1490e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    }
1500e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky
1510e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky    OutMI.addOperand(MCOp);
1520e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky  }
1530e7fdf5f09cf047223aa1756ca113ccd3c383a8eNick Lewycky}
154