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 MCSymbol
*GetSymbolFromOperand(const MachineOperand
&MO
,
34 const TargetMachine
&TM
= AP
.TM
;
35 Mangler
&Mang
= TM
.getObjFileLowering()->getMangler();
36 const DataLayout
&DL
= AP
.getDataLayout();
37 MCContext
&Ctx
= AP
.OutContext
;
39 SmallString
<128> Name
;
41 assert(MO
.isSymbol() && "Isn't a symbol reference");
42 Mangler::getNameWithPrefix(Name
, MO
.getSymbolName(), DL
);
44 const GlobalValue
*GV
= MO
.getGlobal();
45 TM
.getNameWithPrefix(Name
, GV
, Mang
);
48 MCSymbol
*Sym
= Ctx
.getOrCreateSymbol(Name
);
53 static MCOperand
GetSymbolRef(const MachineOperand
&MO
, const MCSymbol
*Symbol
,
54 AsmPrinter
&Printer
) {
55 MCContext
&Ctx
= Printer
.OutContext
;
56 MCSymbolRefExpr::VariantKind RefKind
= MCSymbolRefExpr::VK_None
;
58 unsigned access
= MO
.getTargetFlags() & PPCII::MO_ACCESS_MASK
;
61 case PPCII::MO_TPREL_LO
:
62 RefKind
= MCSymbolRefExpr::VK_PPC_TPREL_LO
;
64 case PPCII::MO_TPREL_HA
:
65 RefKind
= MCSymbolRefExpr::VK_PPC_TPREL_HA
;
67 case PPCII::MO_DTPREL_LO
:
68 RefKind
= MCSymbolRefExpr::VK_PPC_DTPREL_LO
;
70 case PPCII::MO_TLSLD_LO
:
71 RefKind
= MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO
;
73 case PPCII::MO_TOC_LO
:
74 RefKind
= MCSymbolRefExpr::VK_PPC_TOC_LO
;
77 bool IsPCRel
= (MO
.getTargetFlags() & ~access
) == PPCII::MO_PCREL_FLAG
;
78 RefKind
= IsPCRel
? MCSymbolRefExpr::VK_PPC_TLS_PCREL
79 : MCSymbolRefExpr::VK_PPC_TLS
;
83 if (MO
.getTargetFlags() == PPCII::MO_PLT
)
84 RefKind
= MCSymbolRefExpr::VK_PLT
;
85 else if (MO
.getTargetFlags() == PPCII::MO_PCREL_FLAG
)
86 RefKind
= MCSymbolRefExpr::VK_PCREL
;
87 else if (MO
.getTargetFlags() == (PPCII::MO_PCREL_FLAG
| PPCII::MO_GOT_FLAG
))
88 RefKind
= MCSymbolRefExpr::VK_PPC_GOT_PCREL
;
89 else if (MO
.getTargetFlags() == (PPCII::MO_PCREL_FLAG
| PPCII::MO_TPREL_FLAG
))
90 RefKind
= MCSymbolRefExpr::VK_TPREL
;
91 else if (MO
.getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG
)
92 RefKind
= MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL
;
93 else if (MO
.getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG
)
94 RefKind
= MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL
;
95 else if (MO
.getTargetFlags() == PPCII::MO_GOT_TPREL_PCREL_FLAG
)
96 RefKind
= MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL
;
98 const MachineInstr
*MI
= MO
.getParent();
99 const MachineFunction
*MF
= MI
->getMF();
100 const Module
*M
= MF
->getFunction().getParent();
101 const PPCSubtarget
*Subtarget
= &(MF
->getSubtarget
<PPCSubtarget
>());
102 const TargetMachine
&TM
= Printer
.TM
;
104 unsigned MIOpcode
= MI
->getOpcode();
105 assert((Subtarget
->isUsingPCRelativeCalls() || MIOpcode
!= PPC::BL8_NOTOC
) &&
106 "BL8_NOTOC is only valid when using PC Relative Calls.");
107 if (Subtarget
->isUsingPCRelativeCalls()) {
108 if (MIOpcode
== PPC::TAILB
|| MIOpcode
== PPC::TAILB8
||
109 MIOpcode
== PPC::TCRETURNdi
|| MIOpcode
== PPC::TCRETURNdi8
||
110 MIOpcode
== PPC::BL8_NOTOC
) {
111 RefKind
= MCSymbolRefExpr::VK_PPC_NOTOC
;
113 if (MO
.getTargetFlags() == PPCII::MO_PCREL_OPT_FLAG
)
114 RefKind
= MCSymbolRefExpr::VK_PPC_PCREL_OPT
;
117 const MCExpr
*Expr
= MCSymbolRefExpr::create(Symbol
, RefKind
, Ctx
);
118 // If -msecure-plt -fPIC, add 32768 to symbol.
119 if (Subtarget
->isSecurePlt() && TM
.isPositionIndependent() &&
120 M
->getPICLevel() == PICLevel::BigPIC
&&
121 MO
.getTargetFlags() == PPCII::MO_PLT
)
123 MCBinaryExpr::createAdd(Expr
, MCConstantExpr::create(32768, Ctx
), Ctx
);
125 if (!MO
.isJTI() && MO
.getOffset())
126 Expr
= MCBinaryExpr::createAdd(Expr
,
127 MCConstantExpr::create(MO
.getOffset(), Ctx
),
130 // Subtract off the PIC base if required.
131 if (MO
.getTargetFlags() & PPCII::MO_PIC_FLAG
) {
132 const MachineFunction
*MF
= MO
.getParent()->getParent()->getParent();
134 const MCExpr
*PB
= MCSymbolRefExpr::create(MF
->getPICBaseSymbol(), Ctx
);
135 Expr
= MCBinaryExpr::createSub(Expr
, PB
, Ctx
);
138 // Add ha16() / lo16() markers if required.
141 Expr
= PPCMCExpr::createLo(Expr
, Ctx
);
144 Expr
= PPCMCExpr::createHa(Expr
, Ctx
);
148 return MCOperand::createExpr(Expr
);
151 void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr
*MI
, MCInst
&OutMI
,
153 OutMI
.setOpcode(MI
->getOpcode());
155 for (unsigned i
= 0, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
157 if (LowerPPCMachineOperandToMCOperand(MI
->getOperand(i
), MCOp
, AP
))
158 OutMI
.addOperand(MCOp
);
162 bool llvm::LowerPPCMachineOperandToMCOperand(const MachineOperand
&MO
,
163 MCOperand
&OutMO
, AsmPrinter
&AP
) {
164 switch (MO
.getType()) {
166 llvm_unreachable("unknown operand type");
167 case MachineOperand::MO_Register
:
168 assert(!MO
.getSubReg() && "Subregs should be eliminated!");
169 assert(MO
.getReg() > PPC::NoRegister
&&
170 MO
.getReg() < PPC::NUM_TARGET_REGS
&&
171 "Invalid register for this target!");
172 // Ignore all implicit register operands.
175 OutMO
= MCOperand::createReg(MO
.getReg());
177 case MachineOperand::MO_Immediate
:
178 OutMO
= MCOperand::createImm(MO
.getImm());
180 case MachineOperand::MO_MachineBasicBlock
:
181 OutMO
= MCOperand::createExpr(
182 MCSymbolRefExpr::create(MO
.getMBB()->getSymbol(), AP
.OutContext
));
184 case MachineOperand::MO_GlobalAddress
:
185 case MachineOperand::MO_ExternalSymbol
:
186 OutMO
= GetSymbolRef(MO
, GetSymbolFromOperand(MO
, AP
), AP
);
188 case MachineOperand::MO_JumpTableIndex
:
189 OutMO
= GetSymbolRef(MO
, AP
.GetJTISymbol(MO
.getIndex()), AP
);
191 case MachineOperand::MO_ConstantPoolIndex
:
192 OutMO
= GetSymbolRef(MO
, AP
.GetCPISymbol(MO
.getIndex()), AP
);
194 case MachineOperand::MO_BlockAddress
:
196 GetSymbolRef(MO
, AP
.GetBlockAddressSymbol(MO
.getBlockAddress()), AP
);
198 case MachineOperand::MO_MCSymbol
:
199 OutMO
= GetSymbolRef(MO
, MO
.getMCSymbol(), AP
);
201 case MachineOperand::MO_RegisterMask
: