xref: /aosp_15_r20/external/llvm/lib/Target/ARM/ARMMCInstLower.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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