PPCMCTargetDesc.cpp 15 KB

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