1 //===-- PPCMCInstLower.cpp - Convert PPC MachineInstr to an MCInst --------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains code to lower PPC MachineInstrs to their corresponding
12 //===----------------------------------------------------------------------===//
14 #include "MCTargetDesc/PPCMCExpr.h"
16 #include "PPCSubtarget.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/Twine.h"
19 #include "llvm/CodeGen/AsmPrinter.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
22 #include "llvm/CodeGen/TargetLowering.h"
23 #include "llvm/IR/DataLayout.h"
24 #include "llvm/IR/GlobalValue.h"
25 #include "llvm/IR/Mangler.h"
26 #include "llvm/MC/MCAsmInfo.h"
27 #include "llvm/MC/MCExpr.h"
28 #include "llvm/MC/MCInst.h"
29 #include "llvm/Target/TargetLoweringObjectFile.h"
32 static MachineModuleInfoMachO
&getMachOMMI(AsmPrinter
&AP
) {
33 return AP
.MMI
->getObjFileInfo
<MachineModuleInfoMachO
>();
36 static MCSymbol
*GetSymbolFromOperand(const MachineOperand
&MO
,
38 const TargetMachine
&TM
= AP
.TM
;
39 Mangler
&Mang
= TM
.getObjFileLowering()->getMangler();
40 const DataLayout
&DL
= AP
.getDataLayout();
41 MCContext
&Ctx
= AP
.OutContext
;
43 SmallString
<128> Name
;
45 if (MO
.getTargetFlags() & PPCII::MO_NLP_FLAG
)
46 Suffix
= "$non_lazy_ptr";
49 Name
+= DL
.getPrivateGlobalPrefix();
52 assert(MO
.isSymbol() && "Isn't a symbol reference");
53 Mangler::getNameWithPrefix(Name
, MO
.getSymbolName(), DL
);
55 const GlobalValue
*GV
= MO
.getGlobal();
56 TM
.getNameWithPrefix(Name
, GV
, Mang
);
60 MCSymbol
*Sym
= Ctx
.getOrCreateSymbol(Name
);
62 // If the symbol reference is actually to a non_lazy_ptr, not to the symbol,
63 // then add the suffix.
64 if (MO
.getTargetFlags() & PPCII::MO_NLP_FLAG
) {
65 MachineModuleInfoMachO
&MachO
= getMachOMMI(AP
);
67 MachineModuleInfoImpl::StubValueTy
&StubSym
= MachO
.getGVStubEntry(Sym
);
69 if (!StubSym
.getPointer()) {
70 assert(MO
.isGlobal() && "Extern symbol not handled yet");
71 StubSym
= MachineModuleInfoImpl::
72 StubValueTy(AP
.getSymbol(MO
.getGlobal()),
73 !MO
.getGlobal()->hasInternalLinkage());
81 static MCOperand
GetSymbolRef(const MachineOperand
&MO
, const MCSymbol
*Symbol
,
82 AsmPrinter
&Printer
, bool IsDarwin
) {
83 MCContext
&Ctx
= Printer
.OutContext
;
84 MCSymbolRefExpr::VariantKind RefKind
= MCSymbolRefExpr::VK_None
;
86 unsigned access
= MO
.getTargetFlags() & PPCII::MO_ACCESS_MASK
;
89 case PPCII::MO_TPREL_LO
:
90 RefKind
= MCSymbolRefExpr::VK_PPC_TPREL_LO
;
92 case PPCII::MO_TPREL_HA
:
93 RefKind
= MCSymbolRefExpr::VK_PPC_TPREL_HA
;
95 case PPCII::MO_DTPREL_LO
:
96 RefKind
= MCSymbolRefExpr::VK_PPC_DTPREL_LO
;
98 case PPCII::MO_TLSLD_LO
:
99 RefKind
= MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO
;
101 case PPCII::MO_TOC_LO
:
102 RefKind
= MCSymbolRefExpr::VK_PPC_TOC_LO
;
105 RefKind
= MCSymbolRefExpr::VK_PPC_TLS
;
109 if (MO
.getTargetFlags() == PPCII::MO_PLT
)
110 RefKind
= MCSymbolRefExpr::VK_PLT
;
112 const MachineFunction
*MF
= MO
.getParent()->getParent()->getParent();
113 const Module
*M
= MF
->getFunction().getParent();
114 const PPCSubtarget
*Subtarget
= &(MF
->getSubtarget
<PPCSubtarget
>());
115 const TargetMachine
&TM
= Printer
.TM
;
116 const MCExpr
*Expr
= MCSymbolRefExpr::create(Symbol
, RefKind
, Ctx
);
117 // If -msecure-plt -fPIC, add 32768 to symbol.
118 if (Subtarget
->isSecurePlt() && TM
.isPositionIndependent() &&
119 M
->getPICLevel() == PICLevel::BigPIC
&&
120 MO
.getTargetFlags() == PPCII::MO_PLT
)
122 MCBinaryExpr::createAdd(Expr
, MCConstantExpr::create(32768, Ctx
), Ctx
);
124 if (!MO
.isJTI() && MO
.getOffset())
125 Expr
= MCBinaryExpr::createAdd(Expr
,
126 MCConstantExpr::create(MO
.getOffset(), Ctx
),
129 // Subtract off the PIC base if required.
130 if (MO
.getTargetFlags() & PPCII::MO_PIC_FLAG
) {
131 const MachineFunction
*MF
= MO
.getParent()->getParent()->getParent();
133 const MCExpr
*PB
= MCSymbolRefExpr::create(MF
->getPICBaseSymbol(), Ctx
);
134 Expr
= MCBinaryExpr::createSub(Expr
, PB
, Ctx
);
137 // Add ha16() / lo16() markers if required.
140 Expr
= PPCMCExpr::createLo(Expr
, IsDarwin
, Ctx
);
143 Expr
= PPCMCExpr::createHa(Expr
, IsDarwin
, Ctx
);
147 return MCOperand::createExpr(Expr
);
150 void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr
*MI
, MCInst
&OutMI
,
151 AsmPrinter
&AP
, bool IsDarwin
) {
152 OutMI
.setOpcode(MI
->getOpcode());
154 for (unsigned i
= 0, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
156 if (LowerPPCMachineOperandToMCOperand(MI
->getOperand(i
), MCOp
, AP
,
158 OutMI
.addOperand(MCOp
);
162 bool llvm::LowerPPCMachineOperandToMCOperand(const MachineOperand
&MO
,
163 MCOperand
&OutMO
, AsmPrinter
&AP
,
165 switch (MO
.getType()) {
167 llvm_unreachable("unknown operand type");
168 case MachineOperand::MO_Register
:
169 assert(!MO
.getSubReg() && "Subregs should be eliminated!");
170 assert(MO
.getReg() > PPC::NoRegister
&&
171 MO
.getReg() < PPC::NUM_TARGET_REGS
&&
172 "Invalid register for this target!");
173 OutMO
= MCOperand::createReg(MO
.getReg());
175 case MachineOperand::MO_Immediate
:
176 OutMO
= MCOperand::createImm(MO
.getImm());
178 case MachineOperand::MO_MachineBasicBlock
:
179 OutMO
= MCOperand::createExpr(
180 MCSymbolRefExpr::create(MO
.getMBB()->getSymbol(), AP
.OutContext
));
182 case MachineOperand::MO_GlobalAddress
:
183 case MachineOperand::MO_ExternalSymbol
:
184 OutMO
= GetSymbolRef(MO
, GetSymbolFromOperand(MO
, AP
), AP
, IsDarwin
);
186 case MachineOperand::MO_JumpTableIndex
:
187 OutMO
= GetSymbolRef(MO
, AP
.GetJTISymbol(MO
.getIndex()), AP
, IsDarwin
);
189 case MachineOperand::MO_ConstantPoolIndex
:
190 OutMO
= GetSymbolRef(MO
, AP
.GetCPISymbol(MO
.getIndex()), AP
, IsDarwin
);
192 case MachineOperand::MO_BlockAddress
:
193 OutMO
= GetSymbolRef(MO
, AP
.GetBlockAddressSymbol(MO
.getBlockAddress()), AP
,
196 case MachineOperand::MO_MCSymbol
:
197 OutMO
= GetSymbolRef(MO
, MO
.getMCSymbol(), AP
, IsDarwin
);
199 case MachineOperand::MO_RegisterMask
: