PPCMCTargetDesc.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. //===-- PPCMCTargetDesc.cpp - PowerPC Target Descriptions -----------------===//
  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 provides PowerPC specific target descriptions.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "MCTargetDesc/PPCMCTargetDesc.h"
  13. #include "MCTargetDesc/PPCInstPrinter.h"
  14. #include "MCTargetDesc/PPCMCAsmInfo.h"
  15. #include "PPCELFStreamer.h"
  16. #include "PPCTargetStreamer.h"
  17. #include "PPCXCOFFStreamer.h"
  18. #include "TargetInfo/PowerPCTargetInfo.h"
  19. #include "llvm/ADT/SmallPtrSet.h"
  20. #include "llvm/ADT/StringRef.h"
  21. #include "llvm/ADT/Triple.h"
  22. #include "llvm/BinaryFormat/ELF.h"
  23. #include "llvm/MC/MCAsmBackend.h"
  24. #include "llvm/MC/MCAssembler.h"
  25. #include "llvm/MC/MCCodeEmitter.h"
  26. #include "llvm/MC/MCContext.h"
  27. #include "llvm/MC/MCDwarf.h"
  28. #include "llvm/MC/MCELFStreamer.h"
  29. #include "llvm/MC/MCExpr.h"
  30. #include "llvm/MC/MCInstrAnalysis.h"
  31. #include "llvm/MC/MCInstrInfo.h"
  32. #include "llvm/MC/MCObjectWriter.h"
  33. #include "llvm/MC/MCRegisterInfo.h"
  34. #include "llvm/MC/MCSectionXCOFF.h"
  35. #include "llvm/MC/MCStreamer.h"
  36. #include "llvm/MC/MCSubtargetInfo.h"
  37. #include "llvm/MC/MCSymbol.h"
  38. #include "llvm/MC/MCSymbolELF.h"
  39. #include "llvm/MC/MCSymbolXCOFF.h"
  40. #include "llvm/MC/TargetRegistry.h"
  41. #include "llvm/Support/Casting.h"
  42. #include "llvm/Support/CodeGen.h"
  43. #include "llvm/Support/ErrorHandling.h"
  44. #include "llvm/Support/FormattedStream.h"
  45. #include "llvm/Support/raw_ostream.h"
  46. using namespace llvm;
  47. #define GET_INSTRINFO_MC_DESC
  48. #include "PPCGenInstrInfo.inc"
  49. #define GET_SUBTARGETINFO_MC_DESC
  50. #include "PPCGenSubtargetInfo.inc"
  51. #define GET_REGINFO_MC_DESC
  52. #include "PPCGenRegisterInfo.inc"
  53. PPCTargetStreamer::PPCTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
  54. // Pin the vtable to this file.
  55. PPCTargetStreamer::~PPCTargetStreamer() = default;
  56. static MCInstrInfo *createPPCMCInstrInfo() {
  57. MCInstrInfo *X = new MCInstrInfo();
  58. InitPPCMCInstrInfo(X);
  59. return X;
  60. }
  61. static MCRegisterInfo *createPPCMCRegisterInfo(const Triple &TT) {
  62. bool isPPC64 =
  63. (TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le);
  64. unsigned Flavour = isPPC64 ? 0 : 1;
  65. unsigned RA = isPPC64 ? PPC::LR8 : PPC::LR;
  66. MCRegisterInfo *X = new MCRegisterInfo();
  67. InitPPCMCRegisterInfo(X, RA, Flavour, Flavour);
  68. return X;
  69. }
  70. static MCSubtargetInfo *createPPCMCSubtargetInfo(const Triple &TT,
  71. StringRef CPU, StringRef FS) {
  72. // Set some default feature to MC layer.
  73. std::string FullFS = std::string(FS);
  74. if (TT.isOSAIX()) {
  75. if (!FullFS.empty())
  76. FullFS = "+aix," + FullFS;
  77. else
  78. FullFS = "+aix";
  79. }
  80. return createPPCMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FullFS);
  81. }
  82. static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI,
  83. const Triple &TheTriple,
  84. const MCTargetOptions &Options) {
  85. bool isPPC64 = (TheTriple.getArch() == Triple::ppc64 ||
  86. TheTriple.getArch() == Triple::ppc64le);
  87. MCAsmInfo *MAI;
  88. if (TheTriple.isOSBinFormatXCOFF())
  89. MAI = new PPCXCOFFMCAsmInfo(isPPC64, TheTriple);
  90. else
  91. MAI = new PPCELFMCAsmInfo(isPPC64, TheTriple);
  92. // Initial state of the frame pointer is R1.
  93. unsigned Reg = isPPC64 ? PPC::X1 : PPC::R1;
  94. MCCFIInstruction Inst =
  95. MCCFIInstruction::cfiDefCfa(nullptr, MRI.getDwarfRegNum(Reg, true), 0);
  96. MAI->addInitialFrameState(Inst);
  97. return MAI;
  98. }
  99. static MCStreamer *
  100. createPPCELFStreamer(const Triple &T, MCContext &Context,
  101. std::unique_ptr<MCAsmBackend> &&MAB,
  102. std::unique_ptr<MCObjectWriter> &&OW,
  103. std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll) {
  104. return createPPCELFStreamer(Context, std::move(MAB), std::move(OW),
  105. std::move(Emitter));
  106. }
  107. static MCStreamer *createPPCXCOFFStreamer(
  108. const Triple &T, MCContext &Context, std::unique_ptr<MCAsmBackend> &&MAB,
  109. std::unique_ptr<MCObjectWriter> &&OW,
  110. std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll) {
  111. return createPPCXCOFFStreamer(Context, std::move(MAB), std::move(OW),
  112. std::move(Emitter));
  113. }
  114. namespace {
  115. class PPCTargetAsmStreamer : public PPCTargetStreamer {
  116. formatted_raw_ostream &OS;
  117. public:
  118. PPCTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS)
  119. : PPCTargetStreamer(S), OS(OS) {}
  120. void emitTCEntry(const MCSymbol &S,
  121. MCSymbolRefExpr::VariantKind Kind) override {
  122. if (const MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(&S)) {
  123. MCSymbolXCOFF *TCSym =
  124. cast<MCSectionXCOFF>(Streamer.getCurrentSectionOnly())
  125. ->getQualNameSymbol();
  126. // If the variant kind is VK_PPC_AIX_TLSGDM the entry represents the
  127. // region handle for the symbol, we add the relocation specifier @m.
  128. // If the variant kind is VK_PPC_AIX_TLSGD the entry represents the
  129. // variable offset for the symbol, we add the relocation specifier @gd.
  130. if (Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD ||
  131. Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM)
  132. OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << "@"
  133. << MCSymbolRefExpr::getVariantKindName(Kind) << '\n';
  134. else
  135. OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << '\n';
  136. if (TCSym->hasRename())
  137. Streamer.emitXCOFFRenameDirective(TCSym, TCSym->getSymbolTableName());
  138. return;
  139. }
  140. OS << "\t.tc " << S.getName() << "[TC]," << S.getName() << '\n';
  141. }
  142. void emitMachine(StringRef CPU) override {
  143. OS << "\t.machine " << CPU << '\n';
  144. }
  145. void emitAbiVersion(int AbiVersion) override {
  146. OS << "\t.abiversion " << AbiVersion << '\n';
  147. }
  148. void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override {
  149. const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
  150. OS << "\t.localentry\t";
  151. S->print(OS, MAI);
  152. OS << ", ";
  153. LocalOffset->print(OS, MAI);
  154. OS << '\n';
  155. }
  156. };
  157. class PPCTargetELFStreamer : public PPCTargetStreamer {
  158. public:
  159. PPCTargetELFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {}
  160. MCELFStreamer &getStreamer() {
  161. return static_cast<MCELFStreamer &>(Streamer);
  162. }
  163. void emitTCEntry(const MCSymbol &S,
  164. MCSymbolRefExpr::VariantKind Kind) override {
  165. // Creates a R_PPC64_TOC relocation
  166. Streamer.emitValueToAlignment(8);
  167. Streamer.emitSymbolValue(&S, 8);
  168. }
  169. void emitMachine(StringRef CPU) override {
  170. // FIXME: Is there anything to do in here or does this directive only
  171. // limit the parser?
  172. }
  173. void emitAbiVersion(int AbiVersion) override {
  174. MCAssembler &MCA = getStreamer().getAssembler();
  175. unsigned Flags = MCA.getELFHeaderEFlags();
  176. Flags &= ~ELF::EF_PPC64_ABI;
  177. Flags |= (AbiVersion & ELF::EF_PPC64_ABI);
  178. MCA.setELFHeaderEFlags(Flags);
  179. }
  180. void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override {
  181. MCAssembler &MCA = getStreamer().getAssembler();
  182. // encodePPC64LocalEntryOffset will report an error if it cannot
  183. // encode LocalOffset.
  184. unsigned Encoded = encodePPC64LocalEntryOffset(LocalOffset);
  185. unsigned Other = S->getOther();
  186. Other &= ~ELF::STO_PPC64_LOCAL_MASK;
  187. Other |= Encoded;
  188. S->setOther(Other);
  189. // For GAS compatibility, unless we already saw a .abiversion directive,
  190. // set e_flags to indicate ELFv2 ABI.
  191. unsigned Flags = MCA.getELFHeaderEFlags();
  192. if ((Flags & ELF::EF_PPC64_ABI) == 0)
  193. MCA.setELFHeaderEFlags(Flags | 2);
  194. }
  195. void emitAssignment(MCSymbol *S, const MCExpr *Value) override {
  196. auto *Symbol = cast<MCSymbolELF>(S);
  197. // When encoding an assignment to set symbol A to symbol B, also copy
  198. // the st_other bits encoding the local entry point offset.
  199. if (copyLocalEntry(Symbol, Value))
  200. UpdateOther.insert(Symbol);
  201. else
  202. UpdateOther.erase(Symbol);
  203. }
  204. void finish() override {
  205. for (auto *Sym : UpdateOther)
  206. if (Sym->isVariable())
  207. copyLocalEntry(Sym, Sym->getVariableValue());
  208. // Clear the set of symbols that needs to be updated so the streamer can
  209. // be reused without issues.
  210. UpdateOther.clear();
  211. }
  212. private:
  213. SmallPtrSet<MCSymbolELF *, 32> UpdateOther;
  214. bool copyLocalEntry(MCSymbolELF *D, const MCExpr *S) {
  215. auto *Ref = dyn_cast<const MCSymbolRefExpr>(S);
  216. if (!Ref)
  217. return false;
  218. const auto &RhsSym = cast<MCSymbolELF>(Ref->getSymbol());
  219. unsigned Other = D->getOther();
  220. Other &= ~ELF::STO_PPC64_LOCAL_MASK;
  221. Other |= RhsSym.getOther() & ELF::STO_PPC64_LOCAL_MASK;
  222. D->setOther(Other);
  223. return true;
  224. }
  225. unsigned encodePPC64LocalEntryOffset(const MCExpr *LocalOffset) {
  226. MCAssembler &MCA = getStreamer().getAssembler();
  227. int64_t Offset;
  228. if (!LocalOffset->evaluateAsAbsolute(Offset, MCA))
  229. MCA.getContext().reportError(LocalOffset->getLoc(),
  230. ".localentry expression must be absolute");
  231. switch (Offset) {
  232. default:
  233. MCA.getContext().reportError(
  234. LocalOffset->getLoc(), ".localentry expression must be a power of 2");
  235. return 0;
  236. case 0:
  237. return 0;
  238. case 1:
  239. return 1 << ELF::STO_PPC64_LOCAL_BIT;
  240. case 4:
  241. case 8:
  242. case 16:
  243. case 32:
  244. case 64:
  245. return (int)Log2(Offset) << (int)ELF::STO_PPC64_LOCAL_BIT;
  246. }
  247. }
  248. };
  249. class PPCTargetMachOStreamer : public PPCTargetStreamer {
  250. public:
  251. PPCTargetMachOStreamer(MCStreamer &S) : PPCTargetStreamer(S) {}
  252. void emitTCEntry(const MCSymbol &S,
  253. MCSymbolRefExpr::VariantKind Kind) override {
  254. llvm_unreachable("Unknown pseudo-op: .tc");
  255. }
  256. void emitMachine(StringRef CPU) override {
  257. // FIXME: We should update the CPUType, CPUSubType in the Object file if
  258. // the new values are different from the defaults.
  259. }
  260. void emitAbiVersion(int AbiVersion) override {
  261. llvm_unreachable("Unknown pseudo-op: .abiversion");
  262. }
  263. void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override {
  264. llvm_unreachable("Unknown pseudo-op: .localentry");
  265. }
  266. };
  267. class PPCTargetXCOFFStreamer : public PPCTargetStreamer {
  268. public:
  269. PPCTargetXCOFFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {}
  270. void emitTCEntry(const MCSymbol &S,
  271. MCSymbolRefExpr::VariantKind Kind) override {
  272. const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
  273. const unsigned PointerSize = MAI->getCodePointerSize();
  274. Streamer.emitValueToAlignment(PointerSize);
  275. Streamer.emitValue(MCSymbolRefExpr::create(&S, Kind, Streamer.getContext()),
  276. PointerSize);
  277. }
  278. void emitMachine(StringRef CPU) override {
  279. llvm_unreachable("Machine pseudo-ops are invalid for XCOFF.");
  280. }
  281. void emitAbiVersion(int AbiVersion) override {
  282. llvm_unreachable("ABI-version pseudo-ops are invalid for XCOFF.");
  283. }
  284. void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override {
  285. llvm_unreachable("Local-entry pseudo-ops are invalid for XCOFF.");
  286. }
  287. };
  288. } // end anonymous namespace
  289. static MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
  290. formatted_raw_ostream &OS,
  291. MCInstPrinter *InstPrint,
  292. bool isVerboseAsm) {
  293. return new PPCTargetAsmStreamer(S, OS);
  294. }
  295. static MCTargetStreamer *
  296. createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
  297. const Triple &TT = STI.getTargetTriple();
  298. if (TT.isOSBinFormatELF())
  299. return new PPCTargetELFStreamer(S);
  300. if (TT.isOSBinFormatXCOFF())
  301. return new PPCTargetXCOFFStreamer(S);
  302. return new PPCTargetMachOStreamer(S);
  303. }
  304. static MCInstPrinter *createPPCMCInstPrinter(const Triple &T,
  305. unsigned SyntaxVariant,
  306. const MCAsmInfo &MAI,
  307. const MCInstrInfo &MII,
  308. const MCRegisterInfo &MRI) {
  309. return new PPCInstPrinter(MAI, MII, MRI, T);
  310. }
  311. namespace {
  312. class PPCMCInstrAnalysis : public MCInstrAnalysis {
  313. public:
  314. explicit PPCMCInstrAnalysis(const MCInstrInfo *Info)
  315. : MCInstrAnalysis(Info) {}
  316. bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
  317. uint64_t &Target) const override {
  318. unsigned NumOps = Inst.getNumOperands();
  319. if (NumOps == 0 ||
  320. Info->get(Inst.getOpcode()).OpInfo[NumOps - 1].OperandType !=
  321. MCOI::OPERAND_PCREL)
  322. return false;
  323. Target = Addr + Inst.getOperand(NumOps - 1).getImm() * Size;
  324. return true;
  325. }
  326. };
  327. } // end anonymous namespace
  328. static MCInstrAnalysis *createPPCMCInstrAnalysis(const MCInstrInfo *Info) {
  329. return new PPCMCInstrAnalysis(Info);
  330. }
  331. extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetMC() {
  332. for (Target *T : {&getThePPC32Target(), &getThePPC32LETarget(),
  333. &getThePPC64Target(), &getThePPC64LETarget()}) {
  334. // Register the MC asm info.
  335. RegisterMCAsmInfoFn C(*T, createPPCMCAsmInfo);
  336. // Register the MC instruction info.
  337. TargetRegistry::RegisterMCInstrInfo(*T, createPPCMCInstrInfo);
  338. // Register the MC register info.
  339. TargetRegistry::RegisterMCRegInfo(*T, createPPCMCRegisterInfo);
  340. // Register the MC subtarget info.
  341. TargetRegistry::RegisterMCSubtargetInfo(*T, createPPCMCSubtargetInfo);
  342. // Register the MC instruction analyzer.
  343. TargetRegistry::RegisterMCInstrAnalysis(*T, createPPCMCInstrAnalysis);
  344. // Register the MC Code Emitter
  345. TargetRegistry::RegisterMCCodeEmitter(*T, createPPCMCCodeEmitter);
  346. // Register the asm backend.
  347. TargetRegistry::RegisterMCAsmBackend(*T, createPPCAsmBackend);
  348. // Register the elf streamer.
  349. TargetRegistry::RegisterELFStreamer(*T, createPPCELFStreamer);
  350. // Register the XCOFF streamer.
  351. TargetRegistry::RegisterXCOFFStreamer(*T, createPPCXCOFFStreamer);
  352. // Register the object target streamer.
  353. TargetRegistry::RegisterObjectTargetStreamer(*T,
  354. createObjectTargetStreamer);
  355. // Register the asm target streamer.
  356. TargetRegistry::RegisterAsmTargetStreamer(*T, createAsmTargetStreamer);
  357. // Register the MCInstPrinter.
  358. TargetRegistry::RegisterMCInstPrinter(*T, createPPCMCInstPrinter);
  359. }
  360. }