1 //===-- PPCMCInstLower.cpp - Convert PPC MachineInstr to an MCInst --------===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains code to lower PPC MachineInstrs to their corresponding 10 // MCInst records. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "MCTargetDesc/PPCMCExpr.h" 15 #include "PPC.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" 30 using namespace llvm; 31 32 static MachineModuleInfoMachO &getMachOMMI(AsmPrinter &AP) { 33 return AP.MMI->getObjFileInfo<MachineModuleInfoMachO>(); 34 } 35 36 static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, 37 AsmPrinter &AP) { 38 const TargetMachine &TM = AP.TM; 39 Mangler &Mang = TM.getObjFileLowering()->getMangler(); 40 const DataLayout &DL = AP.getDataLayout(); 41 MCContext &Ctx = AP.OutContext; 42 43 SmallString<128> Name; 44 StringRef Suffix; 45 if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG) 46 Suffix = "$non_lazy_ptr"; 47 48 if (!Suffix.empty()) 49 Name += DL.getPrivateGlobalPrefix(); 50 51 if (!MO.isGlobal()) { 52 assert(MO.isSymbol() && "Isn't a symbol reference"); 53 Mangler::getNameWithPrefix(Name, MO.getSymbolName(), DL); 54 } else { 55 const GlobalValue *GV = MO.getGlobal(); 56 TM.getNameWithPrefix(Name, GV, Mang); 57 } 58 59 Name += Suffix; 60 MCSymbol *Sym = Ctx.getOrCreateSymbol(Name); 61 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); 66 67 MachineModuleInfoImpl::StubValueTy &StubSym = MachO.getGVStubEntry(Sym); 68 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()); 74 } 75 return Sym; 76 } 77 78 return Sym; 79 } 80 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; 85 86 unsigned access = MO.getTargetFlags() & PPCII::MO_ACCESS_MASK; 87 88 switch (access) { 89 case PPCII::MO_TPREL_LO: 90 RefKind = MCSymbolRefExpr::VK_PPC_TPREL_LO; 91 break; 92 case PPCII::MO_TPREL_HA: 93 RefKind = MCSymbolRefExpr::VK_PPC_TPREL_HA; 94 break; 95 case PPCII::MO_DTPREL_LO: 96 RefKind = MCSymbolRefExpr::VK_PPC_DTPREL_LO; 97 break; 98 case PPCII::MO_TLSLD_LO: 99 RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO; 100 break; 101 case PPCII::MO_TOC_LO: 102 RefKind = MCSymbolRefExpr::VK_PPC_TOC_LO; 103 break; 104 case PPCII::MO_TLS: 105 RefKind = MCSymbolRefExpr::VK_PPC_TLS; 106 break; 107 } 108 109 if (MO.getTargetFlags() == PPCII::MO_PLT) 110 RefKind = MCSymbolRefExpr::VK_PLT; 111 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) 121 Expr = 122 MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(32768, Ctx), Ctx); 123 124 if (!MO.isJTI() && MO.getOffset()) 125 Expr = MCBinaryExpr::createAdd(Expr, 126 MCConstantExpr::create(MO.getOffset(), Ctx), 127 Ctx); 128 129 // Subtract off the PIC base if required. 130 if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG) { 131 const MachineFunction *MF = MO.getParent()->getParent()->getParent(); 132 133 const MCExpr *PB = MCSymbolRefExpr::create(MF->getPICBaseSymbol(), Ctx); 134 Expr = MCBinaryExpr::createSub(Expr, PB, Ctx); 135 } 136 137 // Add ha16() / lo16() markers if required. 138 switch (access) { 139 case PPCII::MO_LO: 140 Expr = PPCMCExpr::createLo(Expr, IsDarwin, Ctx); 141 break; 142 case PPCII::MO_HA: 143 Expr = PPCMCExpr::createHa(Expr, IsDarwin, Ctx); 144 break; 145 } 146 147 return MCOperand::createExpr(Expr); 148 } 149 150 void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, 151 AsmPrinter &AP, bool IsDarwin) { 152 OutMI.setOpcode(MI->getOpcode()); 153 154 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 155 MCOperand MCOp; 156 if (LowerPPCMachineOperandToMCOperand(MI->getOperand(i), MCOp, AP, 157 IsDarwin)) 158 OutMI.addOperand(MCOp); 159 } 160 } 161 162 bool llvm::LowerPPCMachineOperandToMCOperand(const MachineOperand &MO, 163 MCOperand &OutMO, AsmPrinter &AP, 164 bool IsDarwin) { 165 switch (MO.getType()) { 166 default: 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()); 174 return true; 175 case MachineOperand::MO_Immediate: 176 OutMO = MCOperand::createImm(MO.getImm()); 177 return true; 178 case MachineOperand::MO_MachineBasicBlock: 179 OutMO = MCOperand::createExpr( 180 MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), AP.OutContext)); 181 return true; 182 case MachineOperand::MO_GlobalAddress: 183 case MachineOperand::MO_ExternalSymbol: 184 OutMO = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP, IsDarwin); 185 return true; 186 case MachineOperand::MO_JumpTableIndex: 187 OutMO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP, IsDarwin); 188 return true; 189 case MachineOperand::MO_ConstantPoolIndex: 190 OutMO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP, IsDarwin); 191 return true; 192 case MachineOperand::MO_BlockAddress: 193 OutMO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP, 194 IsDarwin); 195 return true; 196 case MachineOperand::MO_MCSymbol: 197 OutMO = GetSymbolRef(MO, MO.getMCSymbol(), AP, IsDarwin); 198 return true; 199 case MachineOperand::MO_RegisterMask: 200 return false; 201 } 202 } 203