XCoreMCInstLower.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
1//===-- XCoreMCInstLower.cpp - Convert XCore MachineInstr to 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 XCore MachineInstrs to their
12/// corresponding MCInst records.
13///
14//===----------------------------------------------------------------------===//
15#include "XCoreMCInstLower.h"
16#include "llvm/CodeGen/AsmPrinter.h"
17#include "llvm/CodeGen/MachineFunction.h"
18#include "llvm/CodeGen/MachineInstr.h"
19#include "llvm/CodeGen/MachineOperand.h"
20#include "llvm/IR/Mangler.h"
21#include "llvm/MC/MCContext.h"
22#include "llvm/MC/MCExpr.h"
23#include "llvm/MC/MCInst.h"
24
25using namespace llvm;
26
27XCoreMCInstLower::XCoreMCInstLower(class AsmPrinter &asmprinter)
28: Printer(asmprinter) {}
29
30void XCoreMCInstLower::Initialize(Mangler *M, MCContext *C) {
31  Mang = M;
32  Ctx = C;
33}
34
35MCOperand XCoreMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
36                                               MachineOperandType MOTy,
37                                               unsigned Offset) const {
38  MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
39  const MCSymbol *Symbol;
40
41  switch (MOTy) {
42    case MachineOperand::MO_MachineBasicBlock:
43      Symbol = MO.getMBB()->getSymbol();
44      break;
45    case MachineOperand::MO_GlobalAddress:
46      Symbol = Printer.getSymbol(MO.getGlobal());
47      Offset += MO.getOffset();
48      break;
49    case MachineOperand::MO_BlockAddress:
50      Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress());
51      Offset += MO.getOffset();
52      break;
53    case MachineOperand::MO_ExternalSymbol:
54      Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName());
55      Offset += MO.getOffset();
56      break;
57    case MachineOperand::MO_JumpTableIndex:
58      Symbol = Printer.GetJTISymbol(MO.getIndex());
59      break;
60    case MachineOperand::MO_ConstantPoolIndex:
61      Symbol = Printer.GetCPISymbol(MO.getIndex());
62      Offset += MO.getOffset();
63      break;
64    default:
65      llvm_unreachable("<unknown operand type>");
66  }
67
68  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, Kind, *Ctx);
69
70  if (!Offset)
71    return MCOperand::CreateExpr(MCSym);
72
73  // Assume offset is never negative.
74  assert(Offset > 0);
75
76  const MCConstantExpr *OffsetExpr =  MCConstantExpr::Create(Offset, *Ctx);
77  const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(MCSym, OffsetExpr, *Ctx);
78  return MCOperand::CreateExpr(Add);
79}
80
81MCOperand XCoreMCInstLower::LowerOperand(const MachineOperand &MO,
82                                         unsigned offset) const {
83  MachineOperandType MOTy = MO.getType();
84
85  switch (MOTy) {
86    default: llvm_unreachable("unknown operand type");
87    case MachineOperand::MO_Register:
88      // Ignore all implicit register operands.
89      if (MO.isImplicit()) break;
90      return MCOperand::CreateReg(MO.getReg());
91    case MachineOperand::MO_Immediate:
92      return MCOperand::CreateImm(MO.getImm() + offset);
93    case MachineOperand::MO_MachineBasicBlock:
94    case MachineOperand::MO_GlobalAddress:
95    case MachineOperand::MO_ExternalSymbol:
96    case MachineOperand::MO_JumpTableIndex:
97    case MachineOperand::MO_ConstantPoolIndex:
98    case MachineOperand::MO_BlockAddress:
99      return LowerSymbolOperand(MO, MOTy, offset);
100    case MachineOperand::MO_RegisterMask:
101      break;
102  }
103
104  return MCOperand();
105}
106
107void XCoreMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
108  OutMI.setOpcode(MI->getOpcode());
109
110  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
111    const MachineOperand &MO = MI->getOperand(i);
112    MCOperand MCOp = LowerOperand(MO);
113
114    if (MCOp.isValid())
115      OutMI.addOperand(MCOp);
116  }
117}
118