]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/lib/Target/XCore/XCoreMCInstLower.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / lib / Target / XCore / XCoreMCInstLower.cpp
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/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/Target/Mangler.h"
24
25 using namespace llvm;
26
27 XCoreMCInstLower::XCoreMCInstLower(class AsmPrinter &asmprinter)
28 : Printer(asmprinter) {}
29
30 void XCoreMCInstLower::Initialize(Mangler *M, MCContext *C) {
31   Mang = M;
32   Ctx = C;
33 }
34
35 MCOperand 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 = Mang->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
81 MCOperand 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
107 void 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 }