MSP430MCInstLower.cpp revision 263508
176633Stshiozak//===-- MSP430MCInstLower.cpp - Convert MSP430 MachineInstr to an MCInst --===//
276633Stshiozak//
376633Stshiozak//                     The LLVM Compiler Infrastructure
476633Stshiozak//
576633Stshiozak// This file is distributed under the University of Illinois Open Source
676633Stshiozak// License. See LICENSE.TXT for details.
776633Stshiozak//
876633Stshiozak//===----------------------------------------------------------------------===//
976633Stshiozak//
1076633Stshiozak// This file contains code to lower MSP430 MachineInstrs to their corresponding
1176633Stshiozak// MCInst records.
1276633Stshiozak//
1376633Stshiozak//===----------------------------------------------------------------------===//
1476633Stshiozak
1576633Stshiozak#include "MSP430MCInstLower.h"
1676633Stshiozak#include "llvm/ADT/SmallString.h"
1776633Stshiozak#include "llvm/CodeGen/AsmPrinter.h"
1876633Stshiozak#include "llvm/CodeGen/MachineBasicBlock.h"
1976633Stshiozak#include "llvm/CodeGen/MachineInstr.h"
2076633Stshiozak#include "llvm/MC/MCAsmInfo.h"
2176633Stshiozak#include "llvm/MC/MCContext.h"
2276633Stshiozak#include "llvm/MC/MCExpr.h"
2376633Stshiozak#include "llvm/MC/MCInst.h"
2476633Stshiozak#include "llvm/Support/ErrorHandling.h"
2576633Stshiozak#include "llvm/Support/raw_ostream.h"
2676633Stshiozak#include "llvm/Target/Mangler.h"
2779555Sobrienusing namespace llvm;
2876633Stshiozak
2976633StshiozakMCSymbol *MSP430MCInstLower::
3076633StshiozakGetGlobalAddressSymbol(const MachineOperand &MO) const {
3176633Stshiozak  switch (MO.getTargetFlags()) {
3276633Stshiozak  default: llvm_unreachable("Unknown target flag on GV operand");
3376633Stshiozak  case 0: break;
3476633Stshiozak  }
3576633Stshiozak
3676633Stshiozak  return Printer.getSymbol(MO.getGlobal());
37101253Stjr}
38101253Stjr
3976633StshiozakMCSymbol *MSP430MCInstLower::
4076633StshiozakGetExternalSymbolSymbol(const MachineOperand &MO) const {
4176633Stshiozak  switch (MO.getTargetFlags()) {
4276633Stshiozak  default: llvm_unreachable("Unknown target flag on GV operand");
4376633Stshiozak  case 0: break;
44101313Stjr  }
45101313Stjr
46101313Stjr  return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
47101313Stjr}
48101313Stjr
49101253StjrMCSymbol *MSP430MCInstLower::
50101253StjrGetJumpTableSymbol(const MachineOperand &MO) const {
51101253Stjr  SmallString<256> Name;
52101253Stjr  raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "JTI"
53101253Stjr                            << Printer.getFunctionNumber() << '_'
5476633Stshiozak                            << MO.getIndex();
5576633Stshiozak
5676633Stshiozak  switch (MO.getTargetFlags()) {
5776633Stshiozak  default: llvm_unreachable("Unknown target flag on GV operand");
5876633Stshiozak  case 0: break;
59101253Stjr  }
60101313Stjr
61101313Stjr  // Create a symbol for the name.
62101253Stjr  return Ctx.GetOrCreateSymbol(Name.str());
63101253Stjr}
64101253Stjr
6593032SimpMCSymbol *MSP430MCInstLower::
6693032SimpGetConstantPoolIndexSymbol(const MachineOperand &MO) const {
6793032Simp  SmallString<256> Name;
6893032Simp  raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "CPI"
6993032Simp                            << Printer.getFunctionNumber() << '_'
7093032Simp                            << MO.getIndex();
7193032Simp
7293032Simp  switch (MO.getTargetFlags()) {
7393032Simp  default: llvm_unreachable("Unknown target flag on GV operand");
7493032Simp  case 0: break;
7593032Simp  }
7693032Simp
7793032Simp  // Create a symbol for the name.
7893032Simp  return Ctx.GetOrCreateSymbol(Name.str());
79101253Stjr}
8076633Stshiozak
8176633StshiozakMCSymbol *MSP430MCInstLower::
82101253StjrGetBlockAddressSymbol(const MachineOperand &MO) const {
83101253Stjr  switch (MO.getTargetFlags()) {
8476633Stshiozak  default: llvm_unreachable("Unknown target flag on GV operand");
85  case 0: break;
86  }
87
88  return Printer.GetBlockAddressSymbol(MO.getBlockAddress());
89}
90
91MCOperand MSP430MCInstLower::
92LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const {
93  // FIXME: We would like an efficient form for this, so we don't have to do a
94  // lot of extra uniquing.
95  const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);
96
97  switch (MO.getTargetFlags()) {
98  default: llvm_unreachable("Unknown target flag on GV operand");
99  case 0: break;
100  }
101
102  if (!MO.isJTI() && MO.getOffset())
103    Expr = MCBinaryExpr::CreateAdd(Expr,
104                                   MCConstantExpr::Create(MO.getOffset(), Ctx),
105                                   Ctx);
106  return MCOperand::CreateExpr(Expr);
107}
108
109void MSP430MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
110  OutMI.setOpcode(MI->getOpcode());
111
112  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
113    const MachineOperand &MO = MI->getOperand(i);
114
115    MCOperand MCOp;
116    switch (MO.getType()) {
117    default:
118      MI->dump();
119      llvm_unreachable("unknown operand type");
120    case MachineOperand::MO_Register:
121      // Ignore all implicit register operands.
122      if (MO.isImplicit()) continue;
123      MCOp = MCOperand::CreateReg(MO.getReg());
124      break;
125    case MachineOperand::MO_Immediate:
126      MCOp = MCOperand::CreateImm(MO.getImm());
127      break;
128    case MachineOperand::MO_MachineBasicBlock:
129      MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
130                         MO.getMBB()->getSymbol(), Ctx));
131      break;
132    case MachineOperand::MO_GlobalAddress:
133      MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
134      break;
135    case MachineOperand::MO_ExternalSymbol:
136      MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
137      break;
138    case MachineOperand::MO_JumpTableIndex:
139      MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO));
140      break;
141    case MachineOperand::MO_ConstantPoolIndex:
142      MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
143      break;
144    case MachineOperand::MO_BlockAddress:
145      MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO));
146      break;
147    case MachineOperand::MO_RegisterMask:
148      continue;
149    }
150
151    OutMI.addOperand(MCOp);
152  }
153}
154