MCAsmStreamer.cpp 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372
  1. //===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output --------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/MC/MCStreamer.h"
  10. #include "llvm/ADT/STLExtras.h"
  11. #include "llvm/ADT/SmallString.h"
  12. #include "llvm/ADT/StringExtras.h"
  13. #include "llvm/ADT/Twine.h"
  14. #include "llvm/MC/MCAsmBackend.h"
  15. #include "llvm/MC/MCAsmInfo.h"
  16. #include "llvm/MC/MCCodeEmitter.h"
  17. #include "llvm/MC/MCContext.h"
  18. #include "llvm/MC/MCExpr.h"
  19. #include "llvm/MC/MCFixupKindInfo.h"
  20. #include "llvm/MC/MCInst.h"
  21. #include "llvm/MC/MCInstPrinter.h"
  22. #include "llvm/MC/MCObjectFileInfo.h"
  23. #include "llvm/MC/MCRegisterInfo.h"
  24. #include "llvm/MC/MCSectionCOFF.h"
  25. #include "llvm/MC/MCSectionMachO.h"
  26. #include "llvm/MC/MCSymbolELF.h"
  27. #include "llvm/Support/CommandLine.h"
  28. #include "llvm/Support/ErrorHandling.h"
  29. #include "llvm/Support/Format.h"
  30. #include "llvm/Support/FormattedStream.h"
  31. #include "llvm/Support/MathExtras.h"
  32. #include "llvm/Support/Path.h"
  33. #include <cctype>
  34. using namespace llvm;
  35. namespace {
  36. class MCAsmStreamer final : public MCStreamer {
  37. std::unique_ptr<formatted_raw_ostream> OSOwner;
  38. formatted_raw_ostream &OS;
  39. const MCAsmInfo *MAI;
  40. std::unique_ptr<MCInstPrinter> InstPrinter;
  41. std::unique_ptr<MCCodeEmitter> Emitter;
  42. std::unique_ptr<MCAsmBackend> AsmBackend;
  43. SmallString<128> CommentToEmit;
  44. raw_svector_ostream CommentStream;
  45. unsigned IsVerboseAsm : 1;
  46. unsigned ShowInst : 1;
  47. unsigned UseDwarfDirectory : 1;
  48. void EmitRegisterName(int64_t Register);
  49. void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
  50. void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
  51. public:
  52. MCAsmStreamer(MCContext &Context, std::unique_ptr<formatted_raw_ostream> os,
  53. bool isVerboseAsm, bool useDwarfDirectory,
  54. MCInstPrinter *printer, MCCodeEmitter *emitter,
  55. MCAsmBackend *asmbackend, bool showInst)
  56. : MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner),
  57. MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter),
  58. AsmBackend(asmbackend), CommentStream(CommentToEmit),
  59. IsVerboseAsm(isVerboseAsm), ShowInst(showInst),
  60. UseDwarfDirectory(useDwarfDirectory) {
  61. assert(InstPrinter);
  62. if (IsVerboseAsm)
  63. InstPrinter->setCommentStream(CommentStream);
  64. }
  65. inline void EmitEOL() {
  66. // If we don't have any comments, just emit a \n.
  67. if (!IsVerboseAsm) {
  68. OS << '\n';
  69. return;
  70. }
  71. EmitCommentsAndEOL();
  72. }
  73. void EmitCommentsAndEOL();
  74. /// isVerboseAsm - Return true if this streamer supports verbose assembly at
  75. /// all.
  76. bool isVerboseAsm() const override { return IsVerboseAsm; }
  77. /// hasRawTextSupport - We support EmitRawText.
  78. bool hasRawTextSupport() const override { return true; }
  79. /// AddComment - Add a comment that can be emitted to the generated .s
  80. /// file if applicable as a QoI issue to make the output of the compiler
  81. /// more readable. This only affects the MCAsmStreamer, and only when
  82. /// verbose assembly output is enabled.
  83. void AddComment(const Twine &T) override;
  84. /// AddEncodingComment - Add a comment showing the encoding of an instruction.
  85. void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &);
  86. /// GetCommentOS - Return a raw_ostream that comments can be written to.
  87. /// Unlike AddComment, you are required to terminate comments with \n if you
  88. /// use this method.
  89. raw_ostream &GetCommentOS() override {
  90. if (!IsVerboseAsm)
  91. return nulls(); // Discard comments unless in verbose asm mode.
  92. return CommentStream;
  93. }
  94. void emitRawComment(const Twine &T, bool TabPrefix = true) override;
  95. /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
  96. void AddBlankLine() override {
  97. EmitEOL();
  98. }
  99. /// @name MCStreamer Interface
  100. /// @{
  101. void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
  102. void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
  103. void EmitLabel(MCSymbol *Symbol) override;
  104. void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
  105. void EmitLinkerOptions(ArrayRef<std::string> Options) override;
  106. void EmitDataRegion(MCDataRegionType Kind) override;
  107. void EmitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
  108. unsigned Update) override;
  109. void EmitThumbFunc(MCSymbol *Func) override;
  110. void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
  111. void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
  112. bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
  113. void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
  114. void BeginCOFFSymbolDef(const MCSymbol *Symbol) override;
  115. void EmitCOFFSymbolStorageClass(int StorageClass) override;
  116. void EmitCOFFSymbolType(int Type) override;
  117. void EndCOFFSymbolDef() override;
  118. void EmitCOFFSafeSEH(MCSymbol const *Symbol) override;
  119. void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
  120. void EmitCOFFSecRel32(MCSymbol const *Symbol) override;
  121. void emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) override;
  122. void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
  123. unsigned ByteAlignment) override;
  124. /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
  125. ///
  126. /// @param Symbol - The common symbol to emit.
  127. /// @param Size - The size of the common symbol.
  128. /// @param ByteAlignment - The alignment of the common symbol in bytes.
  129. void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
  130. unsigned ByteAlignment) override;
  131. void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
  132. uint64_t Size = 0, unsigned ByteAlignment = 0) override;
  133. void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
  134. unsigned ByteAlignment = 0) override;
  135. void EmitBytes(StringRef Data) override;
  136. void EmitValueImpl(const MCExpr *Value, unsigned Size,
  137. const SMLoc &Loc = SMLoc()) override;
  138. void EmitIntValue(uint64_t Value, unsigned Size) override;
  139. void EmitULEB128Value(const MCExpr *Value) override;
  140. void EmitSLEB128Value(const MCExpr *Value) override;
  141. void EmitGPRel64Value(const MCExpr *Value) override;
  142. void EmitGPRel32Value(const MCExpr *Value) override;
  143. void EmitFill(uint64_t NumBytes, uint8_t FillValue) override;
  144. void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
  145. unsigned ValueSize = 1,
  146. unsigned MaxBytesToEmit = 0) override;
  147. void EmitCodeAlignment(unsigned ByteAlignment,
  148. unsigned MaxBytesToEmit = 0) override;
  149. bool EmitValueToOffset(const MCExpr *Offset,
  150. unsigned char Value = 0) override;
  151. void EmitFileDirective(StringRef Filename) override;
  152. unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
  153. StringRef Filename,
  154. unsigned CUID = 0) override;
  155. void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
  156. unsigned Column, unsigned Flags,
  157. unsigned Isa, unsigned Discriminator,
  158. StringRef FileName) override;
  159. MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
  160. void EmitIdent(StringRef IdentString) override;
  161. void EmitCFISections(bool EH, bool Debug) override;
  162. void EmitCFIDefCfa(int64_t Register, int64_t Offset) override;
  163. void EmitCFIDefCfaOffset(int64_t Offset) override;
  164. void EmitCFIDefCfaRegister(int64_t Register) override;
  165. void EmitCFIOffset(int64_t Register, int64_t Offset) override;
  166. void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) override;
  167. void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) override;
  168. void EmitCFIRememberState() override;
  169. void EmitCFIRestoreState() override;
  170. void EmitCFISameValue(int64_t Register) override;
  171. void EmitCFIRelOffset(int64_t Register, int64_t Offset) override;
  172. void EmitCFIAdjustCfaOffset(int64_t Adjustment) override;
  173. void EmitCFISignalFrame() override;
  174. void EmitCFIUndefined(int64_t Register) override;
  175. void EmitCFIRegister(int64_t Register1, int64_t Register2) override;
  176. void EmitCFIWindowSave() override;
  177. void EmitWinCFIStartProc(const MCSymbol *Symbol) override;
  178. void EmitWinCFIEndProc() override;
  179. void EmitWinCFIStartChained() override;
  180. void EmitWinCFIEndChained() override;
  181. void EmitWinCFIPushReg(unsigned Register) override;
  182. void EmitWinCFISetFrame(unsigned Register, unsigned Offset) override;
  183. void EmitWinCFIAllocStack(unsigned Size) override;
  184. void EmitWinCFISaveReg(unsigned Register, unsigned Offset) override;
  185. void EmitWinCFISaveXMM(unsigned Register, unsigned Offset) override;
  186. void EmitWinCFIPushFrame(bool Code) override;
  187. void EmitWinCFIEndProlog() override;
  188. void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) override;
  189. void EmitWinEHHandlerData() override;
  190. void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
  191. void EmitBundleAlignMode(unsigned AlignPow2) override;
  192. void EmitBundleLock(bool AlignToEnd) override;
  193. void EmitBundleUnlock() override;
  194. /// EmitRawText - If this file is backed by an assembly streamer, this dumps
  195. /// the specified string in the output .s file. This capability is
  196. /// indicated by the hasRawTextSupport() predicate.
  197. void EmitRawTextImpl(StringRef String) override;
  198. void FinishImpl() override;
  199. };
  200. } // end anonymous namespace.
  201. /// AddComment - Add a comment that can be emitted to the generated .s
  202. /// file if applicable as a QoI issue to make the output of the compiler
  203. /// more readable. This only affects the MCAsmStreamer, and only when
  204. /// verbose assembly output is enabled.
  205. void MCAsmStreamer::AddComment(const Twine &T) {
  206. if (!IsVerboseAsm) return;
  207. // Make sure that CommentStream is flushed.
  208. CommentStream.flush();
  209. T.toVector(CommentToEmit);
  210. // Each comment goes on its own line.
  211. CommentToEmit.push_back('\n');
  212. // Tell the comment stream that the vector changed underneath it.
  213. CommentStream.resync();
  214. }
  215. void MCAsmStreamer::EmitCommentsAndEOL() {
  216. if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
  217. OS << '\n';
  218. return;
  219. }
  220. CommentStream.flush();
  221. StringRef Comments = CommentToEmit;
  222. assert(Comments.back() == '\n' &&
  223. "Comment array not newline terminated");
  224. do {
  225. // Emit a line of comments.
  226. OS.PadToColumn(MAI->getCommentColumn());
  227. size_t Position = Comments.find('\n');
  228. OS << MAI->getCommentString() << ' ' << Comments.substr(0, Position) <<'\n';
  229. Comments = Comments.substr(Position+1);
  230. } while (!Comments.empty());
  231. CommentToEmit.clear();
  232. // Tell the comment stream that the vector changed underneath it.
  233. CommentStream.resync();
  234. }
  235. static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
  236. assert(Bytes && "Invalid size!");
  237. return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
  238. }
  239. void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) {
  240. if (TabPrefix)
  241. OS << '\t';
  242. OS << MAI->getCommentString() << T;
  243. EmitEOL();
  244. }
  245. void MCAsmStreamer::ChangeSection(MCSection *Section,
  246. const MCExpr *Subsection) {
  247. assert(Section && "Cannot switch to a null section!");
  248. Section->PrintSwitchToSection(*MAI, OS, Subsection);
  249. }
  250. void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
  251. assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
  252. MCStreamer::EmitLabel(Symbol);
  253. Symbol->print(OS, MAI);
  254. OS << MAI->getLabelSuffix();
  255. EmitEOL();
  256. }
  257. void MCAsmStreamer::EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {
  258. StringRef str = MCLOHIdToName(Kind);
  259. #ifndef NDEBUG
  260. int NbArgs = MCLOHIdToNbArgs(Kind);
  261. assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");
  262. assert(str != "" && "Invalid LOH name");
  263. #endif
  264. OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";
  265. bool IsFirst = true;
  266. for (MCLOHArgs::const_iterator It = Args.begin(), EndIt = Args.end();
  267. It != EndIt; ++It) {
  268. if (!IsFirst)
  269. OS << ", ";
  270. IsFirst = false;
  271. (*It)->print(OS, MAI);
  272. }
  273. EmitEOL();
  274. }
  275. void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
  276. switch (Flag) {
  277. case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
  278. case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
  279. case MCAF_Code16: OS << '\t'<< MAI->getCode16Directive();break;
  280. case MCAF_Code32: OS << '\t'<< MAI->getCode32Directive();break;
  281. case MCAF_Code64: OS << '\t'<< MAI->getCode64Directive();break;
  282. }
  283. EmitEOL();
  284. }
  285. void MCAsmStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
  286. assert(!Options.empty() && "At least one option is required!");
  287. OS << "\t.linker_option \"" << Options[0] << '"';
  288. for (ArrayRef<std::string>::iterator it = Options.begin() + 1,
  289. ie = Options.end(); it != ie; ++it) {
  290. OS << ", " << '"' << *it << '"';
  291. }
  292. OS << "\n";
  293. }
  294. void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
  295. if (!MAI->doesSupportDataRegionDirectives())
  296. return;
  297. switch (Kind) {
  298. case MCDR_DataRegion: OS << "\t.data_region"; break;
  299. case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
  300. case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
  301. case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
  302. case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
  303. }
  304. EmitEOL();
  305. }
  306. void MCAsmStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
  307. unsigned Minor, unsigned Update) {
  308. switch (Kind) {
  309. case MCVM_IOSVersionMin: OS << "\t.ios_version_min"; break;
  310. case MCVM_OSXVersionMin: OS << "\t.macosx_version_min"; break;
  311. }
  312. OS << " " << Major << ", " << Minor;
  313. if (Update)
  314. OS << ", " << Update;
  315. EmitEOL();
  316. }
  317. void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
  318. // This needs to emit to a temporary string to get properly quoted
  319. // MCSymbols when they have spaces in them.
  320. OS << "\t.thumb_func";
  321. // Only Mach-O hasSubsectionsViaSymbols()
  322. if (MAI->hasSubsectionsViaSymbols()) {
  323. OS << '\t';
  324. Func->print(OS, MAI);
  325. }
  326. EmitEOL();
  327. }
  328. void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
  329. Symbol->print(OS, MAI);
  330. OS << " = ";
  331. Value->print(OS, MAI);
  332. EmitEOL();
  333. MCStreamer::EmitAssignment(Symbol, Value);
  334. }
  335. void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
  336. OS << ".weakref ";
  337. Alias->print(OS, MAI);
  338. OS << ", ";
  339. Symbol->print(OS, MAI);
  340. EmitEOL();
  341. }
  342. bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
  343. MCSymbolAttr Attribute) {
  344. switch (Attribute) {
  345. case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
  346. case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
  347. case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
  348. case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
  349. case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
  350. case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
  351. case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
  352. case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
  353. if (!MAI->hasDotTypeDotSizeDirective())
  354. return false; // Symbol attribute not supported
  355. OS << "\t.type\t";
  356. Symbol->print(OS, MAI);
  357. OS << ',' << ((MAI->getCommentString()[0] != '@') ? '@' : '%');
  358. switch (Attribute) {
  359. default: return false;
  360. case MCSA_ELF_TypeFunction: OS << "function"; break;
  361. case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
  362. case MCSA_ELF_TypeObject: OS << "object"; break;
  363. case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
  364. case MCSA_ELF_TypeCommon: OS << "common"; break;
  365. case MCSA_ELF_TypeNoType: OS << "no_type"; break;
  366. case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
  367. }
  368. EmitEOL();
  369. return true;
  370. case MCSA_Global: // .globl/.global
  371. OS << MAI->getGlobalDirective();
  372. break;
  373. case MCSA_Hidden: OS << "\t.hidden\t"; break;
  374. case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
  375. case MCSA_Internal: OS << "\t.internal\t"; break;
  376. case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
  377. case MCSA_Local: OS << "\t.local\t"; break;
  378. case MCSA_NoDeadStrip:
  379. if (!MAI->hasNoDeadStrip())
  380. return false;
  381. OS << "\t.no_dead_strip\t";
  382. break;
  383. case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
  384. case MCSA_PrivateExtern:
  385. OS << "\t.private_extern\t";
  386. break;
  387. case MCSA_Protected: OS << "\t.protected\t"; break;
  388. case MCSA_Reference: OS << "\t.reference\t"; break;
  389. case MCSA_Weak: OS << MAI->getWeakDirective(); break;
  390. case MCSA_WeakDefinition:
  391. OS << "\t.weak_definition\t";
  392. break;
  393. // .weak_reference
  394. case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break;
  395. case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
  396. }
  397. Symbol->print(OS, MAI);
  398. EmitEOL();
  399. return true;
  400. }
  401. void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
  402. OS << ".desc" << ' ';
  403. Symbol->print(OS, MAI);
  404. OS << ',' << DescValue;
  405. EmitEOL();
  406. }
  407. void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
  408. OS << "\t.def\t ";
  409. Symbol->print(OS, MAI);
  410. OS << ';';
  411. EmitEOL();
  412. }
  413. void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
  414. OS << "\t.scl\t" << StorageClass << ';';
  415. EmitEOL();
  416. }
  417. void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
  418. OS << "\t.type\t" << Type << ';';
  419. EmitEOL();
  420. }
  421. void MCAsmStreamer::EndCOFFSymbolDef() {
  422. OS << "\t.endef";
  423. EmitEOL();
  424. }
  425. void MCAsmStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
  426. OS << "\t.safeseh\t";
  427. Symbol->print(OS, MAI);
  428. EmitEOL();
  429. }
  430. void MCAsmStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
  431. OS << "\t.secidx\t";
  432. Symbol->print(OS, MAI);
  433. EmitEOL();
  434. }
  435. void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
  436. OS << "\t.secrel32\t";
  437. Symbol->print(OS, MAI);
  438. EmitEOL();
  439. }
  440. void MCAsmStreamer::emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) {
  441. assert(MAI->hasDotTypeDotSizeDirective());
  442. OS << "\t.size\t";
  443. Symbol->print(OS, MAI);
  444. OS << ", ";
  445. Value->print(OS, MAI);
  446. OS << '\n';
  447. }
  448. void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
  449. unsigned ByteAlignment) {
  450. // Common symbols do not belong to any actual section.
  451. AssignSection(Symbol, nullptr);
  452. OS << "\t.comm\t";
  453. Symbol->print(OS, MAI);
  454. OS << ',' << Size;
  455. if (ByteAlignment != 0) {
  456. if (MAI->getCOMMDirectiveAlignmentIsInBytes())
  457. OS << ',' << ByteAlignment;
  458. else
  459. OS << ',' << Log2_32(ByteAlignment);
  460. }
  461. EmitEOL();
  462. }
  463. /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
  464. ///
  465. /// @param Symbol - The common symbol to emit.
  466. /// @param Size - The size of the common symbol.
  467. void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
  468. unsigned ByteAlign) {
  469. // Common symbols do not belong to any actual section.
  470. AssignSection(Symbol, nullptr);
  471. OS << "\t.lcomm\t";
  472. Symbol->print(OS, MAI);
  473. OS << ',' << Size;
  474. if (ByteAlign > 1) {
  475. switch (MAI->getLCOMMDirectiveAlignmentType()) {
  476. case LCOMM::NoAlignment:
  477. llvm_unreachable("alignment not supported on .lcomm!");
  478. case LCOMM::ByteAlignment:
  479. OS << ',' << ByteAlign;
  480. break;
  481. case LCOMM::Log2Alignment:
  482. assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
  483. OS << ',' << Log2_32(ByteAlign);
  484. break;
  485. }
  486. }
  487. EmitEOL();
  488. }
  489. void MCAsmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
  490. uint64_t Size, unsigned ByteAlignment) {
  491. if (Symbol)
  492. AssignSection(Symbol, Section);
  493. // Note: a .zerofill directive does not switch sections.
  494. OS << ".zerofill ";
  495. // This is a mach-o specific directive.
  496. const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
  497. OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
  498. if (Symbol) {
  499. OS << ',';
  500. Symbol->print(OS, MAI);
  501. OS << ',' << Size;
  502. if (ByteAlignment != 0)
  503. OS << ',' << Log2_32(ByteAlignment);
  504. }
  505. EmitEOL();
  506. }
  507. // .tbss sym, size, align
  508. // This depends that the symbol has already been mangled from the original,
  509. // e.g. _a.
  510. void MCAsmStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
  511. uint64_t Size, unsigned ByteAlignment) {
  512. AssignSection(Symbol, Section);
  513. assert(Symbol && "Symbol shouldn't be NULL!");
  514. // Instead of using the Section we'll just use the shortcut.
  515. // This is a mach-o specific directive and section.
  516. OS << ".tbss ";
  517. Symbol->print(OS, MAI);
  518. OS << ", " << Size;
  519. // Output align if we have it. We default to 1 so don't bother printing
  520. // that.
  521. if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
  522. EmitEOL();
  523. }
  524. static inline char toOctal(int X) { return (X&7)+'0'; }
  525. static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
  526. OS << '"';
  527. for (unsigned i = 0, e = Data.size(); i != e; ++i) {
  528. unsigned char C = Data[i];
  529. if (C == '"' || C == '\\') {
  530. OS << '\\' << (char)C;
  531. continue;
  532. }
  533. if (isprint((unsigned char)C)) {
  534. OS << (char)C;
  535. continue;
  536. }
  537. switch (C) {
  538. case '\b': OS << "\\b"; break;
  539. case '\f': OS << "\\f"; break;
  540. case '\n': OS << "\\n"; break;
  541. case '\r': OS << "\\r"; break;
  542. case '\t': OS << "\\t"; break;
  543. default:
  544. OS << '\\';
  545. OS << toOctal(C >> 6);
  546. OS << toOctal(C >> 3);
  547. OS << toOctal(C >> 0);
  548. break;
  549. }
  550. }
  551. OS << '"';
  552. }
  553. void MCAsmStreamer::EmitBytes(StringRef Data) {
  554. assert(getCurrentSection().first &&
  555. "Cannot emit contents before setting section!");
  556. if (Data.empty()) return;
  557. if (Data.size() == 1) {
  558. OS << MAI->getData8bitsDirective();
  559. OS << (unsigned)(unsigned char)Data[0];
  560. EmitEOL();
  561. return;
  562. }
  563. // If the data ends with 0 and the target supports .asciz, use it, otherwise
  564. // use .ascii
  565. if (MAI->getAscizDirective() && Data.back() == 0) {
  566. OS << MAI->getAscizDirective();
  567. Data = Data.substr(0, Data.size()-1);
  568. } else {
  569. OS << MAI->getAsciiDirective();
  570. }
  571. PrintQuotedString(Data, OS);
  572. EmitEOL();
  573. }
  574. void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
  575. EmitValue(MCConstantExpr::create(Value, getContext()), Size);
  576. }
  577. void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
  578. const SMLoc &Loc) {
  579. assert(Size <= 8 && "Invalid size");
  580. assert(getCurrentSection().first &&
  581. "Cannot emit contents before setting section!");
  582. const char *Directive = nullptr;
  583. switch (Size) {
  584. default: break;
  585. case 1: Directive = MAI->getData8bitsDirective(); break;
  586. case 2: Directive = MAI->getData16bitsDirective(); break;
  587. case 4: Directive = MAI->getData32bitsDirective(); break;
  588. case 8: Directive = MAI->getData64bitsDirective(); break;
  589. }
  590. if (!Directive) {
  591. int64_t IntValue;
  592. if (!Value->evaluateAsAbsolute(IntValue))
  593. report_fatal_error("Don't know how to emit this value.");
  594. // We couldn't handle the requested integer size so we fallback by breaking
  595. // the request down into several, smaller, integers. Since sizes greater
  596. // than eight are invalid and size equivalent to eight should have been
  597. // handled earlier, we use four bytes as our largest piece of granularity.
  598. bool IsLittleEndian = MAI->isLittleEndian();
  599. for (unsigned Emitted = 0; Emitted != Size;) {
  600. unsigned Remaining = Size - Emitted;
  601. // The size of our partial emission must be a power of two less than
  602. // eight.
  603. unsigned EmissionSize = PowerOf2Floor(Remaining);
  604. if (EmissionSize > 4)
  605. EmissionSize = 4;
  606. // Calculate the byte offset of our partial emission taking into account
  607. // the endianness of the target.
  608. unsigned ByteOffset =
  609. IsLittleEndian ? Emitted : (Remaining - EmissionSize);
  610. uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
  611. // We truncate our partial emission to fit within the bounds of the
  612. // emission domain. This produces nicer output and silences potential
  613. // truncation warnings when round tripping through another assembler.
  614. uint64_t Shift = 64 - EmissionSize * 8;
  615. assert(Shift < static_cast<uint64_t>(
  616. std::numeric_limits<unsigned long long>::digits) &&
  617. "undefined behavior");
  618. ValueToEmit &= ~0ULL >> Shift;
  619. EmitIntValue(ValueToEmit, EmissionSize);
  620. Emitted += EmissionSize;
  621. }
  622. return;
  623. }
  624. assert(Directive && "Invalid size for machine code value!");
  625. OS << Directive;
  626. Value->print(OS, MAI);
  627. EmitEOL();
  628. }
  629. void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
  630. int64_t IntValue;
  631. if (Value->evaluateAsAbsolute(IntValue)) {
  632. EmitULEB128IntValue(IntValue);
  633. return;
  634. }
  635. OS << ".uleb128 ";
  636. Value->print(OS, MAI);
  637. EmitEOL();
  638. }
  639. void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
  640. int64_t IntValue;
  641. if (Value->evaluateAsAbsolute(IntValue)) {
  642. EmitSLEB128IntValue(IntValue);
  643. return;
  644. }
  645. OS << ".sleb128 ";
  646. Value->print(OS, MAI);
  647. EmitEOL();
  648. }
  649. void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
  650. assert(MAI->getGPRel64Directive() != nullptr);
  651. OS << MAI->getGPRel64Directive();
  652. Value->print(OS, MAI);
  653. EmitEOL();
  654. }
  655. void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
  656. assert(MAI->getGPRel32Directive() != nullptr);
  657. OS << MAI->getGPRel32Directive();
  658. Value->print(OS, MAI);
  659. EmitEOL();
  660. }
  661. /// EmitFill - Emit NumBytes bytes worth of the value specified by
  662. /// FillValue. This implements directives such as '.space'.
  663. void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
  664. if (NumBytes == 0) return;
  665. if (const char *ZeroDirective = MAI->getZeroDirective()) {
  666. OS << ZeroDirective << NumBytes;
  667. if (FillValue != 0)
  668. OS << ',' << (int)FillValue;
  669. EmitEOL();
  670. return;
  671. }
  672. // Emit a byte at a time.
  673. MCStreamer::EmitFill(NumBytes, FillValue);
  674. }
  675. void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
  676. unsigned ValueSize,
  677. unsigned MaxBytesToEmit) {
  678. // Some assemblers don't support non-power of two alignments, so we always
  679. // emit alignments as a power of two if possible.
  680. if (isPowerOf2_32(ByteAlignment)) {
  681. switch (ValueSize) {
  682. default:
  683. llvm_unreachable("Invalid size for machine code value!");
  684. case 1:
  685. OS << "\t.align\t";
  686. break;
  687. case 2:
  688. OS << ".p2alignw ";
  689. break;
  690. case 4:
  691. OS << ".p2alignl ";
  692. break;
  693. case 8:
  694. llvm_unreachable("Unsupported alignment size!");
  695. }
  696. if (MAI->getAlignmentIsInBytes())
  697. OS << ByteAlignment;
  698. else
  699. OS << Log2_32(ByteAlignment);
  700. if (Value || MaxBytesToEmit) {
  701. OS << ", 0x";
  702. OS.write_hex(truncateToSize(Value, ValueSize));
  703. if (MaxBytesToEmit)
  704. OS << ", " << MaxBytesToEmit;
  705. }
  706. EmitEOL();
  707. return;
  708. }
  709. // Non-power of two alignment. This is not widely supported by assemblers.
  710. // FIXME: Parameterize this based on MAI.
  711. switch (ValueSize) {
  712. default: llvm_unreachable("Invalid size for machine code value!");
  713. case 1: OS << ".balign"; break;
  714. case 2: OS << ".balignw"; break;
  715. case 4: OS << ".balignl"; break;
  716. case 8: llvm_unreachable("Unsupported alignment size!");
  717. }
  718. OS << ' ' << ByteAlignment;
  719. OS << ", " << truncateToSize(Value, ValueSize);
  720. if (MaxBytesToEmit)
  721. OS << ", " << MaxBytesToEmit;
  722. EmitEOL();
  723. }
  724. void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
  725. unsigned MaxBytesToEmit) {
  726. // Emit with a text fill value.
  727. EmitValueToAlignment(ByteAlignment, MAI->getTextAlignFillValue(),
  728. 1, MaxBytesToEmit);
  729. }
  730. bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
  731. unsigned char Value) {
  732. // FIXME: Verify that Offset is associated with the current section.
  733. OS << ".org ";
  734. Offset->print(OS, MAI);
  735. OS << ", " << (unsigned)Value;
  736. EmitEOL();
  737. return false;
  738. }
  739. void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
  740. assert(MAI->hasSingleParameterDotFile());
  741. OS << "\t.file\t";
  742. PrintQuotedString(Filename, OS);
  743. EmitEOL();
  744. }
  745. unsigned MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo,
  746. StringRef Directory,
  747. StringRef Filename,
  748. unsigned CUID) {
  749. assert(CUID == 0);
  750. MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
  751. unsigned NumFiles = Table.getMCDwarfFiles().size();
  752. FileNo = Table.getFile(Directory, Filename, FileNo);
  753. if (FileNo == 0)
  754. return 0;
  755. if (NumFiles == Table.getMCDwarfFiles().size())
  756. return FileNo;
  757. SmallString<128> FullPathName;
  758. if (!UseDwarfDirectory && !Directory.empty()) {
  759. if (sys::path::is_absolute(Filename))
  760. Directory = "";
  761. else {
  762. FullPathName = Directory;
  763. sys::path::append(FullPathName, Filename);
  764. Directory = "";
  765. Filename = FullPathName;
  766. }
  767. }
  768. OS << "\t.file\t" << FileNo << ' ';
  769. if (!Directory.empty()) {
  770. PrintQuotedString(Directory, OS);
  771. OS << ' ';
  772. }
  773. PrintQuotedString(Filename, OS);
  774. EmitEOL();
  775. return FileNo;
  776. }
  777. void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
  778. unsigned Column, unsigned Flags,
  779. unsigned Isa,
  780. unsigned Discriminator,
  781. StringRef FileName) {
  782. OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
  783. if (Flags & DWARF2_FLAG_BASIC_BLOCK)
  784. OS << " basic_block";
  785. if (Flags & DWARF2_FLAG_PROLOGUE_END)
  786. OS << " prologue_end";
  787. if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
  788. OS << " epilogue_begin";
  789. unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
  790. if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
  791. OS << " is_stmt ";
  792. if (Flags & DWARF2_FLAG_IS_STMT)
  793. OS << "1";
  794. else
  795. OS << "0";
  796. }
  797. if (Isa)
  798. OS << " isa " << Isa;
  799. if (Discriminator)
  800. OS << " discriminator " << Discriminator;
  801. if (IsVerboseAsm) {
  802. OS.PadToColumn(MAI->getCommentColumn());
  803. OS << MAI->getCommentString() << ' ' << FileName << ':'
  804. << Line << ':' << Column;
  805. }
  806. EmitEOL();
  807. this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
  808. Isa, Discriminator, FileName);
  809. }
  810. MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
  811. // Always use the zeroth line table, since asm syntax only supports one line
  812. // table for now.
  813. return MCStreamer::getDwarfLineTableSymbol(0);
  814. }
  815. void MCAsmStreamer::EmitIdent(StringRef IdentString) {
  816. assert(MAI->hasIdentDirective() && ".ident directive not supported");
  817. OS << "\t.ident\t";
  818. PrintQuotedString(IdentString, OS);
  819. EmitEOL();
  820. }
  821. void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
  822. MCStreamer::EmitCFISections(EH, Debug);
  823. OS << "\t.cfi_sections ";
  824. if (EH) {
  825. OS << ".eh_frame";
  826. if (Debug)
  827. OS << ", .debug_frame";
  828. } else if (Debug) {
  829. OS << ".debug_frame";
  830. }
  831. EmitEOL();
  832. }
  833. void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
  834. OS << "\t.cfi_startproc";
  835. if (Frame.IsSimple)
  836. OS << " simple";
  837. EmitEOL();
  838. }
  839. void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
  840. MCStreamer::EmitCFIEndProcImpl(Frame);
  841. OS << "\t.cfi_endproc";
  842. EmitEOL();
  843. }
  844. void MCAsmStreamer::EmitRegisterName(int64_t Register) {
  845. if (!MAI->useDwarfRegNumForCFI()) {
  846. const MCRegisterInfo *MRI = getContext().getRegisterInfo();
  847. unsigned LLVMRegister = MRI->getLLVMRegNum(Register, true);
  848. InstPrinter->printRegName(OS, LLVMRegister);
  849. } else {
  850. OS << Register;
  851. }
  852. }
  853. void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
  854. MCStreamer::EmitCFIDefCfa(Register, Offset);
  855. OS << "\t.cfi_def_cfa ";
  856. EmitRegisterName(Register);
  857. OS << ", " << Offset;
  858. EmitEOL();
  859. }
  860. void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
  861. MCStreamer::EmitCFIDefCfaOffset(Offset);
  862. OS << "\t.cfi_def_cfa_offset " << Offset;
  863. EmitEOL();
  864. }
  865. void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
  866. MCStreamer::EmitCFIDefCfaRegister(Register);
  867. OS << "\t.cfi_def_cfa_register ";
  868. EmitRegisterName(Register);
  869. EmitEOL();
  870. }
  871. void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
  872. this->MCStreamer::EmitCFIOffset(Register, Offset);
  873. OS << "\t.cfi_offset ";
  874. EmitRegisterName(Register);
  875. OS << ", " << Offset;
  876. EmitEOL();
  877. }
  878. void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
  879. unsigned Encoding) {
  880. MCStreamer::EmitCFIPersonality(Sym, Encoding);
  881. OS << "\t.cfi_personality " << Encoding << ", ";
  882. Sym->print(OS, MAI);
  883. EmitEOL();
  884. }
  885. void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
  886. MCStreamer::EmitCFILsda(Sym, Encoding);
  887. OS << "\t.cfi_lsda " << Encoding << ", ";
  888. Sym->print(OS, MAI);
  889. EmitEOL();
  890. }
  891. void MCAsmStreamer::EmitCFIRememberState() {
  892. MCStreamer::EmitCFIRememberState();
  893. OS << "\t.cfi_remember_state";
  894. EmitEOL();
  895. }
  896. void MCAsmStreamer::EmitCFIRestoreState() {
  897. MCStreamer::EmitCFIRestoreState();
  898. OS << "\t.cfi_restore_state";
  899. EmitEOL();
  900. }
  901. void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
  902. MCStreamer::EmitCFISameValue(Register);
  903. OS << "\t.cfi_same_value ";
  904. EmitRegisterName(Register);
  905. EmitEOL();
  906. }
  907. void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
  908. MCStreamer::EmitCFIRelOffset(Register, Offset);
  909. OS << "\t.cfi_rel_offset ";
  910. EmitRegisterName(Register);
  911. OS << ", " << Offset;
  912. EmitEOL();
  913. }
  914. void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
  915. MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
  916. OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
  917. EmitEOL();
  918. }
  919. void MCAsmStreamer::EmitCFISignalFrame() {
  920. MCStreamer::EmitCFISignalFrame();
  921. OS << "\t.cfi_signal_frame";
  922. EmitEOL();
  923. }
  924. void MCAsmStreamer::EmitCFIUndefined(int64_t Register) {
  925. MCStreamer::EmitCFIUndefined(Register);
  926. OS << "\t.cfi_undefined " << Register;
  927. EmitEOL();
  928. }
  929. void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
  930. MCStreamer::EmitCFIRegister(Register1, Register2);
  931. OS << "\t.cfi_register " << Register1 << ", " << Register2;
  932. EmitEOL();
  933. }
  934. void MCAsmStreamer::EmitCFIWindowSave() {
  935. MCStreamer::EmitCFIWindowSave();
  936. OS << "\t.cfi_window_save";
  937. EmitEOL();
  938. }
  939. void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
  940. MCStreamer::EmitWinCFIStartProc(Symbol);
  941. OS << ".seh_proc ";
  942. Symbol->print(OS, MAI);
  943. EmitEOL();
  944. }
  945. void MCAsmStreamer::EmitWinCFIEndProc() {
  946. MCStreamer::EmitWinCFIEndProc();
  947. OS << "\t.seh_endproc";
  948. EmitEOL();
  949. }
  950. void MCAsmStreamer::EmitWinCFIStartChained() {
  951. MCStreamer::EmitWinCFIStartChained();
  952. OS << "\t.seh_startchained";
  953. EmitEOL();
  954. }
  955. void MCAsmStreamer::EmitWinCFIEndChained() {
  956. MCStreamer::EmitWinCFIEndChained();
  957. OS << "\t.seh_endchained";
  958. EmitEOL();
  959. }
  960. void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
  961. bool Except) {
  962. MCStreamer::EmitWinEHHandler(Sym, Unwind, Except);
  963. OS << "\t.seh_handler ";
  964. Sym->print(OS, MAI);
  965. if (Unwind)
  966. OS << ", @unwind";
  967. if (Except)
  968. OS << ", @except";
  969. EmitEOL();
  970. }
  971. void MCAsmStreamer::EmitWinEHHandlerData() {
  972. MCStreamer::EmitWinEHHandlerData();
  973. // Switch sections. Don't call SwitchSection directly, because that will
  974. // cause the section switch to be visible in the emitted assembly.
  975. // We only do this so the section switch that terminates the handler
  976. // data block is visible.
  977. WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
  978. MCSection *XData =
  979. WinEH::UnwindEmitter::getXDataSection(CurFrame->Function, getContext());
  980. SwitchSectionNoChange(XData);
  981. OS << "\t.seh_handlerdata";
  982. EmitEOL();
  983. }
  984. void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register) {
  985. MCStreamer::EmitWinCFIPushReg(Register);
  986. OS << "\t.seh_pushreg " << Register;
  987. EmitEOL();
  988. }
  989. void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) {
  990. MCStreamer::EmitWinCFISetFrame(Register, Offset);
  991. OS << "\t.seh_setframe " << Register << ", " << Offset;
  992. EmitEOL();
  993. }
  994. void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size) {
  995. MCStreamer::EmitWinCFIAllocStack(Size);
  996. OS << "\t.seh_stackalloc " << Size;
  997. EmitEOL();
  998. }
  999. void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) {
  1000. MCStreamer::EmitWinCFISaveReg(Register, Offset);
  1001. OS << "\t.seh_savereg " << Register << ", " << Offset;
  1002. EmitEOL();
  1003. }
  1004. void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
  1005. MCStreamer::EmitWinCFISaveXMM(Register, Offset);
  1006. OS << "\t.seh_savexmm " << Register << ", " << Offset;
  1007. EmitEOL();
  1008. }
  1009. void MCAsmStreamer::EmitWinCFIPushFrame(bool Code) {
  1010. MCStreamer::EmitWinCFIPushFrame(Code);
  1011. OS << "\t.seh_pushframe";
  1012. if (Code)
  1013. OS << " @code";
  1014. EmitEOL();
  1015. }
  1016. void MCAsmStreamer::EmitWinCFIEndProlog(void) {
  1017. MCStreamer::EmitWinCFIEndProlog();
  1018. OS << "\t.seh_endprologue";
  1019. EmitEOL();
  1020. }
  1021. void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
  1022. const MCSubtargetInfo &STI) {
  1023. raw_ostream &OS = GetCommentOS();
  1024. SmallString<256> Code;
  1025. SmallVector<MCFixup, 4> Fixups;
  1026. raw_svector_ostream VecOS(Code);
  1027. Emitter->encodeInstruction(Inst, VecOS, Fixups, STI);
  1028. VecOS.flush();
  1029. // If we are showing fixups, create symbolic markers in the encoded
  1030. // representation. We do this by making a per-bit map to the fixup item index,
  1031. // then trying to display it as nicely as possible.
  1032. SmallVector<uint8_t, 64> FixupMap;
  1033. FixupMap.resize(Code.size() * 8);
  1034. for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
  1035. FixupMap[i] = 0;
  1036. for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
  1037. MCFixup &F = Fixups[i];
  1038. const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
  1039. for (unsigned j = 0; j != Info.TargetSize; ++j) {
  1040. unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
  1041. assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
  1042. FixupMap[Index] = 1 + i;
  1043. }
  1044. }
  1045. // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
  1046. // high order halfword of a 32-bit Thumb2 instruction is emitted first.
  1047. OS << "encoding: [";
  1048. for (unsigned i = 0, e = Code.size(); i != e; ++i) {
  1049. if (i)
  1050. OS << ',';
  1051. // See if all bits are the same map entry.
  1052. uint8_t MapEntry = FixupMap[i * 8 + 0];
  1053. for (unsigned j = 1; j != 8; ++j) {
  1054. if (FixupMap[i * 8 + j] == MapEntry)
  1055. continue;
  1056. MapEntry = uint8_t(~0U);
  1057. break;
  1058. }
  1059. if (MapEntry != uint8_t(~0U)) {
  1060. if (MapEntry == 0) {
  1061. OS << format("0x%02x", uint8_t(Code[i]));
  1062. } else {
  1063. if (Code[i]) {
  1064. // FIXME: Some of the 8 bits require fix up.
  1065. OS << format("0x%02x", uint8_t(Code[i])) << '\''
  1066. << char('A' + MapEntry - 1) << '\'';
  1067. } else
  1068. OS << char('A' + MapEntry - 1);
  1069. }
  1070. } else {
  1071. // Otherwise, write out in binary.
  1072. OS << "0b";
  1073. for (unsigned j = 8; j--;) {
  1074. unsigned Bit = (Code[i] >> j) & 1;
  1075. unsigned FixupBit;
  1076. if (MAI->isLittleEndian())
  1077. FixupBit = i * 8 + j;
  1078. else
  1079. FixupBit = i * 8 + (7-j);
  1080. if (uint8_t MapEntry = FixupMap[FixupBit]) {
  1081. assert(Bit == 0 && "Encoder wrote into fixed up bit!");
  1082. OS << char('A' + MapEntry - 1);
  1083. } else
  1084. OS << Bit;
  1085. }
  1086. }
  1087. }
  1088. OS << "]\n";
  1089. for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
  1090. MCFixup &F = Fixups[i];
  1091. const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
  1092. OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
  1093. << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
  1094. }
  1095. }
  1096. void MCAsmStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) {
  1097. assert(getCurrentSection().first &&
  1098. "Cannot emit contents before setting section!");
  1099. // Show the encoding in a comment if we have a code emitter.
  1100. if (Emitter)
  1101. AddEncodingComment(Inst, STI);
  1102. // Show the MCInst if enabled.
  1103. if (ShowInst) {
  1104. Inst.dump_pretty(GetCommentOS(), InstPrinter.get(), "\n ");
  1105. GetCommentOS() << "\n";
  1106. }
  1107. if(getTargetStreamer())
  1108. getTargetStreamer()->prettyPrintAsm(*InstPrinter, OS, Inst, STI);
  1109. else
  1110. InstPrinter->printInst(&Inst, OS, "", STI);
  1111. EmitEOL();
  1112. }
  1113. void MCAsmStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
  1114. OS << "\t.bundle_align_mode " << AlignPow2;
  1115. EmitEOL();
  1116. }
  1117. void MCAsmStreamer::EmitBundleLock(bool AlignToEnd) {
  1118. OS << "\t.bundle_lock";
  1119. if (AlignToEnd)
  1120. OS << " align_to_end";
  1121. EmitEOL();
  1122. }
  1123. void MCAsmStreamer::EmitBundleUnlock() {
  1124. OS << "\t.bundle_unlock";
  1125. EmitEOL();
  1126. }
  1127. /// EmitRawText - If this file is backed by an assembly streamer, this dumps
  1128. /// the specified string in the output .s file. This capability is
  1129. /// indicated by the hasRawTextSupport() predicate.
  1130. void MCAsmStreamer::EmitRawTextImpl(StringRef String) {
  1131. if (!String.empty() && String.back() == '\n')
  1132. String = String.substr(0, String.size()-1);
  1133. OS << String;
  1134. EmitEOL();
  1135. }
  1136. void MCAsmStreamer::FinishImpl() {
  1137. // If we are generating dwarf for assembly source files dump out the sections.
  1138. if (getContext().getGenDwarfForAssembly())
  1139. MCGenDwarfInfo::Emit(this);
  1140. // Emit the label for the line table, if requested - since the rest of the
  1141. // line table will be defined by .loc/.file directives, and not emitted
  1142. // directly, the label is the only work required here.
  1143. auto &Tables = getContext().getMCDwarfLineTables();
  1144. if (!Tables.empty()) {
  1145. assert(Tables.size() == 1 && "asm output only supports one line table");
  1146. if (auto *Label = Tables.begin()->second.getLabel()) {
  1147. SwitchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
  1148. EmitLabel(Label);
  1149. }
  1150. }
  1151. }
  1152. MCStreamer *llvm::createAsmStreamer(MCContext &Context,
  1153. std::unique_ptr<formatted_raw_ostream> OS,
  1154. bool isVerboseAsm, bool useDwarfDirectory,
  1155. MCInstPrinter *IP, MCCodeEmitter *CE,
  1156. MCAsmBackend *MAB, bool ShowInst) {
  1157. return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm,
  1158. useDwarfDirectory, IP, CE, MAB, ShowInst);
  1159. }