brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.5 KiB · 75440a0 Raw
237 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains code to lower PPC MachineInstrs to their corresponding10// MCInst records.11//12//===----------------------------------------------------------------------===//13 14#include "MCTargetDesc/PPCMCAsmInfo.h"15#include "PPC.h"16#include "PPCMachineFunctionInfo.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/IR/DataLayout.h"25#include "llvm/IR/GlobalValue.h"26#include "llvm/IR/Mangler.h"27#include "llvm/IR/Module.h"28#include "llvm/MC/MCAsmInfo.h"29#include "llvm/MC/MCExpr.h"30#include "llvm/MC/MCInst.h"31#include "llvm/Target/TargetLoweringObjectFile.h"32using namespace llvm;33 34static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO,35                                      AsmPrinter &AP) {36  if (MO.isGlobal()) {37    // Get the symbol from the global, accounting for XCOFF-specific38    // intricacies (see TargetLoweringObjectFileXCOFF::getTargetSymbol).39    const GlobalValue *GV = MO.getGlobal();40    return AP.getSymbol(GV);41  }42 43  assert(MO.isSymbol() && "Isn't a symbol reference");44 45  SmallString<128> Name;46  const DataLayout &DL = AP.getDataLayout();47  Mangler::getNameWithPrefix(Name, MO.getSymbolName(), DL);48 49  MCContext &Ctx = AP.OutContext;50  MCSymbol *Sym = Ctx.getOrCreateSymbol(Name);51  return Sym;52}53 54static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,55                              AsmPrinter &Printer) {56  MCContext &Ctx = Printer.OutContext;57  PPCMCExpr::Specifier RefKind = PPC::S_None;58 59  unsigned access = MO.getTargetFlags();60 61  switch (access) {62    case PPCII::MO_TPREL_LO:63      RefKind = PPC::S_TPREL_LO;64      break;65    case PPCII::MO_TPREL_HA:66      RefKind = PPC::S_TPREL_HA;67      break;68    case PPCII::MO_DTPREL_LO:69      RefKind = PPC::S_DTPREL_LO;70      break;71    case PPCII::MO_TLSLD_LO:72      RefKind = PPC::S_GOT_TLSLD_LO;73      break;74    case PPCII::MO_TOC_LO:75      RefKind = PPC::S_TOC_LO;76      break;77    case PPCII::MO_TLS:78      RefKind = PPC::S_TLS;79      break;80    case PPCII::MO_TLS_PCREL_FLAG:81      RefKind = PPC::S_TLS_PCREL;82      break;83  }84 85  const TargetMachine &TM = Printer.TM;86  const MachineInstr *MI = MO.getParent();87  const MachineFunction *MF = MI->getMF();88 89  if (MO.getTargetFlags() == PPCII::MO_PLT)90    RefKind = PPC::S_PLT;91  else if (MO.getTargetFlags() == PPCII::MO_PCREL_FLAG)92    RefKind = PPC::S_PCREL;93  else if (MO.getTargetFlags() == PPCII::MO_GOT_PCREL_FLAG)94    RefKind = PPC::S_GOT_PCREL;95  else if (MO.getTargetFlags() == PPCII::MO_TPREL_PCREL_FLAG)96    RefKind = PPC::S_TPREL;97  else if (MO.getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG)98    RefKind = PPC::S_GOT_TLSGD_PCREL;99  else if (MO.getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG)100    RefKind = PPC::S_GOT_TLSLD_PCREL;101  else if (MO.getTargetFlags() == PPCII::MO_GOT_TPREL_PCREL_FLAG)102    RefKind = PPC::S_GOT_TPREL_PCREL;103  else if (MO.getTargetFlags() == PPCII::MO_TPREL_FLAG ||104           MO.getTargetFlags() == PPCII::MO_TLSLD_FLAG) {105    assert(MO.isGlobal() && "Only expecting a global MachineOperand here!");106    TLSModel::Model Model = TM.getTLSModel(MO.getGlobal());107    const PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();108    // For the local-[exec|dynamic] TLS model, we may generate the offset from109    // the TLS base as an immediate operand (instead of using a TOC entry). Set110    // the relocation type in case the result is used for purposes other than a111    // TOC reference. In TOC reference cases, this result is discarded.112    if (Model == TLSModel::LocalExec)113      RefKind = PPC::S_AIX_TLSLE;114    else if (Model == TLSModel::LocalDynamic &&115             FuncInfo->isAIXFuncUseTLSIEForLD())116      // On AIX, TLS model opt may have turned local-dynamic accesses into117      // initial-exec accesses.118      RefKind = PPC::S_AIX_TLSIE;119    else if (Model == TLSModel::LocalDynamic)120      RefKind = PPC::S_AIX_TLSLD;121  }122 123  const Module *M = MF->getFunction().getParent();124  const PPCSubtarget *Subtarget = &(MF->getSubtarget<PPCSubtarget>());125 126  unsigned MIOpcode = MI->getOpcode();127  assert((Subtarget->isUsingPCRelativeCalls() || MIOpcode != PPC::BL8_NOTOC) &&128         "BL8_NOTOC is only valid when using PC Relative Calls.");129  if (Subtarget->isUsingPCRelativeCalls()) {130    if (MIOpcode == PPC::TAILB || MIOpcode == PPC::TAILB8 ||131        MIOpcode == PPC::TCRETURNdi || MIOpcode == PPC::TCRETURNdi8 ||132        MIOpcode == PPC::BL8_NOTOC || MIOpcode == PPC::BL8_NOTOC_RM) {133      RefKind = PPC::S_NOTOC;134    }135    if (MO.getTargetFlags() == PPCII::MO_PCREL_OPT_FLAG)136      RefKind = PPC::S_PCREL_OPT;137  }138 139  const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, RefKind, Ctx);140  // If -msecure-plt -fPIC, add 32768 to symbol.141  if (Subtarget->isSecurePlt() && TM.isPositionIndependent() &&142      M->getPICLevel() == PICLevel::BigPIC &&143      MO.getTargetFlags() == PPCII::MO_PLT)144    Expr =145        MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(32768, Ctx), Ctx);146 147  if (!MO.isJTI() && MO.getOffset())148    Expr = MCBinaryExpr::createAdd(Expr,149                                   MCConstantExpr::create(MO.getOffset(), Ctx),150                                   Ctx);151 152  // Subtract off the PIC base if required.153  if (MO.getTargetFlags() == PPCII::MO_PIC_FLAG ||154      MO.getTargetFlags() == PPCII::MO_PIC_HA_FLAG ||155      MO.getTargetFlags() == PPCII::MO_PIC_LO_FLAG) {156    const MachineFunction *MF = MO.getParent()->getParent()->getParent();157 158    const MCExpr *PB = MCSymbolRefExpr::create(MF->getPICBaseSymbol(), Ctx);159    Expr = MCBinaryExpr::createSub(Expr, PB, Ctx);160  }161 162  // Add ha16() / lo16() markers if required.163  switch (access) {164    case PPCII::MO_LO:165    case PPCII::MO_PIC_LO_FLAG:166      Expr = MCSpecifierExpr::create(Expr, PPC::S_LO, Ctx);167      break;168    case PPCII::MO_HA:169    case PPCII::MO_PIC_HA_FLAG:170      Expr = MCSpecifierExpr::create(Expr, PPC::S_HA, Ctx);171      break;172  }173 174  return MCOperand::createExpr(Expr);175}176 177void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,178                                        AsmPrinter &AP) {179  OutMI.setOpcode(MI->getOpcode());180 181  for (const MachineOperand &MO : MI->operands()) {182    MCOperand MCOp;183    if (LowerPPCMachineOperandToMCOperand(MO, MCOp, AP))184      OutMI.addOperand(MCOp);185  }186}187 188bool llvm::LowerPPCMachineOperandToMCOperand(const MachineOperand &MO,189                                             MCOperand &OutMO, AsmPrinter &AP) {190  switch (MO.getType()) {191  default:192    llvm_unreachable("unknown operand type");193  case MachineOperand::MO_Register:194    assert(!MO.getSubReg() && "Subregs should be eliminated!");195    assert(MO.getReg() > PPC::NoRegister &&196           MO.getReg() < PPC::NUM_TARGET_REGS &&197           "Invalid register for this target!");198    // ISA instructions refer to the containing dmr reg.199    if (PPC::isDMRROWpRegister(MO.getReg())) {200      OutMO =201          MCOperand::createReg(PPC::DMR0 + (MO.getReg() - PPC::DMRROWp0) / 4);202      return true;203    }204    // Ignore all implicit register operands.205    if (MO.isImplicit())206      return false;207    OutMO = MCOperand::createReg(MO.getReg());208    return true;209  case MachineOperand::MO_Immediate:210    OutMO = MCOperand::createImm(MO.getImm());211    return true;212  case MachineOperand::MO_MachineBasicBlock:213    OutMO = MCOperand::createExpr(214        MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), AP.OutContext));215    return true;216  case MachineOperand::MO_GlobalAddress:217  case MachineOperand::MO_ExternalSymbol:218    OutMO = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP);219    return true;220  case MachineOperand::MO_JumpTableIndex:221    OutMO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP);222    return true;223  case MachineOperand::MO_ConstantPoolIndex:224    OutMO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP);225    return true;226  case MachineOperand::MO_BlockAddress:227    OutMO =228        GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP);229    return true;230  case MachineOperand::MO_MCSymbol:231    OutMO = GetSymbolRef(MO, MO.getMCSymbol(), AP);232    return true;233  case MachineOperand::MO_RegisterMask:234    return false;235  }236}237