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