]>
Commit | Line | Data |
---|---|---|
970d7e83 LB |
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" | |
1a4d82fc | 20 | #include "llvm/IR/Mangler.h" |
970d7e83 LB |
21 | #include "llvm/MC/MCContext.h" |
22 | #include "llvm/MC/MCExpr.h" | |
23 | #include "llvm/MC/MCInst.h" | |
970d7e83 LB |
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: | |
1a4d82fc | 46 | Symbol = Printer.getSymbol(MO.getGlobal()); |
970d7e83 LB |
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 | } |