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 //===----------------------------------------------------------------------===//
15 #include "MCTargetDesc/PPCMCExpr.h"
17 #include "PPCSubtarget.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/Twine.h"
20 #include "llvm/CodeGen/AsmPrinter.h"
21 #include "llvm/CodeGen/MachineFunction.h"
22 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
23 #include "llvm/CodeGen/TargetLowering.h"
24 #include "llvm/CodeGen/TargetLoweringObjectFile.h"
25 #include "llvm/IR/DataLayout.h"
26 #include "llvm/IR/GlobalValue.h"
27 #include "llvm/IR/Mangler.h"
28 #include "llvm/MC/MCAsmInfo.h"
29 #include "llvm/MC/MCExpr.h"
30 #include "llvm/MC/MCInst.h"
33 static MachineModuleInfoMachO
&getMachOMMI(AsmPrinter
&AP
) {
34 return AP
.MMI
->getObjFileInfo
<MachineModuleInfoMachO
>();
37 static MCSymbol
*GetSymbolFromOperand(const MachineOperand
&MO
,
39 const TargetMachine
&TM
= AP
.TM
;
40 Mangler
&Mang
= TM
.getObjFileLowering()->getMangler();
41 const DataLayout
&DL
= AP
.getDataLayout();
42 MCContext
&Ctx
= AP
.OutContext
;
44 SmallString
<128> Name
;
46 if (MO
.getTargetFlags() & PPCII::MO_NLP_FLAG
)
47 Suffix
= "$non_lazy_ptr";
50 Name
+= DL
.getPrivateGlobalPrefix();
53 assert(MO
.isSymbol() && "Isn't a symbol reference");
54 Mangler::getNameWithPrefix(Name
, MO
.getSymbolName(), DL
);
56 const GlobalValue
*GV
= MO
.getGlobal();
57 TM
.getNameWithPrefix(Name
, GV
, Mang
);
61 MCSymbol
*Sym
= Ctx
.getOrCreateSymbol(Name
);
63 // If the symbol reference is actually to a non_lazy_ptr, not to the symbol,
64 // then add the suffix.
65 if (MO
.getTargetFlags() & PPCII::MO_NLP_FLAG
) {
66 MachineModuleInfoMachO
&MachO
= getMachOMMI(AP
);
68 MachineModuleInfoImpl::StubValueTy
&StubSym
= MachO
.getGVStubEntry(Sym
);
70 if (!StubSym
.getPointer()) {
71 assert(MO
.isGlobal() && "Extern symbol not handled yet");
72 StubSym
= MachineModuleInfoImpl::
73 StubValueTy(AP
.getSymbol(MO
.getGlobal()),
74 !MO
.getGlobal()->hasInternalLinkage());
82 static MCOperand
GetSymbolRef(const MachineOperand
&MO
, const MCSymbol
*Symbol
,
83 AsmPrinter
&Printer
, bool isDarwin
) {
84 MCContext
&Ctx
= Printer
.OutContext
;
85 MCSymbolRefExpr::VariantKind RefKind
= MCSymbolRefExpr::VK_None
;
87 unsigned access
= MO
.getTargetFlags() & PPCII::MO_ACCESS_MASK
;
90 case PPCII::MO_TPREL_LO
:
91 RefKind
= MCSymbolRefExpr::VK_PPC_TPREL_LO
;
93 case PPCII::MO_TPREL_HA
:
94 RefKind
= MCSymbolRefExpr::VK_PPC_TPREL_HA
;
96 case PPCII::MO_DTPREL_LO
:
97 RefKind
= MCSymbolRefExpr::VK_PPC_DTPREL_LO
;
99 case PPCII::MO_TLSLD_LO
:
100 RefKind
= MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO
;
102 case PPCII::MO_TOC_LO
:
103 RefKind
= MCSymbolRefExpr::VK_PPC_TOC_LO
;
106 RefKind
= MCSymbolRefExpr::VK_PPC_TLS
;
110 if (MO
.getTargetFlags() == PPCII::MO_PLT
)
111 RefKind
= MCSymbolRefExpr::VK_PLT
;
113 const MCExpr
*Expr
= MCSymbolRefExpr::create(Symbol
, RefKind
, Ctx
);
115 if (!MO
.isJTI() && MO
.getOffset())
116 Expr
= MCBinaryExpr::createAdd(Expr
,
117 MCConstantExpr::create(MO
.getOffset(), Ctx
),
120 // Subtract off the PIC base if required.
121 if (MO
.getTargetFlags() & PPCII::MO_PIC_FLAG
) {
122 const MachineFunction
*MF
= MO
.getParent()->getParent()->getParent();
124 const MCExpr
*PB
= MCSymbolRefExpr::create(MF
->getPICBaseSymbol(), Ctx
);
125 Expr
= MCBinaryExpr::createSub(Expr
, PB
, Ctx
);
128 // Add ha16() / lo16() markers if required.
131 Expr
= PPCMCExpr::createLo(Expr
, isDarwin
, Ctx
);
134 Expr
= PPCMCExpr::createHa(Expr
, isDarwin
, Ctx
);
138 return MCOperand::createExpr(Expr
);
141 void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr
*MI
, MCInst
&OutMI
,
142 AsmPrinter
&AP
, bool isDarwin
) {
143 OutMI
.setOpcode(MI
->getOpcode());
145 for (unsigned i
= 0, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
147 if (LowerPPCMachineOperandToMCOperand(MI
->getOperand(i
), MCOp
, AP
,
149 OutMI
.addOperand(MCOp
);
153 bool llvm::LowerPPCMachineOperandToMCOperand(const MachineOperand
&MO
,
154 MCOperand
&OutMO
, AsmPrinter
&AP
,
156 switch (MO
.getType()) {
158 llvm_unreachable("unknown operand type");
159 case MachineOperand::MO_Register
:
160 assert(!MO
.getSubReg() && "Subregs should be eliminated!");
161 assert(MO
.getReg() > PPC::NoRegister
&&
162 MO
.getReg() < PPC::NUM_TARGET_REGS
&&
163 "Invalid register for this target!");
164 OutMO
= MCOperand::createReg(MO
.getReg());
166 case MachineOperand::MO_Immediate
:
167 OutMO
= MCOperand::createImm(MO
.getImm());
169 case MachineOperand::MO_MachineBasicBlock
:
170 OutMO
= MCOperand::createExpr(
171 MCSymbolRefExpr::create(MO
.getMBB()->getSymbol(), AP
.OutContext
));
173 case MachineOperand::MO_GlobalAddress
:
174 case MachineOperand::MO_ExternalSymbol
:
175 OutMO
= GetSymbolRef(MO
, GetSymbolFromOperand(MO
, AP
), AP
, isDarwin
);
177 case MachineOperand::MO_JumpTableIndex
:
178 OutMO
= GetSymbolRef(MO
, AP
.GetJTISymbol(MO
.getIndex()), AP
, isDarwin
);
180 case MachineOperand::MO_ConstantPoolIndex
:
181 OutMO
= GetSymbolRef(MO
, AP
.GetCPISymbol(MO
.getIndex()), AP
, isDarwin
);
183 case MachineOperand::MO_BlockAddress
:
184 OutMO
= GetSymbolRef(MO
, AP
.GetBlockAddressSymbol(MO
.getBlockAddress()), AP
,
187 case MachineOperand::MO_RegisterMask
: