PPCMCInstLower.cpp revision b908258d59745ab9f150c66f94541951cf9c9211
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 "PPC.h" 16#include "llvm/CodeGen/AsmPrinter.h" 17#include "llvm/CodeGen/MachineBasicBlock.h" 18#include "llvm/CodeGen/MachineModuleInfoImpls.h" 19#include "llvm/MC/MCAsmInfo.h" 20#include "llvm/MC/MCExpr.h" 21#include "llvm/MC/MCInst.h" 22#include "llvm/Target/Mangler.h" 23#include "llvm/ADT/SmallString.h" 24using namespace llvm; 25 26static MachineModuleInfoMachO &getMachOMMI(AsmPrinter &AP) { 27 return AP.MMI->getObjFileInfo<MachineModuleInfoMachO>(); 28} 29 30 31static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){ 32 MCContext &Ctx = AP.OutContext; 33 34 SmallString<128> Name; 35 if (!MO.isGlobal()) { 36 assert(MO.isSymbol() && "Isn't a symbol reference"); 37 Name += AP.MAI->getGlobalPrefix(); 38 Name += MO.getSymbolName(); 39 } else { 40 const GlobalValue *GV = MO.getGlobal(); 41 bool isImplicitlyPrivate = false; 42 if (MO.getTargetFlags() == PPCII::MO_DARWIN_STUB || 43 //MO.getTargetFlags() == PPCII::MO_DARWIN_NONLAZY || 44 //MO.getTargetFlags() == PPCII::MO_DARWIN_NONLAZY_PIC_BASE || 45 //MO.getTargetFlags() == PPCII::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE 46 0) 47 isImplicitlyPrivate = true; 48 49 AP.Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate); 50 } 51 52 // If the target flags on the operand changes the name of the symbol, do that 53 // before we return the symbol. 54 switch (MO.getTargetFlags()) { 55 default: break; 56#if 0 57 case X86II::MO_DARWIN_NONLAZY: 58 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: { 59 Name += "$non_lazy_ptr"; 60 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 61 62 MachineModuleInfoImpl::StubValueTy &StubSym = 63 getMachOMMI(AP).getGVStubEntry(Sym); 64 if (StubSym.getPointer() == 0) { 65 assert(MO.isGlobal() && "Extern symbol not handled yet"); 66 StubSym = 67 MachineModuleInfoImpl:: 68 StubValueTy(Mang->getSymbol(MO.getGlobal()), 69 !MO.getGlobal()->hasInternalLinkage()); 70 } 71 return Sym; 72 } 73 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: { 74 Name += "$non_lazy_ptr"; 75 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 76 MachineModuleInfoImpl::StubValueTy &StubSym = 77 getMachOMMI(AP).getHiddenGVStubEntry(Sym); 78 if (StubSym.getPointer() == 0) { 79 assert(MO.isGlobal() && "Extern symbol not handled yet"); 80 StubSym = 81 MachineModuleInfoImpl:: 82 StubValueTy(Mang->getSymbol(MO.getGlobal()), 83 !MO.getGlobal()->hasInternalLinkage()); 84 } 85 return Sym; 86 } 87#endif 88 case PPCII::MO_DARWIN_STUB: { 89 Name += "$stub"; 90 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 91 MachineModuleInfoImpl::StubValueTy &StubSym = 92 getMachOMMI(AP).getFnStubEntry(Sym); 93 if (StubSym.getPointer()) 94 return Sym; 95 96 if (MO.isGlobal()) { 97 StubSym = 98 MachineModuleInfoImpl:: 99 StubValueTy(AP.Mang->getSymbol(MO.getGlobal()), 100 !MO.getGlobal()->hasInternalLinkage()); 101 } else { 102 Name.erase(Name.end()-5, Name.end()); 103 StubSym = 104 MachineModuleInfoImpl:: 105 StubValueTy(Ctx.GetOrCreateSymbol(Name.str()), false); 106 } 107 return Sym; 108 } 109 } 110 111 return Ctx.GetOrCreateSymbol(Name.str()); 112} 113 114static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, 115 AsmPrinter &Printer) { 116 MCContext &Ctx = Printer.OutContext; 117 MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; 118 119 const MCExpr *Expr = 0; 120 switch (MO.getTargetFlags()) { 121 default: assert(0 && "Unknown target flag on symbol operand"); 122 case PPCII::MO_NO_FLAG: 123 // These affect the name of the symbol, not any suffix. 124 case PPCII::MO_DARWIN_STUB: 125 break; 126 127#if 0 128 case PPCII::MO_LO16: 129 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_LO16, Ctx); 130 break; 131#endif 132 } 133 134 if (Expr == 0) 135 Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx); 136 137 138 if (!MO.isJTI() && MO.getOffset()) 139 Expr = MCBinaryExpr::CreateAdd(Expr, 140 MCConstantExpr::Create(MO.getOffset(), Ctx), 141 Ctx); 142 return MCOperand::CreateExpr(Expr); 143 144} 145 146void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, 147 AsmPrinter &AP) { 148 OutMI.setOpcode(MI->getOpcode()); 149 150 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 151 const MachineOperand &MO = MI->getOperand(i); 152 153 MCOperand MCOp; 154 switch (MO.getType()) { 155 default: 156 MI->dump(); 157 assert(0 && "unknown operand type"); 158 case MachineOperand::MO_Register: 159 assert(!MO.getSubReg() && "Subregs should be eliminated!"); 160 MCOp = MCOperand::CreateReg(MO.getReg()); 161 break; 162 case MachineOperand::MO_Immediate: 163 MCOp = MCOperand::CreateImm(MO.getImm()); 164 break; 165 case MachineOperand::MO_MachineBasicBlock: 166 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 167 MO.getMBB()->getSymbol(), AP.OutContext)); 168 break; 169 case MachineOperand::MO_GlobalAddress: 170 case MachineOperand::MO_ExternalSymbol: 171 MCOp = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP); 172 break; 173 case MachineOperand::MO_JumpTableIndex: 174 MCOp = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP); 175 break; 176 case MachineOperand::MO_ConstantPoolIndex: 177 MCOp = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP); 178 break; 179 case MachineOperand::MO_BlockAddress: 180 MCOp = GetSymbolRef(MO,AP.GetBlockAddressSymbol(MO.getBlockAddress()),AP); 181 break; 182 } 183 184 OutMI.addOperand(MCOp); 185 } 186} 187