blob: f7a9ba9cdfcfecde156793dc74ea7f9b16107e37 [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"
17#include "llvm/CodeGen/MachineBasicBlock.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 Lattner1520fd62010-11-14 21:20:46 +0000127#if 0
Chris Lattnerb9082582010-11-14 23:42:06 +0000128 case PPCII::MO_LO16:
Chris Lattner1520fd62010-11-14 21:20:46 +0000129 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_LO16, Ctx);
130 break;
131#endif
132 }
Chris Lattnerb9082582010-11-14 23:42:06 +0000133
134 if (Expr == 0)
135 Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx);
136
Chris Lattner1520fd62010-11-14 21:20:46 +0000137
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
Chris Lattnera7217c82010-11-14 21:12:33 +0000146void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
Chris Lattner1520fd62010-11-14 21:20:46 +0000147 AsmPrinter &AP) {
Chris Lattner293ef9a2010-11-14 19:53:02 +0000148 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;
Chris Lattner1520fd62010-11-14 21:20:46 +0000165 case MachineOperand::MO_MachineBasicBlock:
166 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
167 MO.getMBB()->getSymbol(), AP.OutContext));
168 break;
169 case MachineOperand::MO_GlobalAddress:
Chris Lattner1520fd62010-11-14 21:20:46 +0000170 case MachineOperand::MO_ExternalSymbol:
Chris Lattnerb9082582010-11-14 23:42:06 +0000171 MCOp = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP);
Chris Lattner1520fd62010-11-14 21:20:46 +0000172 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;
Chris Lattner293ef9a2010-11-14 19:53:02 +0000182 }
183
184 OutMI.addOperand(MCOp);
185 }
186}