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