1 //===-- PPCMCInstLower.cpp - Convert PPC MachineInstr to an MCInst --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains code to lower PPC MachineInstrs to their corresponding
13 //===----------------------------------------------------------------------===//
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"
26 static MachineModuleInfoMachO &getMachOMMI(AsmPrinter &AP) {
27 return AP.MMI->getObjFileInfo<MachineModuleInfoMachO>();
31 static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){
32 MCContext &Ctx = AP.OutContext;
34 SmallString<128> Name;
36 assert(MO.isSymbol() && "Isn't a symbol reference");
37 Name += AP.MAI->getGlobalPrefix();
38 Name += MO.getSymbolName();
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
47 isImplicitlyPrivate = true;
49 AP.Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate);
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()) {
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());
62 MachineModuleInfoImpl::StubValueTy &StubSym =
63 getMachOMMI(AP).getGVStubEntry(Sym);
64 if (StubSym.getPointer() == 0) {
65 assert(MO.isGlobal() && "Extern symbol not handled yet");
67 MachineModuleInfoImpl::
68 StubValueTy(Mang->getSymbol(MO.getGlobal()),
69 !MO.getGlobal()->hasInternalLinkage());
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");
81 MachineModuleInfoImpl::
82 StubValueTy(Mang->getSymbol(MO.getGlobal()),
83 !MO.getGlobal()->hasInternalLinkage());
88 case PPCII::MO_DARWIN_STUB: {
90 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
91 MachineModuleInfoImpl::StubValueTy &StubSym =
92 getMachOMMI(AP).getFnStubEntry(Sym);
93 if (StubSym.getPointer())
98 MachineModuleInfoImpl::
99 StubValueTy(AP.Mang->getSymbol(MO.getGlobal()),
100 !MO.getGlobal()->hasInternalLinkage());
102 Name.erase(Name.end()-5, Name.end());
104 MachineModuleInfoImpl::
105 StubValueTy(Ctx.GetOrCreateSymbol(Name.str()), false);
111 return Ctx.GetOrCreateSymbol(Name.str());
114 static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
115 AsmPrinter &Printer) {
116 MCContext &Ctx = Printer.OutContext;
117 MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
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:
129 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_LO16, Ctx);
135 Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx);
138 if (!MO.isJTI() && MO.getOffset())
139 Expr = MCBinaryExpr::CreateAdd(Expr,
140 MCConstantExpr::Create(MO.getOffset(), Ctx),
142 return MCOperand::CreateExpr(Expr);
146 void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
148 OutMI.setOpcode(MI->getOpcode());
150 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
151 const MachineOperand &MO = MI->getOperand(i);
154 switch (MO.getType()) {
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());
162 case MachineOperand::MO_Immediate:
163 MCOp = MCOperand::CreateImm(MO.getImm());
165 case MachineOperand::MO_MachineBasicBlock:
166 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
167 MO.getMBB()->getSymbol(), AP.OutContext));
169 case MachineOperand::MO_GlobalAddress:
170 case MachineOperand::MO_ExternalSymbol:
171 MCOp = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP);
173 case MachineOperand::MO_JumpTableIndex:
174 MCOp = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP);
176 case MachineOperand::MO_ConstantPoolIndex:
177 MCOp = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP);
179 case MachineOperand::MO_BlockAddress:
180 MCOp = GetSymbolRef(MO,AP.GetBlockAddressSymbol(MO.getBlockAddress()),AP);
184 OutMI.addOperand(MCOp);