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 MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, 33 AsmPrinter &AP) { 34 const TargetMachine &TM = AP.TM; 35 Mangler &Mang = TM.getObjFileLowering()->getMangler(); 36 const DataLayout &DL = AP.getDataLayout(); 37 MCContext &Ctx = AP.OutContext; 38 39 SmallString<128> Name; 40 if (!MO.isGlobal()) { 41 assert(MO.isSymbol() && "Isn't a symbol reference"); 42 Mangler::getNameWithPrefix(Name, MO.getSymbolName(), DL); 43 } else { 44 const GlobalValue *GV = MO.getGlobal(); 45 TM.getNameWithPrefix(Name, GV, Mang); 46 } 47 48 MCSymbol *Sym = Ctx.getOrCreateSymbol(Name); 49 50 return Sym; 51 } 52 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; 57 58 unsigned access = MO.getTargetFlags() & PPCII::MO_ACCESS_MASK; 59 60 switch (access) { 61 case PPCII::MO_TPREL_LO: 62 RefKind = MCSymbolRefExpr::VK_PPC_TPREL_LO; 63 break; 64 case PPCII::MO_TPREL_HA: 65 RefKind = MCSymbolRefExpr::VK_PPC_TPREL_HA; 66 break; 67 case PPCII::MO_DTPREL_LO: 68 RefKind = MCSymbolRefExpr::VK_PPC_DTPREL_LO; 69 break; 70 case PPCII::MO_TLSLD_LO: 71 RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO; 72 break; 73 case PPCII::MO_TOC_LO: 74 RefKind = MCSymbolRefExpr::VK_PPC_TOC_LO; 75 break; 76 case PPCII::MO_TLS: 77 RefKind = MCSymbolRefExpr::VK_PPC_TLS; 78 break; 79 } 80 81 if (MO.getTargetFlags() == PPCII::MO_PLT) 82 RefKind = MCSymbolRefExpr::VK_PLT; 83 84 const MachineFunction *MF = MO.getParent()->getParent()->getParent(); 85 const Module *M = MF->getFunction().getParent(); 86 const PPCSubtarget *Subtarget = &(MF->getSubtarget<PPCSubtarget>()); 87 const TargetMachine &TM = Printer.TM; 88 const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, RefKind, Ctx); 89 // If -msecure-plt -fPIC, add 32768 to symbol. 90 if (Subtarget->isSecurePlt() && TM.isPositionIndependent() && 91 M->getPICLevel() == PICLevel::BigPIC && 92 MO.getTargetFlags() == PPCII::MO_PLT) 93 Expr = 94 MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(32768, Ctx), Ctx); 95 96 if (!MO.isJTI() && MO.getOffset()) 97 Expr = MCBinaryExpr::createAdd(Expr, 98 MCConstantExpr::create(MO.getOffset(), Ctx), 99 Ctx); 100 101 // Subtract off the PIC base if required. 102 if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG) { 103 const MachineFunction *MF = MO.getParent()->getParent()->getParent(); 104 105 const MCExpr *PB = MCSymbolRefExpr::create(MF->getPICBaseSymbol(), Ctx); 106 Expr = MCBinaryExpr::createSub(Expr, PB, Ctx); 107 } 108 109 // Add ha16() / lo16() markers if required. 110 switch (access) { 111 case PPCII::MO_LO: 112 Expr = PPCMCExpr::createLo(Expr, Ctx); 113 break; 114 case PPCII::MO_HA: 115 Expr = PPCMCExpr::createHa(Expr, Ctx); 116 break; 117 } 118 119 return MCOperand::createExpr(Expr); 120 } 121 122 void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, 123 AsmPrinter &AP) { 124 OutMI.setOpcode(MI->getOpcode()); 125 126 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 127 MCOperand MCOp; 128 if (LowerPPCMachineOperandToMCOperand(MI->getOperand(i), MCOp, AP)) 129 OutMI.addOperand(MCOp); 130 } 131 } 132 133 bool llvm::LowerPPCMachineOperandToMCOperand(const MachineOperand &MO, 134 MCOperand &OutMO, AsmPrinter &AP) { 135 switch (MO.getType()) { 136 default: 137 llvm_unreachable("unknown operand type"); 138 case MachineOperand::MO_Register: 139 assert(!MO.getSubReg() && "Subregs should be eliminated!"); 140 assert(MO.getReg() > PPC::NoRegister && 141 MO.getReg() < PPC::NUM_TARGET_REGS && 142 "Invalid register for this target!"); 143 OutMO = MCOperand::createReg(MO.getReg()); 144 return true; 145 case MachineOperand::MO_Immediate: 146 OutMO = MCOperand::createImm(MO.getImm()); 147 return true; 148 case MachineOperand::MO_MachineBasicBlock: 149 OutMO = MCOperand::createExpr( 150 MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), AP.OutContext)); 151 return true; 152 case MachineOperand::MO_GlobalAddress: 153 case MachineOperand::MO_ExternalSymbol: 154 OutMO = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP); 155 return true; 156 case MachineOperand::MO_JumpTableIndex: 157 OutMO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP); 158 return true; 159 case MachineOperand::MO_ConstantPoolIndex: 160 OutMO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP); 161 return true; 162 case MachineOperand::MO_BlockAddress: 163 OutMO = 164 GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP); 165 return true; 166 case MachineOperand::MO_MCSymbol: 167 OutMO = GetSymbolRef(MO, MO.getMCSymbol(), AP); 168 return true; 169 case MachineOperand::MO_RegisterMask: 170 return false; 171 } 172 } 173