blob: ca43ef5be620549826d5cd77023d609b179c0ec4 [file] [log] [blame]
Chris Lattner293ef9a2010-11-14 19:53:02 +00001//===-- 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
Chris Lattnera7217c82010-11-14 21:12:33 +000015#include "PPC.h"
Chris Lattner293ef9a2010-11-14 19:53:02 +000016#include "llvm/CodeGen/AsmPrinter.h"
Chris Lattner1e61e692010-11-15 02:46:57 +000017#include "llvm/CodeGen/MachineFunction.h"
Chris Lattnerb9082582010-11-14 23:42:06 +000018#include "llvm/CodeGen/MachineModuleInfoImpls.h"
19#include "llvm/MC/MCAsmInfo.h"
Chris Lattner293ef9a2010-11-14 19:53:02 +000020#include "llvm/MC/MCExpr.h"
21#include "llvm/MC/MCInst.h"
Chris Lattner1520fd62010-11-14 21:20:46 +000022#include "llvm/Target/Mangler.h"
Chris Lattnerb9082582010-11-14 23:42:06 +000023#include "llvm/ADT/SmallString.h"
Chris Lattner293ef9a2010-11-14 19:53:02 +000024using namespace llvm;
25
Chris Lattnerb9082582010-11-14 23:42:06 +000026static 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
Chris Lattner1520fd62010-11-14 21:20:46 +0000114static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
115 AsmPrinter &Printer) {
116 MCContext &Ctx = Printer.OutContext;
Chris Lattnerb9082582010-11-14 23:42:06 +0000117 MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
118
119 const MCExpr *Expr = 0;
Chris Lattner1520fd62010-11-14 21:20:46 +0000120 switch (MO.getTargetFlags()) {
121 default: assert(0 && "Unknown target flag on symbol operand");
Chris Lattnerb9082582010-11-14 23:42:06 +0000122 case PPCII::MO_NO_FLAG:
123 // These affect the name of the symbol, not any suffix.
124 case PPCII::MO_DARWIN_STUB:
Chris Lattner1520fd62010-11-14 21:20:46 +0000125 break;
Chris Lattnerb9082582010-11-14 23:42:06 +0000126
Chris Lattner1e61e692010-11-15 02:46:57 +0000127 case PPCII::MO_LO16: RefKind = MCSymbolRefExpr::VK_PPC_LO16; break;
128 case PPCII::MO_HA16: RefKind = MCSymbolRefExpr::VK_PPC_HA16; break;
129 case PPCII::MO_LO16_PIC: break;
130 case PPCII::MO_HA16_PIC: break;
Chris Lattner1520fd62010-11-14 21:20:46 +0000131 }
Chris Lattnerb9082582010-11-14 23:42:06 +0000132
133 if (Expr == 0)
134 Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx);
135
Chris Lattner1520fd62010-11-14 21:20:46 +0000136 if (!MO.isJTI() && MO.getOffset())
137 Expr = MCBinaryExpr::CreateAdd(Expr,
138 MCConstantExpr::Create(MO.getOffset(), Ctx),
139 Ctx);
Chris Lattner1e61e692010-11-15 02:46:57 +0000140
141 // Subtract off the PIC base.
142 if (MO.getTargetFlags() == PPCII::MO_LO16_PIC ||
143 MO.getTargetFlags() == PPCII::MO_HA16_PIC) {
144 const MachineFunction *MF = MO.getParent()->getParent()->getParent();
145
146 const MCExpr *PB = MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), Ctx);
147 Expr = MCBinaryExpr::CreateSub(Expr, PB, Ctx);
148 // FIXME: We have no way to make the result be VK_PPC_LO16/VK_PPC_HA16,
149 // since it is not a symbol!
150 }
Chris Lattner1520fd62010-11-14 21:20:46 +0000151
Chris Lattner1e61e692010-11-15 02:46:57 +0000152 return MCOperand::CreateExpr(Expr);
Chris Lattner1520fd62010-11-14 21:20:46 +0000153}
154
Chris Lattnera7217c82010-11-14 21:12:33 +0000155void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
Chris Lattner1520fd62010-11-14 21:20:46 +0000156 AsmPrinter &AP) {
Chris Lattner293ef9a2010-11-14 19:53:02 +0000157 OutMI.setOpcode(MI->getOpcode());
158
159 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
160 const MachineOperand &MO = MI->getOperand(i);
161
162 MCOperand MCOp;
163 switch (MO.getType()) {
164 default:
165 MI->dump();
166 assert(0 && "unknown operand type");
167 case MachineOperand::MO_Register:
168 assert(!MO.getSubReg() && "Subregs should be eliminated!");
169 MCOp = MCOperand::CreateReg(MO.getReg());
170 break;
171 case MachineOperand::MO_Immediate:
172 MCOp = MCOperand::CreateImm(MO.getImm());
173 break;
Chris Lattner1520fd62010-11-14 21:20:46 +0000174 case MachineOperand::MO_MachineBasicBlock:
175 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
176 MO.getMBB()->getSymbol(), AP.OutContext));
177 break;
178 case MachineOperand::MO_GlobalAddress:
Chris Lattner1520fd62010-11-14 21:20:46 +0000179 case MachineOperand::MO_ExternalSymbol:
Chris Lattnerb9082582010-11-14 23:42:06 +0000180 MCOp = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP);
Chris Lattner1520fd62010-11-14 21:20:46 +0000181 break;
182 case MachineOperand::MO_JumpTableIndex:
183 MCOp = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP);
184 break;
185 case MachineOperand::MO_ConstantPoolIndex:
186 MCOp = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP);
187 break;
188 case MachineOperand::MO_BlockAddress:
189 MCOp = GetSymbolRef(MO,AP.GetBlockAddressSymbol(MO.getBlockAddress()),AP);
190 break;
Chris Lattner293ef9a2010-11-14 19:53:02 +0000191 }
192
193 OutMI.addOperand(MCOp);
194 }
195}