LLVM API Documentation
00001 //===-- PPCMCInstLower.cpp - Convert PPC MachineInstr to an MCInst --------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains code to lower PPC MachineInstrs to their corresponding 00011 // MCInst records. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "PPC.h" 00016 #include "PPCSubtarget.h" 00017 #include "MCTargetDesc/PPCMCExpr.h" 00018 #include "llvm/ADT/SmallString.h" 00019 #include "llvm/ADT/Twine.h" 00020 #include "llvm/CodeGen/AsmPrinter.h" 00021 #include "llvm/CodeGen/MachineFunction.h" 00022 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 00023 #include "llvm/IR/DataLayout.h" 00024 #include "llvm/IR/GlobalValue.h" 00025 #include "llvm/IR/Mangler.h" 00026 #include "llvm/MC/MCAsmInfo.h" 00027 #include "llvm/MC/MCExpr.h" 00028 #include "llvm/MC/MCInst.h" 00029 #include "llvm/Target/TargetLowering.h" 00030 #include "llvm/Target/TargetLoweringObjectFile.h" 00031 using namespace llvm; 00032 00033 static MachineModuleInfoMachO &getMachOMMI(AsmPrinter &AP) { 00034 return AP.MMI->getObjFileInfo<MachineModuleInfoMachO>(); 00035 } 00036 00037 00038 static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){ 00039 const TargetMachine &TM = AP.TM; 00040 Mangler *Mang = AP.Mang; 00041 const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); 00042 MCContext &Ctx = AP.OutContext; 00043 bool isDarwin = TM.getSubtarget<PPCSubtarget>().isDarwin(); 00044 00045 SmallString<128> Name; 00046 StringRef Suffix; 00047 if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB) { 00048 if (isDarwin) 00049 Suffix = "$stub"; 00050 } else if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG) 00051 Suffix = "$non_lazy_ptr"; 00052 00053 if (!Suffix.empty()) 00054 Name += DL->getPrivateGlobalPrefix(); 00055 00056 unsigned PrefixLen = Name.size(); 00057 00058 if (!MO.isGlobal()) { 00059 assert(MO.isSymbol() && "Isn't a symbol reference"); 00060 Mang->getNameWithPrefix(Name, MO.getSymbolName()); 00061 } else { 00062 const GlobalValue *GV = MO.getGlobal(); 00063 TM.getNameWithPrefix(Name, GV, *Mang); 00064 } 00065 00066 unsigned OrigLen = Name.size() - PrefixLen; 00067 00068 Name += Suffix; 00069 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 00070 StringRef OrigName = StringRef(Name).substr(PrefixLen, OrigLen); 00071 00072 // If the target flags on the operand changes the name of the symbol, do that 00073 // before we return the symbol. 00074 if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB && isDarwin) { 00075 MachineModuleInfoImpl::StubValueTy &StubSym = 00076 getMachOMMI(AP).getFnStubEntry(Sym); 00077 if (StubSym.getPointer()) 00078 return Sym; 00079 00080 if (MO.isGlobal()) { 00081 StubSym = 00082 MachineModuleInfoImpl:: 00083 StubValueTy(AP.getSymbol(MO.getGlobal()), 00084 !MO.getGlobal()->hasInternalLinkage()); 00085 } else { 00086 StubSym = 00087 MachineModuleInfoImpl:: 00088 StubValueTy(Ctx.GetOrCreateSymbol(OrigName), false); 00089 } 00090 return Sym; 00091 } 00092 00093 // If the symbol reference is actually to a non_lazy_ptr, not to the symbol, 00094 // then add the suffix. 00095 if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG) { 00096 MachineModuleInfoMachO &MachO = getMachOMMI(AP); 00097 00098 MachineModuleInfoImpl::StubValueTy &StubSym = 00099 (MO.getTargetFlags() & PPCII::MO_NLP_HIDDEN_FLAG) ? 00100 MachO.getHiddenGVStubEntry(Sym) : MachO.getGVStubEntry(Sym); 00101 00102 if (!StubSym.getPointer()) { 00103 assert(MO.isGlobal() && "Extern symbol not handled yet"); 00104 StubSym = MachineModuleInfoImpl:: 00105 StubValueTy(AP.getSymbol(MO.getGlobal()), 00106 !MO.getGlobal()->hasInternalLinkage()); 00107 } 00108 return Sym; 00109 } 00110 00111 return Sym; 00112 } 00113 00114 static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, 00115 AsmPrinter &Printer, bool isDarwin) { 00116 MCContext &Ctx = Printer.OutContext; 00117 MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; 00118 00119 unsigned access = MO.getTargetFlags() & PPCII::MO_ACCESS_MASK; 00120 00121 switch (access) { 00122 case PPCII::MO_TPREL_LO: 00123 RefKind = MCSymbolRefExpr::VK_PPC_TPREL_LO; 00124 break; 00125 case PPCII::MO_TPREL_HA: 00126 RefKind = MCSymbolRefExpr::VK_PPC_TPREL_HA; 00127 break; 00128 case PPCII::MO_DTPREL_LO: 00129 RefKind = MCSymbolRefExpr::VK_PPC_DTPREL_LO; 00130 break; 00131 case PPCII::MO_TLSLD_LO: 00132 RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO; 00133 break; 00134 case PPCII::MO_TOC_LO: 00135 RefKind = MCSymbolRefExpr::VK_PPC_TOC_LO; 00136 break; 00137 case PPCII::MO_TLS: 00138 RefKind = MCSymbolRefExpr::VK_PPC_TLS; 00139 break; 00140 } 00141 00142 if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB && !isDarwin) 00143 RefKind = MCSymbolRefExpr::VK_PLT; 00144 00145 const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx); 00146 00147 if (!MO.isJTI() && MO.getOffset()) 00148 Expr = MCBinaryExpr::CreateAdd(Expr, 00149 MCConstantExpr::Create(MO.getOffset(), Ctx), 00150 Ctx); 00151 00152 // Subtract off the PIC base if required. 00153 if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG) { 00154 const MachineFunction *MF = MO.getParent()->getParent()->getParent(); 00155 00156 const MCExpr *PB = MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), Ctx); 00157 Expr = MCBinaryExpr::CreateSub(Expr, PB, Ctx); 00158 } 00159 00160 // Add ha16() / lo16() markers if required. 00161 switch (access) { 00162 case PPCII::MO_LO: 00163 Expr = PPCMCExpr::CreateLo(Expr, isDarwin, Ctx); 00164 break; 00165 case PPCII::MO_HA: 00166 Expr = PPCMCExpr::CreateHa(Expr, isDarwin, Ctx); 00167 break; 00168 } 00169 00170 return MCOperand::CreateExpr(Expr); 00171 } 00172 00173 void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, 00174 AsmPrinter &AP, bool isDarwin) { 00175 OutMI.setOpcode(MI->getOpcode()); 00176 00177 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 00178 const MachineOperand &MO = MI->getOperand(i); 00179 00180 MCOperand MCOp; 00181 switch (MO.getType()) { 00182 default: 00183 MI->dump(); 00184 llvm_unreachable("unknown operand type"); 00185 case MachineOperand::MO_Register: 00186 assert(!MO.getSubReg() && "Subregs should be eliminated!"); 00187 MCOp = MCOperand::CreateReg(MO.getReg()); 00188 break; 00189 case MachineOperand::MO_Immediate: 00190 MCOp = MCOperand::CreateImm(MO.getImm()); 00191 break; 00192 case MachineOperand::MO_MachineBasicBlock: 00193 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 00194 MO.getMBB()->getSymbol(), AP.OutContext)); 00195 break; 00196 case MachineOperand::MO_GlobalAddress: 00197 case MachineOperand::MO_ExternalSymbol: 00198 MCOp = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP, isDarwin); 00199 break; 00200 case MachineOperand::MO_JumpTableIndex: 00201 MCOp = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP, isDarwin); 00202 break; 00203 case MachineOperand::MO_ConstantPoolIndex: 00204 MCOp = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP, isDarwin); 00205 break; 00206 case MachineOperand::MO_BlockAddress: 00207 MCOp = GetSymbolRef(MO,AP.GetBlockAddressSymbol(MO.getBlockAddress()),AP, 00208 isDarwin); 00209 break; 00210 case MachineOperand::MO_RegisterMask: 00211 continue; 00212 } 00213 00214 OutMI.addOperand(MCOp); 00215 } 00216 }