1 //===-- PPCMCInstLower.cpp - Convert PPC 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 PPC MachineInstrs to their corresponding 11 // MCInst records. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "MCTargetDesc/PPCMCExpr.h" 16 #include "PPC.h" 17 #include "PPCSubtarget.h" 18 #include "llvm/ADT/SmallString.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/CodeGen/AsmPrinter.h" 21 #include "llvm/CodeGen/MachineFunction.h" 22 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 23 #include "llvm/CodeGen/TargetLowering.h" 24 #include "llvm/IR/DataLayout.h" 25 #include "llvm/IR/GlobalValue.h" 26 #include "llvm/IR/Mangler.h" 27 #include "llvm/MC/MCAsmInfo.h" 28 #include "llvm/MC/MCExpr.h" 29 #include "llvm/MC/MCInst.h" 30 #include "llvm/Target/TargetLoweringObjectFile.h" 31 using namespace llvm; 32 33 static MachineModuleInfoMachO &getMachOMMI(AsmPrinter &AP) { 34 return AP.MMI->getObjFileInfo<MachineModuleInfoMachO>(); 35 } 36 37 static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, 38 AsmPrinter &AP) { 39 const TargetMachine &TM = AP.TM; 40 Mangler &Mang = TM.getObjFileLowering()->getMangler(); 41 const DataLayout &DL = AP.getDataLayout(); 42 MCContext &Ctx = AP.OutContext; 43 44 SmallString<128> Name; 45 StringRef Suffix; 46 if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG) 47 Suffix = "$non_lazy_ptr"; 48 49 if (!Suffix.empty()) 50 Name += DL.getPrivateGlobalPrefix(); 51 52 if (!MO.isGlobal()) { 53 assert(MO.isSymbol() && "Isn't a symbol reference"); 54 Mangler::getNameWithPrefix(Name, MO.getSymbolName(), DL); 55 } else { 56 const GlobalValue *GV = MO.getGlobal(); 57 TM.getNameWithPrefix(Name, GV, Mang); 58 } 59 60 Name += Suffix; 61 MCSymbol *Sym = Ctx.getOrCreateSymbol(Name); 62 63 // If the symbol reference is actually to a non_lazy_ptr, not to the symbol, 64 // then add the suffix. 65 if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG) { 66 MachineModuleInfoMachO &MachO = getMachOMMI(AP); 67 68 MachineModuleInfoImpl::StubValueTy &StubSym = MachO.getGVStubEntry(Sym); 69 70 if (!StubSym.getPointer()) { 71 assert(MO.isGlobal() && "Extern symbol not handled yet"); 72 StubSym = MachineModuleInfoImpl:: 73 StubValueTy(AP.getSymbol(MO.getGlobal()), 74 !MO.getGlobal()->hasInternalLinkage()); 75 } 76 return Sym; 77 } 78 79 return Sym; 80 } 81 82 static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, 83 AsmPrinter &Printer, bool isDarwin) { 84 MCContext &Ctx = Printer.OutContext; 85 MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; 86 87 unsigned access = MO.getTargetFlags() & PPCII::MO_ACCESS_MASK; 88 89 switch (access) { 90 case PPCII::MO_TPREL_LO: 91 RefKind = MCSymbolRefExpr::VK_PPC_TPREL_LO; 92 break; 93 case PPCII::MO_TPREL_HA: 94 RefKind = MCSymbolRefExpr::VK_PPC_TPREL_HA; 95 break; 96 case PPCII::MO_DTPREL_LO: 97 RefKind = MCSymbolRefExpr::VK_PPC_DTPREL_LO; 98 break; 99 case PPCII::MO_TLSLD_LO: 100 RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO; 101 break; 102 case PPCII::MO_TOC_LO: 103 RefKind = MCSymbolRefExpr::VK_PPC_TOC_LO; 104 break; 105 case PPCII::MO_TLS: 106 RefKind = MCSymbolRefExpr::VK_PPC_TLS; 107 break; 108 } 109 110 if (MO.getTargetFlags() == PPCII::MO_PLT) 111 RefKind = MCSymbolRefExpr::VK_PLT; 112 113 const MachineFunction *MF = MO.getParent()->getParent()->getParent(); 114 const PPCSubtarget *Subtarget = &(MF->getSubtarget<PPCSubtarget>()); 115 const TargetMachine &TM = Printer.TM; 116 const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, RefKind, Ctx); 117 // -msecure-plt option works only in PIC mode. If secure plt mode 118 // is on add 32768 to symbol. 119 if (Subtarget->isSecurePlt() && TM.isPositionIndependent() && 120 MO.getTargetFlags() == PPCII::MO_PLT) 121 Expr = MCBinaryExpr::createAdd(Expr, 122 MCConstantExpr::create(32768, Ctx), 123 Ctx); 124 125 if (!MO.isJTI() && MO.getOffset()) 126 Expr = MCBinaryExpr::createAdd(Expr, 127 MCConstantExpr::create(MO.getOffset(), Ctx), 128 Ctx); 129 130 // Subtract off the PIC base if required. 131 if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG) { 132 const MachineFunction *MF = MO.getParent()->getParent()->getParent(); 133 134 const MCExpr *PB = MCSymbolRefExpr::create(MF->getPICBaseSymbol(), Ctx); 135 Expr = MCBinaryExpr::createSub(Expr, PB, Ctx); 136 } 137 138 // Add ha16() / lo16() markers if required. 139 switch (access) { 140 case PPCII::MO_LO: 141 Expr = PPCMCExpr::createLo(Expr, isDarwin, Ctx); 142 break; 143 case PPCII::MO_HA: 144 Expr = PPCMCExpr::createHa(Expr, isDarwin, Ctx); 145 break; 146 } 147 148 return MCOperand::createExpr(Expr); 149 } 150 151 void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, 152 AsmPrinter &AP, bool isDarwin) { 153 OutMI.setOpcode(MI->getOpcode()); 154 155 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 156 MCOperand MCOp; 157 if (LowerPPCMachineOperandToMCOperand(MI->getOperand(i), MCOp, AP, 158 isDarwin)) 159 OutMI.addOperand(MCOp); 160 } 161 } 162 163 bool llvm::LowerPPCMachineOperandToMCOperand(const MachineOperand &MO, 164 MCOperand &OutMO, AsmPrinter &AP, 165 bool isDarwin) { 166 switch (MO.getType()) { 167 default: 168 llvm_unreachable("unknown operand type"); 169 case MachineOperand::MO_Register: 170 assert(!MO.getSubReg() && "Subregs should be eliminated!"); 171 assert(MO.getReg() > PPC::NoRegister && 172 MO.getReg() < PPC::NUM_TARGET_REGS && 173 "Invalid register for this target!"); 174 OutMO = MCOperand::createReg(MO.getReg()); 175 return true; 176 case MachineOperand::MO_Immediate: 177 OutMO = MCOperand::createImm(MO.getImm()); 178 return true; 179 case MachineOperand::MO_MachineBasicBlock: 180 OutMO = MCOperand::createExpr( 181 MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), AP.OutContext)); 182 return true; 183 case MachineOperand::MO_GlobalAddress: 184 case MachineOperand::MO_ExternalSymbol: 185 OutMO = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP, isDarwin); 186 return true; 187 case MachineOperand::MO_JumpTableIndex: 188 OutMO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP, isDarwin); 189 return true; 190 case MachineOperand::MO_ConstantPoolIndex: 191 OutMO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP, isDarwin); 192 return true; 193 case MachineOperand::MO_BlockAddress: 194 OutMO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP, 195 isDarwin); 196 return true; 197 case MachineOperand::MO_RegisterMask: 198 return false; 199 } 200 } 201