1 //===-- ARMMCInstLower.cpp - Convert ARM 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 ARM MachineInstrs to their corresponding
13 //===----------------------------------------------------------------------===//
16 #include "ARMAsmPrinter.h"
17 #include "ARMMCExpr.h"
18 #include "llvm/Constants.h"
19 #include "llvm/CodeGen/MachineBasicBlock.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/Target/Mangler.h"
26 MCOperand
ARMAsmPrinter::GetSymbolRef(const MachineOperand
&MO
,
27 const MCSymbol
*Symbol
) {
29 switch (MO
.getTargetFlags()) {
31 Expr
= MCSymbolRefExpr::Create(Symbol
, MCSymbolRefExpr::VK_None
,
33 switch (MO
.getTargetFlags()) {
35 assert(0 && "Unknown target flag on symbol operand");
39 Expr
= MCSymbolRefExpr::Create(Symbol
, MCSymbolRefExpr::VK_None
,
41 Expr
= ARMMCExpr::CreateLower16(Expr
, OutContext
);
44 Expr
= MCSymbolRefExpr::Create(Symbol
, MCSymbolRefExpr::VK_None
,
46 Expr
= ARMMCExpr::CreateUpper16(Expr
, OutContext
);
53 Expr
= MCSymbolRefExpr::Create(Symbol
, MCSymbolRefExpr::VK_ARM_PLT
,
58 if (!MO
.isJTI() && MO
.getOffset())
59 Expr
= MCBinaryExpr::CreateAdd(Expr
,
60 MCConstantExpr::Create(MO
.getOffset(),
63 return MCOperand::CreateExpr(Expr
);
67 bool ARMAsmPrinter::lowerOperand(const MachineOperand
&MO
,
69 switch (MO
.getType()) {
71 assert(0 && "unknown operand type");
73 case MachineOperand::MO_Register
:
74 // Ignore all non-CPSR implicit register operands.
75 if (MO
.isImplicit() && MO
.getReg() != ARM::CPSR
)
77 assert(!MO
.getSubReg() && "Subregs should be eliminated!");
78 MCOp
= MCOperand::CreateReg(MO
.getReg());
80 case MachineOperand::MO_Immediate
:
81 MCOp
= MCOperand::CreateImm(MO
.getImm());
83 case MachineOperand::MO_MachineBasicBlock
:
84 MCOp
= MCOperand::CreateExpr(MCSymbolRefExpr::Create(
85 MO
.getMBB()->getSymbol(), OutContext
));
87 case MachineOperand::MO_GlobalAddress
:
88 MCOp
= GetSymbolRef(MO
, Mang
->getSymbol(MO
.getGlobal()));
90 case MachineOperand::MO_ExternalSymbol
:
91 MCOp
= GetSymbolRef(MO
,
92 GetExternalSymbolSymbol(MO
.getSymbolName()));
94 case MachineOperand::MO_JumpTableIndex
:
95 MCOp
= GetSymbolRef(MO
, GetJTISymbol(MO
.getIndex()));
97 case MachineOperand::MO_ConstantPoolIndex
:
98 MCOp
= GetSymbolRef(MO
, GetCPISymbol(MO
.getIndex()));
100 case MachineOperand::MO_BlockAddress
:
101 MCOp
= GetSymbolRef(MO
, GetBlockAddressSymbol(MO
.getBlockAddress()));
103 case MachineOperand::MO_FPImmediate
: {
104 APFloat Val
= MO
.getFPImm()->getValueAPF();
106 Val
.convert(APFloat::IEEEdouble
, APFloat::rmTowardZero
, &ignored
);
107 MCOp
= MCOperand::CreateFPImm(Val
.convertToDouble());
114 void llvm::LowerARMMachineInstrToMCInst(const MachineInstr
*MI
, MCInst
&OutMI
,
116 OutMI
.setOpcode(MI
->getOpcode());
118 for (unsigned i
= 0, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
119 const MachineOperand
&MO
= MI
->getOperand(i
);
122 if (AP
.lowerOperand(MO
, MCOp
))
123 OutMI
.addOperand(MCOp
);