PPCMCTargetDesc.cpp revision 360784
11558Srgrimes//===-- PPCMCTargetDesc.cpp - PowerPC Target Descriptions -----------------===//
21558Srgrimes//
31558Srgrimes// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41558Srgrimes// See https://llvm.org/LICENSE.txt for license information.
51558Srgrimes// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61558Srgrimes//
71558Srgrimes//===----------------------------------------------------------------------===//
81558Srgrimes//
91558Srgrimes// This file provides PowerPC specific target descriptions.
101558Srgrimes//
111558Srgrimes//===----------------------------------------------------------------------===//
121558Srgrimes
131558Srgrimes#include "MCTargetDesc/PPCMCTargetDesc.h"
141558Srgrimes#include "MCTargetDesc/PPCInstPrinter.h"
151558Srgrimes#include "MCTargetDesc/PPCMCAsmInfo.h"
161558Srgrimes#include "PPCTargetStreamer.h"
171558Srgrimes#include "TargetInfo/PowerPCTargetInfo.h"
181558Srgrimes#include "llvm/ADT/SmallPtrSet.h"
191558Srgrimes#include "llvm/ADT/StringRef.h"
201558Srgrimes#include "llvm/ADT/Triple.h"
211558Srgrimes#include "llvm/BinaryFormat/ELF.h"
221558Srgrimes#include "llvm/MC/MCAssembler.h"
231558Srgrimes#include "llvm/MC/MCContext.h"
241558Srgrimes#include "llvm/MC/MCDwarf.h"
251558Srgrimes#include "llvm/MC/MCELFStreamer.h"
261558Srgrimes#include "llvm/MC/MCExpr.h"
271558Srgrimes#include "llvm/MC/MCInstrInfo.h"
281558Srgrimes#include "llvm/MC/MCRegisterInfo.h"
291558Srgrimes#include "llvm/MC/MCStreamer.h"
301558Srgrimes#include "llvm/MC/MCSubtargetInfo.h"
311558Srgrimes#include "llvm/MC/MCSymbol.h"
321558Srgrimes#include "llvm/MC/MCSymbolELF.h"
331558Srgrimes#include "llvm/MC/MCSymbolXCOFF.h"
3437663Scharnier#include "llvm/Support/Casting.h"
351558Srgrimes#include "llvm/Support/CodeGen.h"
361558Srgrimes#include "llvm/Support/ErrorHandling.h"
372999Swollman#include "llvm/Support/FormattedStream.h"
381558Srgrimes#include "llvm/Support/TargetRegistry.h"
39105267Scharnier#include "llvm/Support/raw_ostream.h"
401558Srgrimes
4137663Scharnierusing namespace llvm;
42105267Scharnier
4337663Scharnier#define GET_INSTRINFO_MC_DESC
441558Srgrimes#include "PPCGenInstrInfo.inc"
45105267Scharnier
46105267Scharnier#define GET_SUBTARGETINFO_MC_DESC
47105267Scharnier#include "PPCGenSubtargetInfo.inc"
481558Srgrimes
49192934Srmacklem#define GET_REGINFO_MC_DESC
50192934Srmacklem#include "PPCGenRegisterInfo.inc"
51192934Srmacklem
521558SrgrimesPPCTargetStreamer::PPCTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
531558Srgrimes
54192934Srmacklem// Pin the vtable to this file.
551558SrgrimesPPCTargetStreamer::~PPCTargetStreamer() = default;
561558Srgrimes
571558Srgrimesstatic MCInstrInfo *createPPCMCInstrInfo() {
58109363Smbr  MCInstrInfo *X = new MCInstrInfo();
591558Srgrimes  InitPPCMCInstrInfo(X);
6074462Salfred  return X;
6174462Salfred}
629336Sdfr
63192934Srmacklemstatic MCRegisterInfo *createPPCMCRegisterInfo(const Triple &TT) {
6483653Speter  bool isPPC64 =
651558Srgrimes      (TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le);
66192934Srmacklem  unsigned Flavour = isPPC64 ? 0 : 1;
67192934Srmacklem  unsigned RA = isPPC64 ? PPC::LR8 : PPC::LR;
681558Srgrimes
691558Srgrimes  MCRegisterInfo *X = new MCRegisterInfo();
701558Srgrimes  InitPPCMCRegisterInfo(X, RA, Flavour, Flavour);
7137663Scharnier  return X;
721558Srgrimes}
731558Srgrimes
74149433Spjdstatic MCSubtargetInfo *createPPCMCSubtargetInfo(const Triple &TT,
75103949Smike                                                 StringRef CPU, StringRef FS) {
761558Srgrimes  return createPPCMCSubtargetInfoImpl(TT, CPU, FS);
771558Srgrimes}
781558Srgrimes
791558Srgrimesstatic MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI,
801558Srgrimes                                     const Triple &TheTriple,
811558Srgrimes                                     const MCTargetOptions &Options) {
821558Srgrimes  bool isPPC64 = (TheTriple.getArch() == Triple::ppc64 ||
831558Srgrimes                  TheTriple.getArch() == Triple::ppc64le);
84158857Srodrigc
851558Srgrimes  MCAsmInfo *MAI;
861558Srgrimes  if (TheTriple.isOSBinFormatXCOFF())
871558Srgrimes    MAI = new PPCXCOFFMCAsmInfo(isPPC64, TheTriple);
881558Srgrimes  else
891558Srgrimes    MAI = new PPCELFMCAsmInfo(isPPC64, TheTriple);
901558Srgrimes
911558Srgrimes  // Initial state of the frame pointer is R1.
921558Srgrimes  unsigned Reg = isPPC64 ? PPC::X1 : PPC::R1;
931558Srgrimes  MCCFIInstruction Inst =
941558Srgrimes      MCCFIInstruction::createDefCfa(nullptr, MRI.getDwarfRegNum(Reg, true), 0);
95194880Sdfr  MAI->addInitialFrameState(Inst);
96194880Sdfr
971558Srgrimes  return MAI;
981558Srgrimes}
991558Srgrimes
1001558Srgrimesnamespace {
1011558Srgrimes
1021558Srgrimesclass PPCTargetAsmStreamer : public PPCTargetStreamer {
1031558Srgrimes  formatted_raw_ostream &OS;
1041558Srgrimes
1051558Srgrimespublic:
1061558Srgrimes  PPCTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS)
1071558Srgrimes      : PPCTargetStreamer(S), OS(OS) {}
1089336Sdfr
1091558Srgrimes  void emitTCEntry(const MCSymbol &S) override {
1101558Srgrimes    const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
1111558Srgrimes    OS << "\t.tc ";
1121558Srgrimes    OS << (MAI->getSymbolsHaveSMC()
1131558Srgrimes               ? cast<MCSymbolXCOFF>(S).getUnqualifiedName()
1141558Srgrimes               : S.getName());
1151558Srgrimes    OS << "[TC],";
1161558Srgrimes    OS << S.getName();
11727447Sdfr    OS << '\n';
118184588Sdfr  }
119184588Sdfr
1201558Srgrimes  void emitMachine(StringRef CPU) override {
1211558Srgrimes    OS << "\t.machine " << CPU << '\n';
1221558Srgrimes  }
1231558Srgrimes
1241558Srgrimes  void emitAbiVersion(int AbiVersion) override {
12574462Salfred    OS << "\t.abiversion " << AbiVersion << '\n';
12675801Siedowse  }
12742144Sdfr
1281558Srgrimes  void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override {
1291558Srgrimes    const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
1301558Srgrimes
13174462Salfred    OS << "\t.localentry\t";
1321558Srgrimes    S->print(OS, MAI);
1331558Srgrimes    OS << ", ";
1341558Srgrimes    LocalOffset->print(OS, MAI);
1351558Srgrimes    OS << '\n';
1361558Srgrimes  }
1371558Srgrimes};
1381558Srgrimes
1391558Srgrimesclass PPCTargetELFStreamer : public PPCTargetStreamer {
1401558Srgrimespublic:
1411558Srgrimes  PPCTargetELFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {}
1421558Srgrimes
1431558Srgrimes  MCELFStreamer &getStreamer() {
14475641Siedowse    return static_cast<MCELFStreamer &>(Streamer);
1457401Swpaul  }
1461558Srgrimes
1471558Srgrimes  void emitTCEntry(const MCSymbol &S) override {
1489336Sdfr    // Creates a R_PPC64_TOC relocation
1491558Srgrimes    Streamer.EmitValueToAlignment(8);
1501558Srgrimes    Streamer.EmitSymbolValue(&S, 8);
1511558Srgrimes  }
1521558Srgrimes
1539336Sdfr  void emitMachine(StringRef CPU) override {
1549336Sdfr    // FIXME: Is there anything to do in here or does this directive only
1559336Sdfr    // limit the parser?
1569336Sdfr  }
157184588Sdfr
158184588Sdfr  void emitAbiVersion(int AbiVersion) override {
1599336Sdfr    MCAssembler &MCA = getStreamer().getAssembler();
1609336Sdfr    unsigned Flags = MCA.getELFHeaderEFlags();
161222623Srmacklem    Flags &= ~ELF::EF_PPC64_ABI;
162222623Srmacklem    Flags |= (AbiVersion & ELF::EF_PPC64_ABI);
1631558Srgrimes    MCA.setELFHeaderEFlags(Flags);
16492882Simp  }
16592882Simp
16692882Simp  void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override {
16792882Simp    MCAssembler &MCA = getStreamer().getAssembler();
16892882Simp
16992882Simp    int64_t Res;
17075801Siedowse    if (!LocalOffset->evaluateAsAbsolute(Res, MCA))
17192882Simp      report_fatal_error(".localentry expression must be absolute.");
172222623Srmacklem
173222623Srmacklem    unsigned Encoded = ELF::encodePPC64LocalEntryOffset(Res);
174222623Srmacklem    if (Res != ELF::decodePPC64LocalEntryOffset(Encoded))
17575635Siedowse      report_fatal_error(".localentry expression cannot be encoded.");
17692882Simp
17792882Simp    unsigned Other = S->getOther();
17892882Simp    Other &= ~ELF::STO_PPC64_LOCAL_MASK;
17992882Simp    Other |= Encoded;
18092882Simp    S->setOther(Other);
18192882Simp
18292882Simp    // For GAS compatibility, unless we already saw a .abiversion directive,
18392882Simp    // set e_flags to indicate ELFv2 ABI.
18492882Simp    unsigned Flags = MCA.getELFHeaderEFlags();
18592882Simp    if ((Flags & ELF::EF_PPC64_ABI) == 0)
18692882Simp      MCA.setELFHeaderEFlags(Flags | 2);
18792882Simp  }
18892882Simp
18992882Simp  void emitAssignment(MCSymbol *S, const MCExpr *Value) override {
19092882Simp    auto *Symbol = cast<MCSymbolELF>(S);
19192882Simp
19292882Simp    // When encoding an assignment to set symbol A to symbol B, also copy
19392882Simp    // the st_other bits encoding the local entry point offset.
19492882Simp    if (copyLocalEntry(Symbol, Value))
19592882Simp      UpdateOther.insert(Symbol);
19692882Simp    else
19775754Siedowse      UpdateOther.erase(Symbol);
19875801Siedowse  }
19992882Simp
20092882Simp  void finish() override {
20192882Simp    for (auto *Sym : UpdateOther)
20292882Simp      if (Sym->isVariable())
203216587Scharnier        copyLocalEntry(Sym, Sym->getVariableValue());
204100117Salfred  }
20575801Siedowse
20675801Siedowseprivate:
20775801Siedowse  SmallPtrSet<MCSymbolELF *, 32> UpdateOther;
20892882Simp
20992882Simp  bool copyLocalEntry(MCSymbolELF *D, const MCExpr *S) {
21092882Simp    auto *Ref = dyn_cast<const MCSymbolRefExpr>(S);
21192882Simp    if (!Ref)
212100117Salfred      return false;
213216587Scharnier    const auto &RhsSym = cast<MCSymbolELF>(Ref->getSymbol());
21492882Simp    unsigned Other = D->getOther();
21592882Simp    Other &= ~ELF::STO_PPC64_LOCAL_MASK;
21692882Simp    Other |= RhsSym.getOther() & ELF::STO_PPC64_LOCAL_MASK;
2171558Srgrimes    D->setOther(Other);
2181558Srgrimes    return true;
2191558Srgrimes  }
2201558Srgrimes};
221166440Spjd
222166440Spjdclass PPCTargetMachOStreamer : public PPCTargetStreamer {
223172827Smatteopublic:
22472650Sgreen  PPCTargetMachOStreamer(MCStreamer &S) : PPCTargetStreamer(S) {}
22591354Sdd
22672650Sgreen  void emitTCEntry(const MCSymbol &S) override {
2271558Srgrimes    llvm_unreachable("Unknown pseudo-op: .tc");
22872650Sgreen  }
22972650Sgreen
2301558Srgrimes  void emitMachine(StringRef CPU) override {
23125087Sdfr    // FIXME: We should update the CPUType, CPUSubType in the Object file if
2329336Sdfr    // the new values are different from the defaults.
233172827Smatteo  }
2349336Sdfr
235121767Speter  void emitAbiVersion(int AbiVersion) override {
23675754Siedowse    llvm_unreachable("Unknown pseudo-op: .abiversion");
237172827Smatteo  }
23874462Salfred
239172827Smatteo  void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override {
240222623Srmacklem    llvm_unreachable("Unknown pseudo-op: .localentry");
241222623Srmacklem  }
242222623Srmacklem};
243222623Srmacklem
244172827Smatteoclass PPCTargetXCOFFStreamer : public PPCTargetStreamer {
2451558Srgrimespublic:
24674462Salfred  PPCTargetXCOFFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {}
24774462Salfred
248192934Srmacklem  void emitTCEntry(const MCSymbol &S) override {
249192934Srmacklem    const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
250220980Srmacklem    const unsigned PointerSize = MAI->getCodePointerSize();
251192934Srmacklem    Streamer.EmitValueToAlignment(PointerSize);
252192934Srmacklem    Streamer.EmitSymbolValue(&S, PointerSize);
253149433Spjd  }
25475801Siedowse
2551558Srgrimes  void emitMachine(StringRef CPU) override {
2561558Srgrimes    llvm_unreachable("Machine pseudo-ops are invalid for XCOFF.");
25783653Speter  }
2581558Srgrimes
2591558Srgrimes  void emitAbiVersion(int AbiVersion) override {
2601558Srgrimes    llvm_unreachable("ABI-version pseudo-ops are invalid for XCOFF.");
26175801Siedowse  }
262100336Sjoerg
26374462Salfred  void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override {
264184588Sdfr    llvm_unreachable("Local-entry pseudo-ops are invalid for XCOFF.");
2651558Srgrimes  }
2661558Srgrimes};
2671558Srgrimes
26892882Simp} // end anonymous namespace
2691558Srgrimes
2701558Srgrimesstatic MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
2711558Srgrimes                                                 formatted_raw_ostream &OS,
2721558Srgrimes                                                 MCInstPrinter *InstPrint,
2731558Srgrimes                                                 bool isVerboseAsm) {
2741558Srgrimes  return new PPCTargetAsmStreamer(S, OS);
2751558Srgrimes}
2761558Srgrimes
2771558Srgrimesstatic MCTargetStreamer *
2781558SrgrimescreateObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
2791558Srgrimes  const Triple &TT = STI.getTargetTriple();
2801558Srgrimes  if (TT.isOSBinFormatELF())
2811558Srgrimes    return new PPCTargetELFStreamer(S);
282216587Scharnier  if (TT.isOSBinFormatXCOFF())
2831558Srgrimes    return new PPCTargetXCOFFStreamer(S);
28475754Siedowse  return new PPCTargetMachOStreamer(S);
285172827Smatteo}
286172827Smatteo
287172827Smatteostatic MCInstPrinter *createPPCMCInstPrinter(const Triple &T,
288149433Spjd                                             unsigned SyntaxVariant,
289172827Smatteo                                             const MCAsmInfo &MAI,
290172827Smatteo                                             const MCInstrInfo &MII,
291109363Smbr                                             const MCRegisterInfo &MRI) {
292222623Srmacklem  return new PPCInstPrinter(MAI, MII, MRI, T);
293222623Srmacklem}
2941558Srgrimes
29574462Salfredextern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetMC() {
296150214Spjd  for (Target *T :
297149433Spjd       {&getThePPC32Target(), &getThePPC64Target(), &getThePPC64LETarget()}) {
298149433Spjd    // Register the MC asm info.
299149433Spjd    RegisterMCAsmInfoFn C(*T, createPPCMCAsmInfo);
300149433Spjd
301149433Spjd    // Register the MC instruction info.
30274462Salfred    TargetRegistry::RegisterMCInstrInfo(*T, createPPCMCInstrInfo);
30374462Salfred
30474462Salfred    // Register the MC register info.
30574462Salfred    TargetRegistry::RegisterMCRegInfo(*T, createPPCMCRegisterInfo);
30674462Salfred
30774462Salfred    // Register the MC subtarget info.
3082999Swollman    TargetRegistry::RegisterMCSubtargetInfo(*T, createPPCMCSubtargetInfo);
309220980Srmacklem
3101558Srgrimes    // Register the MC Code Emitter
31125087Sdfr    TargetRegistry::RegisterMCCodeEmitter(*T, createPPCMCCodeEmitter);
31225087Sdfr
31325087Sdfr    // Register the asm backend.
314192993Srmacklem    TargetRegistry::RegisterMCAsmBackend(*T, createPPCAsmBackend);
315220980Srmacklem
316192934Srmacklem    // Register the object target streamer.
3179336Sdfr    TargetRegistry::RegisterObjectTargetStreamer(*T,
3189336Sdfr                                                 createObjectTargetStreamer);
3199336Sdfr
3209336Sdfr    // Register the asm target streamer.
3219336Sdfr    TargetRegistry::RegisterAsmTargetStreamer(*T, createAsmTargetStreamer);
3229336Sdfr
3238688Sphk    // Register the MCInstPrinter.
3248688Sphk    TargetRegistry::RegisterMCInstPrinter(*T, createPPCMCInstPrinter);
3258688Sphk  }
32631656Sguido}
327121767Speter