1 //===-- MSP430MCInstLower.cpp - Convert MSP430 MachineInstr to an MCInst---===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains code to lower MSP430 MachineInstrs to their corresponding
13 //===----------------------------------------------------------------------===//
15 #include "MSP430MCInstLower.h"
16 #include "llvm/CodeGen/AsmPrinter.h"
17 #include "llvm/CodeGen/MachineBasicBlock.h"
18 #include "llvm/CodeGen/MachineInstr.h"
19 #include "llvm/MC/MCAsmInfo.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 #include "llvm/Support/raw_ostream.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/ADT/SmallString.h"
29 MCSymbol
*MSP430MCInstLower::
30 GetGlobalAddressSymbol(const MachineOperand
&MO
) const {
31 switch (MO
.getTargetFlags()) {
32 default: llvm_unreachable("Unknown target flag on GV operand");
36 return Printer
.Mang
->getSymbol(MO
.getGlobal());
39 MCSymbol
*MSP430MCInstLower::
40 GetExternalSymbolSymbol(const MachineOperand
&MO
) const {
41 switch (MO
.getTargetFlags()) {
42 default: assert(0 && "Unknown target flag on GV operand");
46 return Printer
.GetExternalSymbolSymbol(MO
.getSymbolName());
49 MCSymbol
*MSP430MCInstLower::
50 GetJumpTableSymbol(const MachineOperand
&MO
) const {
51 SmallString
<256> Name
;
52 raw_svector_ostream(Name
) << Printer
.MAI
->getPrivateGlobalPrefix() << "JTI"
53 << Printer
.getFunctionNumber() << '_'
56 switch (MO
.getTargetFlags()) {
57 default: llvm_unreachable("Unknown target flag on GV operand");
61 // Create a symbol for the name.
62 return Ctx
.GetOrCreateSymbol(Name
.str());
65 MCSymbol
*MSP430MCInstLower::
66 GetConstantPoolIndexSymbol(const MachineOperand
&MO
) const {
67 SmallString
<256> Name
;
68 raw_svector_ostream(Name
) << Printer
.MAI
->getPrivateGlobalPrefix() << "CPI"
69 << Printer
.getFunctionNumber() << '_'
72 switch (MO
.getTargetFlags()) {
73 default: llvm_unreachable("Unknown target flag on GV operand");
77 // Create a symbol for the name.
78 return Ctx
.GetOrCreateSymbol(Name
.str());
81 MCSymbol
*MSP430MCInstLower::
82 GetBlockAddressSymbol(const MachineOperand
&MO
) const {
83 switch (MO
.getTargetFlags()) {
84 default: assert(0 && "Unknown target flag on GV operand");
88 return Printer
.GetBlockAddressSymbol(MO
.getBlockAddress());
91 MCOperand
MSP430MCInstLower::
92 LowerSymbolOperand(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
);
97 switch (MO
.getTargetFlags()) {
98 default: llvm_unreachable("Unknown target flag on GV operand");
102 if (!MO
.isJTI() && MO
.getOffset())
103 Expr
= MCBinaryExpr::CreateAdd(Expr
,
104 MCConstantExpr::Create(MO
.getOffset(), Ctx
),
106 return MCOperand::CreateExpr(Expr
);
109 void MSP430MCInstLower::Lower(const MachineInstr
*MI
, MCInst
&OutMI
) const {
110 OutMI
.setOpcode(MI
->getOpcode());
112 for (unsigned i
= 0, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
113 const MachineOperand
&MO
= MI
->getOperand(i
);
116 switch (MO
.getType()) {
119 assert(0 && "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());
125 case MachineOperand::MO_Immediate
:
126 MCOp
= MCOperand::CreateImm(MO
.getImm());
128 case MachineOperand::MO_MachineBasicBlock
:
129 MCOp
= MCOperand::CreateExpr(MCSymbolRefExpr::Create(
130 MO
.getMBB()->getSymbol(), Ctx
));
132 case MachineOperand::MO_GlobalAddress
:
133 MCOp
= LowerSymbolOperand(MO
, GetGlobalAddressSymbol(MO
));
135 case MachineOperand::MO_ExternalSymbol
:
136 MCOp
= LowerSymbolOperand(MO
, GetExternalSymbolSymbol(MO
));
138 case MachineOperand::MO_JumpTableIndex
:
139 MCOp
= LowerSymbolOperand(MO
, GetJumpTableSymbol(MO
));
141 case MachineOperand::MO_ConstantPoolIndex
:
142 MCOp
= LowerSymbolOperand(MO
, GetConstantPoolIndexSymbol(MO
));
144 case MachineOperand::MO_BlockAddress
:
145 MCOp
= LowerSymbolOperand(MO
, GetBlockAddressSymbol(MO
));
148 OutMI
.addOperand(MCOp
);