1*9880d681SAndroid Build Coastguard Worker //===-- ARMMCInstLower.cpp - Convert ARM MachineInstr to an MCInst --------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains code to lower ARM MachineInstrs to their corresponding
11*9880d681SAndroid Build Coastguard Worker // MCInst records.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "ARM.h"
16*9880d681SAndroid Build Coastguard Worker #include "ARMAsmPrinter.h"
17*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/ARMBaseInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/ARMMCExpr.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBasicBlock.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
24*9880d681SAndroid Build Coastguard Worker using namespace llvm;
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker
GetSymbolRef(const MachineOperand & MO,const MCSymbol * Symbol)27*9880d681SAndroid Build Coastguard Worker MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
28*9880d681SAndroid Build Coastguard Worker const MCSymbol *Symbol) {
29*9880d681SAndroid Build Coastguard Worker const MCExpr *Expr =
30*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(Symbol, MCSymbolRefExpr::VK_None, OutContext);
31*9880d681SAndroid Build Coastguard Worker switch (MO.getTargetFlags() & ARMII::MO_OPTION_MASK) {
32*9880d681SAndroid Build Coastguard Worker default:
33*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unknown target flag on symbol operand");
34*9880d681SAndroid Build Coastguard Worker case ARMII::MO_NO_FLAG:
35*9880d681SAndroid Build Coastguard Worker break;
36*9880d681SAndroid Build Coastguard Worker case ARMII::MO_LO16:
37*9880d681SAndroid Build Coastguard Worker Expr =
38*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(Symbol, MCSymbolRefExpr::VK_None, OutContext);
39*9880d681SAndroid Build Coastguard Worker Expr = ARMMCExpr::createLower16(Expr, OutContext);
40*9880d681SAndroid Build Coastguard Worker break;
41*9880d681SAndroid Build Coastguard Worker case ARMII::MO_HI16:
42*9880d681SAndroid Build Coastguard Worker Expr =
43*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(Symbol, MCSymbolRefExpr::VK_None, OutContext);
44*9880d681SAndroid Build Coastguard Worker Expr = ARMMCExpr::createUpper16(Expr, OutContext);
45*9880d681SAndroid Build Coastguard Worker break;
46*9880d681SAndroid Build Coastguard Worker }
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker if (!MO.isJTI() && MO.getOffset())
49*9880d681SAndroid Build Coastguard Worker Expr = MCBinaryExpr::createAdd(Expr,
50*9880d681SAndroid Build Coastguard Worker MCConstantExpr::create(MO.getOffset(),
51*9880d681SAndroid Build Coastguard Worker OutContext),
52*9880d681SAndroid Build Coastguard Worker OutContext);
53*9880d681SAndroid Build Coastguard Worker return MCOperand::createExpr(Expr);
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker }
56*9880d681SAndroid Build Coastguard Worker
lowerOperand(const MachineOperand & MO,MCOperand & MCOp)57*9880d681SAndroid Build Coastguard Worker bool ARMAsmPrinter::lowerOperand(const MachineOperand &MO,
58*9880d681SAndroid Build Coastguard Worker MCOperand &MCOp) {
59*9880d681SAndroid Build Coastguard Worker switch (MO.getType()) {
60*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("unknown operand type");
61*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_Register:
62*9880d681SAndroid Build Coastguard Worker // Ignore all non-CPSR implicit register operands.
63*9880d681SAndroid Build Coastguard Worker if (MO.isImplicit() && MO.getReg() != ARM::CPSR)
64*9880d681SAndroid Build Coastguard Worker return false;
65*9880d681SAndroid Build Coastguard Worker assert(!MO.getSubReg() && "Subregs should be eliminated!");
66*9880d681SAndroid Build Coastguard Worker MCOp = MCOperand::createReg(MO.getReg());
67*9880d681SAndroid Build Coastguard Worker break;
68*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_Immediate:
69*9880d681SAndroid Build Coastguard Worker MCOp = MCOperand::createImm(MO.getImm());
70*9880d681SAndroid Build Coastguard Worker break;
71*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_MachineBasicBlock:
72*9880d681SAndroid Build Coastguard Worker MCOp = MCOperand::createExpr(MCSymbolRefExpr::create(
73*9880d681SAndroid Build Coastguard Worker MO.getMBB()->getSymbol(), OutContext));
74*9880d681SAndroid Build Coastguard Worker break;
75*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_GlobalAddress: {
76*9880d681SAndroid Build Coastguard Worker MCOp = GetSymbolRef(MO,
77*9880d681SAndroid Build Coastguard Worker GetARMGVSymbol(MO.getGlobal(), MO.getTargetFlags()));
78*9880d681SAndroid Build Coastguard Worker break;
79*9880d681SAndroid Build Coastguard Worker }
80*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_ExternalSymbol:
81*9880d681SAndroid Build Coastguard Worker MCOp = GetSymbolRef(MO,
82*9880d681SAndroid Build Coastguard Worker GetExternalSymbolSymbol(MO.getSymbolName()));
83*9880d681SAndroid Build Coastguard Worker break;
84*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_JumpTableIndex:
85*9880d681SAndroid Build Coastguard Worker MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex()));
86*9880d681SAndroid Build Coastguard Worker break;
87*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_ConstantPoolIndex:
88*9880d681SAndroid Build Coastguard Worker MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex()));
89*9880d681SAndroid Build Coastguard Worker break;
90*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_BlockAddress:
91*9880d681SAndroid Build Coastguard Worker MCOp = GetSymbolRef(MO, GetBlockAddressSymbol(MO.getBlockAddress()));
92*9880d681SAndroid Build Coastguard Worker break;
93*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_FPImmediate: {
94*9880d681SAndroid Build Coastguard Worker APFloat Val = MO.getFPImm()->getValueAPF();
95*9880d681SAndroid Build Coastguard Worker bool ignored;
96*9880d681SAndroid Build Coastguard Worker Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
97*9880d681SAndroid Build Coastguard Worker MCOp = MCOperand::createFPImm(Val.convertToDouble());
98*9880d681SAndroid Build Coastguard Worker break;
99*9880d681SAndroid Build Coastguard Worker }
100*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_RegisterMask:
101*9880d681SAndroid Build Coastguard Worker // Ignore call clobbers.
102*9880d681SAndroid Build Coastguard Worker return false;
103*9880d681SAndroid Build Coastguard Worker }
104*9880d681SAndroid Build Coastguard Worker return true;
105*9880d681SAndroid Build Coastguard Worker }
106*9880d681SAndroid Build Coastguard Worker
LowerARMMachineInstrToMCInst(const MachineInstr * MI,MCInst & OutMI,ARMAsmPrinter & AP)107*9880d681SAndroid Build Coastguard Worker void llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
108*9880d681SAndroid Build Coastguard Worker ARMAsmPrinter &AP) {
109*9880d681SAndroid Build Coastguard Worker OutMI.setOpcode(MI->getOpcode());
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker // In the MC layer, we keep modified immediates in their encoded form
112*9880d681SAndroid Build Coastguard Worker bool EncodeImms = false;
113*9880d681SAndroid Build Coastguard Worker switch (MI->getOpcode()) {
114*9880d681SAndroid Build Coastguard Worker default: break;
115*9880d681SAndroid Build Coastguard Worker case ARM::MOVi:
116*9880d681SAndroid Build Coastguard Worker case ARM::MVNi:
117*9880d681SAndroid Build Coastguard Worker case ARM::CMPri:
118*9880d681SAndroid Build Coastguard Worker case ARM::CMNri:
119*9880d681SAndroid Build Coastguard Worker case ARM::TSTri:
120*9880d681SAndroid Build Coastguard Worker case ARM::TEQri:
121*9880d681SAndroid Build Coastguard Worker case ARM::MSRi:
122*9880d681SAndroid Build Coastguard Worker case ARM::ADCri:
123*9880d681SAndroid Build Coastguard Worker case ARM::ADDri:
124*9880d681SAndroid Build Coastguard Worker case ARM::ADDSri:
125*9880d681SAndroid Build Coastguard Worker case ARM::SBCri:
126*9880d681SAndroid Build Coastguard Worker case ARM::SUBri:
127*9880d681SAndroid Build Coastguard Worker case ARM::SUBSri:
128*9880d681SAndroid Build Coastguard Worker case ARM::ANDri:
129*9880d681SAndroid Build Coastguard Worker case ARM::ORRri:
130*9880d681SAndroid Build Coastguard Worker case ARM::EORri:
131*9880d681SAndroid Build Coastguard Worker case ARM::BICri:
132*9880d681SAndroid Build Coastguard Worker case ARM::RSBri:
133*9880d681SAndroid Build Coastguard Worker case ARM::RSBSri:
134*9880d681SAndroid Build Coastguard Worker case ARM::RSCri:
135*9880d681SAndroid Build Coastguard Worker EncodeImms = true;
136*9880d681SAndroid Build Coastguard Worker break;
137*9880d681SAndroid Build Coastguard Worker }
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
140*9880d681SAndroid Build Coastguard Worker const MachineOperand &MO = MI->getOperand(i);
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker MCOperand MCOp;
143*9880d681SAndroid Build Coastguard Worker if (AP.lowerOperand(MO, MCOp)) {
144*9880d681SAndroid Build Coastguard Worker if (MCOp.isImm() && EncodeImms) {
145*9880d681SAndroid Build Coastguard Worker int32_t Enc = ARM_AM::getSOImmVal(MCOp.getImm());
146*9880d681SAndroid Build Coastguard Worker if (Enc != -1)
147*9880d681SAndroid Build Coastguard Worker MCOp.setImm(Enc);
148*9880d681SAndroid Build Coastguard Worker }
149*9880d681SAndroid Build Coastguard Worker OutMI.addOperand(MCOp);
150*9880d681SAndroid Build Coastguard Worker }
151*9880d681SAndroid Build Coastguard Worker }
152*9880d681SAndroid Build Coastguard Worker }
153