AsmPrinter.cpp revision 21e42d0ea55c31ac4d57578f5116fa606d5c87ee
1c0561f29a8b95106c757ffa9ad186f997dabd836Chris Lattner//===-- AsmPrinter.cpp - Common AsmPrinter code ---------------------------===// 2a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner// 3a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner// The LLVM Compiler Infrastructure 4a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner// 8a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner//===----------------------------------------------------------------------===// 9a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner// 10a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner// This file implements the AsmPrinter class. 11a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner// 12a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner//===----------------------------------------------------------------------===// 13a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner 1414c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner#define DEBUG_TYPE "asm-printer" 15932f022b826c7b0b821c6a5369e18e4ebdceeb4cEvan Cheng#include "llvm/CodeGen/AsmPrinter.h" 1649cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner#include "DwarfDebug.h" 1749cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner#include "DwarfException.h" 18450de393acdf4be89db8558522b04d8111e4562bChris Lattner#include "llvm/Module.h" 195eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen#include "llvm/CodeGen/GCMetadataPrinter.h" 203b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner#include "llvm/CodeGen/MachineConstantPool.h" 211924aabf996be9335fab34e7ee4fa2aa5911389cDavid Greene#include "llvm/CodeGen/MachineFrameInfo.h" 22fe37ab335be5632eab561d49984c95cb06b946d4David Greene#include "llvm/CodeGen/MachineFunction.h" 2337efe6764568a3829fee26aba532283131d1a104Nate Begeman#include "llvm/CodeGen/MachineJumpTableInfo.h" 24b71d1b2fe2c0673005283b48be2f37c750ce367bDavid Greene#include "llvm/CodeGen/MachineLoopInfo.h" 2584bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner#include "llvm/CodeGen/MachineModuleInfo.h" 26618f17702d09795279717827eeb06632d6ef49e4Dan Gohman#include "llvm/Analysis/ConstantFolding.h" 27cd76240f3d0f6c5f8c80e4762a8fe3a4de22e059Argyrios Kyrtzidis#include "llvm/Analysis/DebugInfo.h" 28736e31d0cfd8a28c31741f39be606a11e7fc0036Chris Lattner#include "llvm/MC/MCAsmInfo.h" 292b2954f00ba02ca1a902f47080cd9f06aebc0378Chris Lattner#include "llvm/MC/MCContext.h" 3052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner#include "llvm/MC/MCExpr.h" 313ac1ab835caacdeebbd0d7b4d69160f283928d21David Greene#include "llvm/MC/MCInst.h" 32a87dea4f8c546ca748f1777a8d1cabcc06515d91Chris Lattner#include "llvm/MC/MCSection.h" 33a87dea4f8c546ca748f1777a8d1cabcc06515d91Chris Lattner#include "llvm/MC/MCStreamer.h" 347cb384dcca3f1ccfc993182ee4b972f7fffc8ffaChris Lattner#include "llvm/MC/MCSymbol.h" 3545111d160cf0910030eeb6a949c69273502e5ad5Chris Lattner#include "llvm/Target/Mangler.h" 3607000c6f01d8f57170f2d4c77a86d934bdc5c696Owen Anderson#include "llvm/Target/TargetData.h" 371924aabf996be9335fab34e7ee4fa2aa5911389cDavid Greene#include "llvm/Target/TargetInstrInfo.h" 380336fdba858830d515bf53ac29b8e5ff24dfa823Chris Lattner#include "llvm/Target/TargetLowering.h" 39f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner#include "llvm/Target/TargetLoweringObjectFile.h" 40a432997745f668e85e45826106430f69238b1d1eRafael Espindola#include "llvm/Target/TargetOptions.h" 41da47e6e0d003c873da960361549e57ee4617c301Evan Cheng#include "llvm/Target/TargetRegisterInfo.h" 429fc5cdf77c812aaa80419036de27576d45894d0dChris Lattner#include "llvm/Assembly/Writer.h" 43fad86b003a839cef40ec8ce8408322f4913368caChris Lattner#include "llvm/ADT/SmallString.h" 4414c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner#include "llvm/ADT/Statistic.h" 4514c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner#include "llvm/Support/ErrorHandling.h" 4614c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner#include "llvm/Support/Format.h" 47d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene#include "llvm/Support/MathExtras.h" 489c4210794ee42542a20023cd0a800003797523e0Torok Edwin#include "llvm/Support/Timer.h" 49a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattnerusing namespace llvm; 50a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner 51c0561f29a8b95106c757ffa9ad186f997dabd836Chris Lattnerstatic const char *DWARFGroupName = "DWARF Emission"; 52c0561f29a8b95106c757ffa9ad186f997dabd836Chris Lattnerstatic const char *DbgTimerName = "DWARF Debug Writer"; 53c0561f29a8b95106c757ffa9ad186f997dabd836Chris Lattnerstatic const char *EHTimerName = "DWARF Exception Writer"; 549c4210794ee42542a20023cd0a800003797523e0Torok Edwin 5514c38ec2afeaf25c53a50c2c65116aca8c889401Chris LattnerSTATISTIC(EmittedInsts, "Number of machine instrs printed"); 5614c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 571997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patelchar AsmPrinter::ID = 0; 5811d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner 59e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattnertypedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type; 60e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattnerstatic gcp_map_type &getGCMap(void *&P) { 61e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner if (P == 0) 62e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner P = new gcp_map_type(); 63e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner return *(gcp_map_type*)P; 64e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner} 65e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner 66e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner 67e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner/// getGVAlignmentLog2 - Return the alignment to use for the specified global 68e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner/// value in log2 form. This rounds up to the preferred alignment if possible 69e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner/// and legal. 70e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattnerstatic unsigned getGVAlignmentLog2(const GlobalValue *GV, const TargetData &TD, 71e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner unsigned InBits = 0) { 72e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner unsigned NumBits = 0; 73e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) 74e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner NumBits = TD.getPreferredAlignmentLog(GVar); 7583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 76e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner // If InBits is specified, round it to it. 77e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner if (InBits > NumBits) 78e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner NumBits = InBits; 7983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 80e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner // If the GV has a specified alignment, take it into account. 81e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner if (GV->getAlignment() == 0) 82e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner return NumBits; 8383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 84e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner unsigned GVAlign = Log2_32(GV->getAlignment()); 8583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 86e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner // If the GVAlign is larger than NumBits, or if we are required to obey 87e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner // NumBits because the GV has an assigned section, obey it. 88e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner if (GVAlign > NumBits || GV->hasSection()) 89e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner NumBits = GVAlign; 90e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner return NumBits; 91e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner} 92e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner 93e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner 94e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner 95e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner 96b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris LattnerAsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer) 9790c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Anderson : MachineFunctionPass(ID), 989d1c1ada213c80135fbdda704175aae689daa6f9Chris Lattner TM(tm), MAI(tm.getMCAsmInfo()), 9911d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner OutContext(Streamer.getContext()), 10011d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner OutStreamer(Streamer), 101553881bddcdeb66c0ae06bf9f62ca63b9f29b2e8Devang Patel LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) { 10249cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner DD = 0; DE = 0; MMI = 0; LI = 0; 103d55a2664f9493a4c3be242a75d339fac0ebe2e21Hal Finkel CurrentFnSym = CurrentFnSymForSize = 0; 104e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner GCMetadataPrinters = 0; 10556591ab218639d8a6e4c756ca37adaf20215c3b6Chris Lattner VerboseAsm = Streamer.isVerboseAsm(); 10642bf74be1402df7409efbea089310d4c276fde37Evan Cheng} 107ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 108c317a60c2714a5b90700a11ba646285cb754a5d3Gordon HenriksenAsmPrinter::~AsmPrinter() { 10949cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner assert(DD == 0 && DE == 0 && "Debug/EH info didn't get finalized"); 11083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 111e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner if (GCMetadataPrinters != 0) { 112e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner gcp_map_type &GCMap = getGCMap(GCMetadataPrinters); 11383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 114e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner for (gcp_map_type::iterator I = GCMap.begin(), E = GCMap.end(); I != E; ++I) 115e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner delete I->second; 116e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner delete &GCMap; 117e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner GCMetadataPrinters = 0; 118e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner } 11983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1202b2954f00ba02ca1a902f47080cd9f06aebc0378Chris Lattner delete &OutStreamer; 121c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen} 122ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 123b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner/// getFunctionNumber - Return a unique ID for the current function. 124b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner/// 125b84822fb7b64977c16e97b870891da1d6c9736feChris Lattnerunsigned AsmPrinter::getFunctionNumber() const { 126b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner return MF->getFunctionNumber(); 127b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner} 128b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner 1290d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohmanconst TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const { 130f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner return TM.getTargetLowering()->getObjFileLowering(); 131f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner} 132f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner 133d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattner 134d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattner/// getTargetData - Return information about data layout. 135d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattnerconst TargetData &AsmPrinter::getTargetData() const { 136d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattner return *TM.getTargetData(); 137d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattner} 138d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattner 139dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattner/// getCurrentSection() - Return the current section we are emitting to. 140dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattnerconst MCSection *AsmPrinter::getCurrentSection() const { 141dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattner return OutStreamer.getCurrentSection(); 142b5a32e2e8ce2f3de3a340c5a2dfcd3a159968466Anton Korobeynikov} 1434632d7a57008564c4b0f8246e85bd813a200d2c6Chris Lattner 144dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattner 145d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattner 146ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksenvoid AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const { 147845012e6d31799c7fbd1193fa1af8ee2d12e9231Dan Gohman AU.setPreservesAll(); 148ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksen MachineFunctionPass::getAnalysisUsage(AU); 14911d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner AU.addRequired<MachineModuleInfo>(); 1505eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen AU.addRequired<GCModuleInfo>(); 1513f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose()) 152b71d1b2fe2c0673005283b48be2f37c750ce367bDavid Greene AU.addRequired<MachineLoopInfo>(); 153ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksen} 154ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksen 155a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattnerbool AsmPrinter::doInitialization(Module &M) { 156d32c8a561734e05ff78da4435de0e85e0eed88e1Chris Lattner MMI = getAnalysisIfAvailable<MachineModuleInfo>(); 15711d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner MMI->AnalyzeModule(M); 15811d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner 159f26e03bc7e30162197641406e37e662a15d80f7eChris Lattner // Initialize TargetLoweringObjectFile. 160f26e03bc7e30162197641406e37e662a15d80f7eChris Lattner const_cast<TargetLoweringObjectFile&>(getObjFileLowering()) 161f26e03bc7e30162197641406e37e662a15d80f7eChris Lattner .Initialize(OutContext, TM); 16283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 163b87c305fa77650ee581d4a8c65a0757f88002441Chris Lattner Mang = new Mangler(OutContext, *TM.getTargetData()); 16483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 165812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson // Allow the target to emit any magic that it wants at the start of the file. 166812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson EmitStartOfAsmFile(M); 167952b839ce9bc0c6d605d8b202c9cd76f7f05a77dRafael Espindola 168a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner // Very minimal debug info. It is ignored if we emit actual debug info. If we 169a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner // don't, this at least helps the user find where a global came from. 17033adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->hasSingleParameterDotFile()) { 171a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner // .file "foo.c" 172a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner OutStreamer.EmitFileDirective(M.getModuleIdentifier()); 173952b839ce9bc0c6d605d8b202c9cd76f7f05a77dRafael Espindola } 174952b839ce9bc0c6d605d8b202c9cd76f7f05a77dRafael Espindola 175812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); 176812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson assert(MI && "AsmPrinter didn't require GCModuleInfo?"); 1775eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I) 1785eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I)) 1797d73c7f0d618dd6661cd55834c58aa62f22b28feChris Lattner MP->beginAssembly(*this); 18091bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner 18191bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner // Emit module-level inline asm if it exists. 18247b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner if (!M.getModuleInlineAsm().empty()) { 18347b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner OutStreamer.AddComment("Start of file scope inline assembly"); 18447b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner OutStreamer.AddBlankLine(); 185a38941d458273946594d3592ed5debdc9730db08Chris Lattner EmitInlineAsm(M.getModuleInlineAsm()+"\n"); 18647b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner OutStreamer.AddComment("End of file scope inline assembly"); 18747b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner OutStreamer.AddBlankLine(); 18847b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner } 1892c1b1597f244c836771b4f2668c0ae399d32a5e9Chris Lattner 19049cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner if (MAI->doesSupportDebugInformation()) 19149cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner DD = new DwarfDebug(this, &M); 192d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov 1932d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola switch (MAI->getExceptionHandlingType()) { 1942d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola case ExceptionHandling::None: 1952d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola return false; 1962d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola case ExceptionHandling::SjLj: 1972d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola case ExceptionHandling::DwarfCFI: 1982d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola DE = new DwarfCFIException(this); 1992d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola return false; 2002d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola case ExceptionHandling::ARM: 2012d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola DE = new ARMException(this); 2022d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola return false; 203d652b1368b1e381382951f450e5eeca870d91dd6Charles Davis case ExceptionHandling::Win64: 204d652b1368b1e381382951f450e5eeca870d91dd6Charles Davis DE = new Win64Exception(this); 205d652b1368b1e381382951f450e5eeca870d91dd6Charles Davis return false; 2062d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola } 2072d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola 2082d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola llvm_unreachable("Unknown exception type."); 209a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner} 210a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner 211be9dfcef82c58063708e039bea3cf972ba41581bChris Lattnervoid AsmPrinter::EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const { 212a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner switch ((GlobalValue::LinkageTypes)Linkage) { 213a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::CommonLinkage: 214a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::LinkOnceAnyLinkage: 215a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::LinkOnceODRLinkage: 216a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::WeakAnyLinkage: 217a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::WeakODRLinkage: 2185e721d768254a920b78b9129d79a84c0163cb3f4Bill Wendling case GlobalValue::LinkerPrivateWeakLinkage: 21955ae515f9db484125a23429d4906c5edaf9f10d2Bill Wendling case GlobalValue::LinkerPrivateWeakDefAutoLinkage: 220a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner if (MAI->getWeakDefDirective() != 0) { 221a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .globl _foo 222a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); 22355ae515f9db484125a23429d4906c5edaf9f10d2Bill Wendling 22455ae515f9db484125a23429d4906c5edaf9f10d2Bill Wendling if ((GlobalValue::LinkageTypes)Linkage != 22555ae515f9db484125a23429d4906c5edaf9f10d2Bill Wendling GlobalValue::LinkerPrivateWeakDefAutoLinkage) 22655ae515f9db484125a23429d4906c5edaf9f10d2Bill Wendling // .weak_definition _foo 22755ae515f9db484125a23429d4906c5edaf9f10d2Bill Wendling OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefinition); 22855ae515f9db484125a23429d4906c5edaf9f10d2Bill Wendling else 22955ae515f9db484125a23429d4906c5edaf9f10d2Bill Wendling OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefAutoPrivate); 2305b1b3b73f2e4fc66eb8a9273673d128b139caf03Duncan Sands } else if (MAI->getLinkOnceDirective() != 0) { 231a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .globl _foo 232a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); 2335b1b3b73f2e4fc66eb8a9273673d128b139caf03Duncan Sands //NOTE: linkonce is handled by the section the symbol was assigned to. 234a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner } else { 235a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .weak _foo 236a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak); 237a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner } 238a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner break; 239a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::DLLExportLinkage: 240a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::AppendingLinkage: 241a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // FIXME: appending linkage variables should go into a section of 242a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // their name or something. For now, just emit them as external. 243a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::ExternalLinkage: 244a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // If external or appending, declare as a global symbol. 245a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .globl _foo 246a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); 247a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner break; 248a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::PrivateLinkage: 249a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::InternalLinkage: 250eabd735c9a87203a567caf1ef117aeae9d288aaaBill Wendling case GlobalValue::LinkerPrivateLinkage: 251a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner break; 252a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner default: 253a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner llvm_unreachable("Unknown linkage type!"); 254a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner } 255a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner} 256a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner 257a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner 25848d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner/// EmitGlobalVariable - Emit the specified global variable to the .s file. 25948d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattnervoid AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { 26084397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola if (GV->hasInitializer()) { 26184397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola // Check to see if this is a special global used by LLVM, if so, emit it. 26284397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola if (EmitSpecialLLVMGlobal(GV)) 26384397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola return; 26484397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola 26584397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola if (isVerbose()) { 26684397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola WriteAsOperand(OutStreamer.GetCommentOS(), GV, 26784397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola /*PrintType=*/false, GV->getParent()); 26884397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola OutStreamer.GetCommentOS() << '\n'; 26984397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola } 27004386ca726d726c214be15a0c3e9dbdc82b1e691Eric Christopher } 27183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 272deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner MCSymbol *GVSym = Mang->getSymbol(GV); 273348d542199f83418481bde6eba1c94f6fdb45b85Chad Rosier EmitVisibility(GVSym, GV->getVisibility(), !GV->isDeclaration()); 27474bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 27584397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola if (!GV->hasInitializer()) // External globals require no extra code. 27684397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola return; 27784397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola 278a800f7c464ef9a376057a555129f36d1f8488c3bChris Lattner if (MAI->hasDotTypeDotSizeDirective()) 279a800f7c464ef9a376057a555129f36d1f8488c3bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject); 28083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 28174bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM); 28274bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 28374bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner const TargetData *TD = TM.getTargetData(); 284e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner uint64_t Size = TD->getTypeAllocSize(GV->getType()->getElementType()); 28583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 286567dd1f5d0ae454e7c51ef070bbb8d31a43ed4bcChris Lattner // If the alignment is specified, we *must* obey it. Overaligning a global 287567dd1f5d0ae454e7c51ef070bbb8d31a43ed4bcChris Lattner // with a specified alignment is a prompt way to break globals emitted to 288567dd1f5d0ae454e7c51ef070bbb8d31a43ed4bcChris Lattner // sections and expected to be contiguous (e.g. ObjC metadata). 289e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner unsigned AlignLog = getGVAlignmentLog2(GV, *TD); 29083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 2919744d611d7c7c1fb51c50c4e94901e4e9a905116Chris Lattner // Handle common and BSS local symbols (.lcomm). 2929744d611d7c7c1fb51c50c4e94901e4e9a905116Chris Lattner if (GVKind.isCommon() || GVKind.isBSSLocal()) { 29374bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. 29436a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer unsigned Align = 1 << AlignLog; 29583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 296814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // Handle common symbols. 2979744d611d7c7c1fb51c50c4e94901e4e9a905116Chris Lattner if (GVKind.isCommon()) { 2988048ebe91d76f5ee58f5c2c7535151d782af4b29Chris Lattner if (!getObjFileLowering().getCommDirectiveSupportsAlignment()) 2998048ebe91d76f5ee58f5c2c7535151d782af4b29Chris Lattner Align = 0; 30083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 3019744d611d7c7c1fb51c50c4e94901e4e9a905116Chris Lattner // .comm _foo, 42, 4 3028048ebe91d76f5ee58f5c2c7535151d782af4b29Chris Lattner OutStreamer.EmitCommonSymbol(GVSym, Size, Align); 303814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner return; 304814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner } 30583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 306814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // Handle local BSS symbols. 307814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner if (MAI->hasMachoZeroFillDirective()) { 308814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner const MCSection *TheSection = 309814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM); 310814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // .zerofill __DATA, __bss, _foo, 400, 5 31136a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer OutStreamer.EmitZerofill(TheSection, GVSym, Size, Align); 312814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner return; 313814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner } 31483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 31536a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer if (MAI->getLCOMMDirectiveType() != LCOMM::None && 31636a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer (MAI->getLCOMMDirectiveType() != LCOMM::NoAlignment || Align == 1)) { 317814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // .lcomm _foo, 42 31836a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer OutStreamer.EmitLocalCommonSymbol(GVSym, Size, Align); 319814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner return; 32074bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner } 3218048ebe91d76f5ee58f5c2c7535151d782af4b29Chris Lattner 3228048ebe91d76f5ee58f5c2c7535151d782af4b29Chris Lattner if (!getObjFileLowering().getCommDirectiveSupportsAlignment()) 3238048ebe91d76f5ee58f5c2c7535151d782af4b29Chris Lattner Align = 0; 32483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 325814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // .local _foo 326a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Local); 327814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // .comm _foo, 42, 4 3288048ebe91d76f5ee58f5c2c7535151d782af4b29Chris Lattner OutStreamer.EmitCommonSymbol(GVSym, Size, Align); 32974bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner return; 33074bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner } 33183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 33274bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner const MCSection *TheSection = 33374bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM); 33474bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 33574bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner // Handle the zerofill directive on darwin, which is a special form of BSS 33674bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner // emission. 33774bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) { 3384c4d0c0cc582a61d9e7f58594c71540aaa56b280Chris Lattner if (Size == 0) Size = 1; // zerofill of 0 bytes is undefined. 33983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 34074bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner // .globl _foo 341a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); 34274bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner // .zerofill __DATA, __common, _foo, 400, 5 34374bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog); 34474bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner return; 34574bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner } 34683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 34702b46bc9426925b90137d264216a54aa413335fdEric Christopher // Handle thread local data for mach-o which requires us to output an 34802b46bc9426925b90137d264216a54aa413335fdEric Christopher // additional structure of data and mangle the original symbol so that we 34902b46bc9426925b90137d264216a54aa413335fdEric Christopher // can reference it later. 350dfe254b86e93b131cceb6aa27c33b33b2c8102d6Chris Lattner // 351dfe254b86e93b131cceb6aa27c33b33b2c8102d6Chris Lattner // TODO: This should become an "emit thread local global" method on TLOF. 352dfe254b86e93b131cceb6aa27c33b33b2c8102d6Chris Lattner // All of this macho specific stuff should be sunk down into TLOFMachO and 353dfe254b86e93b131cceb6aa27c33b33b2c8102d6Chris Lattner // stuff like "TLSExtraDataSection" should no longer be part of the parent 354dfe254b86e93b131cceb6aa27c33b33b2c8102d6Chris Lattner // TLOF class. This will also make it more obvious that stuff like 355dfe254b86e93b131cceb6aa27c33b33b2c8102d6Chris Lattner // MCStreamer::EmitTBSSSymbol is macho specific and only called from macho 356dfe254b86e93b131cceb6aa27c33b33b2c8102d6Chris Lattner // specific code. 35702b46bc9426925b90137d264216a54aa413335fdEric Christopher if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective()) { 3588116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // Emit the .tbss symbol 35983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach MCSymbol *MangSym = 3608116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutContext.GetOrCreateSymbol(GVSym->getName() + Twine("$tlv$init")); 36183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 36202b46bc9426925b90137d264216a54aa413335fdEric Christopher if (GVKind.isThreadBSS()) 36302b46bc9426925b90137d264216a54aa413335fdEric Christopher OutStreamer.EmitTBSSSymbol(TheSection, MangSym, Size, 1 << AlignLog); 36402b46bc9426925b90137d264216a54aa413335fdEric Christopher else if (GVKind.isThreadData()) { 36502b46bc9426925b90137d264216a54aa413335fdEric Christopher OutStreamer.SwitchSection(TheSection); 36602b46bc9426925b90137d264216a54aa413335fdEric Christopher 36783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach EmitAlignment(AlignLog, GV); 36802b46bc9426925b90137d264216a54aa413335fdEric Christopher OutStreamer.EmitLabel(MangSym); 36983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 37002b46bc9426925b90137d264216a54aa413335fdEric Christopher EmitGlobalConstant(GV->getInitializer()); 37102b46bc9426925b90137d264216a54aa413335fdEric Christopher } 37283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 3738116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutStreamer.AddBlankLine(); 37483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 3758116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // Emit the variable struct for the runtime. 37683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach const MCSection *TLVSect 3778116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher = getObjFileLowering().getTLSExtraDataSection(); 37883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 3798116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutStreamer.SwitchSection(TLVSect); 3808116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // Emit the linkage here. 3818116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher EmitLinkage(GV->getLinkage(), GVSym); 3828116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutStreamer.EmitLabel(GVSym); 38383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 3848116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // Three pointers in size: 3858116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // - __tlv_bootstrap - used to make sure support exists 3868116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // - spare pointer, used when mapped by the runtime 3878116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // - pointer to mangled symbol above with initializer 3888116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher unsigned PtrSize = TD->getPointerSizeInBits()/8; 3897310064f4d14b62029805ab16a11ff443ea309d5Eric Christopher OutStreamer.EmitSymbolValue(GetExternalSymbolSymbol("_tlv_bootstrap"), 3908116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher PtrSize, 0); 3918116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutStreamer.EmitIntValue(0, PtrSize, 0); 3928116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutStreamer.EmitSymbolValue(MangSym, PtrSize, 0); 39383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 3948116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutStreamer.AddBlankLine(); 395c1a887d76d95100e7e05aa76e077710bc4e0b1cfEric Christopher return; 396c1a887d76d95100e7e05aa76e077710bc4e0b1cfEric Christopher } 39774bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 39874bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner OutStreamer.SwitchSection(TheSection); 39974bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 400a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner EmitLinkage(GV->getLinkage(), GVSym); 401f74e25f60c8c63b819ff603cb4c3c18424dc87a7Chris Lattner EmitAlignment(AlignLog, GV); 402a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner 4034c8c668b57f74e2849ba198c3abfc97899e8072bChris Lattner OutStreamer.EmitLabel(GVSym); 40474bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 40574bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner EmitGlobalConstant(GV->getInitializer()); 40674bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 40774bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner if (MAI->hasDotTypeDotSizeDirective()) 4081947f242d40227d36440a2702a0a612c8077d72eChris Lattner // .size foo, 42 40999328add833807f12a4950c7de29fb2a5df04703Chris Lattner OutStreamer.EmitELFSize(GVSym, MCConstantExpr::Create(Size, OutContext)); 41083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 4110fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner OutStreamer.AddBlankLine(); 41248d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner} 41348d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner 414b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner/// EmitFunctionHeader - This method emits the header for the current 415b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner/// function. 416b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattnervoid AsmPrinter::EmitFunctionHeader() { 417b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner // Print out constants referenced by the function 418a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner EmitConstantPool(); 41983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 420b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner // Print the 'header' of function. 421b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner const Function *F = MF->getFunction(); 422b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 423b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM)); 424be9dfcef82c58063708e039bea3cf972ba41581bChris Lattner EmitVisibility(CurrentFnSym, F->getVisibility()); 425b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 426111a3193b5e25f8765221f2e94fba888155fe4ebChris Lattner EmitLinkage(F->getLinkage(), CurrentFnSym); 427b406a8141d704bca7a8eade3a0c46d7ec73affc8Chris Lattner EmitAlignment(MF->getAlignment(), F); 428b406a8141d704bca7a8eade3a0c46d7ec73affc8Chris Lattner 429b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner if (MAI->hasDotTypeDotSizeDirective()) 430b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction); 431b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 4323f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose()) { 4339bc20ab519d47146a9716d7cff2a892da78774a6Chris Lattner WriteAsOperand(OutStreamer.GetCommentOS(), F, 4349bc20ab519d47146a9716d7cff2a892da78774a6Chris Lattner /*PrintType=*/false, F->getParent()); 4359bc20ab519d47146a9716d7cff2a892da78774a6Chris Lattner OutStreamer.GetCommentOS() << '\n'; 436b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner } 437b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 438f451cb870efcf9e0302d25ed05f4cac6bb494e42Dan Gohman // Emit the CurrentFnSym. This is a virtual function to allow targets to 4392cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner // do their wild and crazy things as required. 4402cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner EmitFunctionEntryLabel(); 44183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 4429cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner // If the function had address-taken blocks that got deleted, then we have 4439cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner // references to the dangling symbols. Emit them at the start of the function 4449cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner // so that we don't get references to undefined symbols. 4459cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner std::vector<MCSymbol*> DeadBlockSyms; 4469cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner MMI->takeDeletedSymbolsForFunction(F, DeadBlockSyms); 4479cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner for (unsigned i = 0, e = DeadBlockSyms.size(); i != e; ++i) { 4489cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner OutStreamer.AddComment("Address taken block that was later removed"); 4499cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner OutStreamer.EmitLabel(DeadBlockSyms[i]); 4509cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner } 45183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 452b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner // Add some workaround for linkonce linkage on Cygwin\MinGW. 453b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner if (MAI->getLinkOnceDirective() != 0 && 454fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner (F->hasLinkOnceLinkage() || F->hasWeakLinkage())) { 4559bc20ab519d47146a9716d7cff2a892da78774a6Chris Lattner // FIXME: What is this? 45683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach MCSymbol *FakeStub = 457fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner OutContext.GetOrCreateSymbol(Twine("Lllvm$workaround$fake$stub$")+ 458fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner CurrentFnSym->getName()); 459fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner OutStreamer.EmitLabel(FakeStub); 460fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner } 46183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 462b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner // Emit pre-function debug and/or EH information. 4639c4210794ee42542a20023cd0a800003797523e0Torok Edwin if (DE) { 46403c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled); 46503c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman DE->BeginFunction(MF); 4669c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 4679c4210794ee42542a20023cd0a800003797523e0Torok Edwin if (DD) { 46803c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); 46903c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman DD->beginFunction(MF); 4709c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 471b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner} 472b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 4732cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the 4742cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner/// function. This can be overridden by targets as required to do custom stuff. 4752cf7251d39f28888af06b6f941eabd1d10995382Chris Lattnervoid AsmPrinter::EmitFunctionEntryLabel() { 476b4202dbb36e9799c96890fc3aa0040c1aedb33c8Chris Lattner // The function label could have already been emitted if two symbols end up 477b4202dbb36e9799c96890fc3aa0040c1aedb33c8Chris Lattner // conflicting due to asm renaming. Detect this and emit an error. 4782fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson if (CurrentFnSym->isUndefined()) { 4792fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson OutStreamer.ForceCodeRegion(); 480b4202dbb36e9799c96890fc3aa0040c1aedb33c8Chris Lattner return OutStreamer.EmitLabel(CurrentFnSym); 4812fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson } 482b4202dbb36e9799c96890fc3aa0040c1aedb33c8Chris Lattner 483b4202dbb36e9799c96890fc3aa0040c1aedb33c8Chris Lattner report_fatal_error("'" + Twine(CurrentFnSym->getName()) + 484b4202dbb36e9799c96890fc3aa0040c1aedb33c8Chris Lattner "' label emitted multiple times to assembly file"); 4852cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner} 486b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 48748d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner 488e025e966a863229feb7ad188f520ce213bb30a34Devang Patel/// EmitComments - Pretty-print comments for instructions. 489e025e966a863229feb7ad188f520ce213bb30a34Devang Patelstatic void EmitComments(const MachineInstr &MI, raw_ostream &CommentOS) { 490e025e966a863229feb7ad188f520ce213bb30a34Devang Patel const MachineFunction *MF = MI.getParent()->getParent(); 491e025e966a863229feb7ad188f520ce213bb30a34Devang Patel const TargetMachine &TM = MF->getTarget(); 49283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 49347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // Check for spills and reloads 49447529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner int FI; 49583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 49647529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner const MachineFrameInfo *FrameInfo = MF->getFrameInfo(); 49783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 49847529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // We assume a single instruction only has a spill or reload, not 49947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // both. 50047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner const MachineMemOperand *MMO; 50147529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (TM.getInstrInfo()->isLoadFromStackSlotPostFE(&MI, FI)) { 50247529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (FrameInfo->isSpillSlotObjectIndex(FI)) { 50347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner MMO = *MI.memoperands_begin(); 50447529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << MMO->getSize() << "-byte Reload\n"; 50547529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } 50647529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } else if (TM.getInstrInfo()->hasLoadFromStackSlot(&MI, MMO, FI)) { 50747529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (FrameInfo->isSpillSlotObjectIndex(FI)) 50847529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << MMO->getSize() << "-byte Folded Reload\n"; 50947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } else if (TM.getInstrInfo()->isStoreToStackSlotPostFE(&MI, FI)) { 51047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (FrameInfo->isSpillSlotObjectIndex(FI)) { 51147529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner MMO = *MI.memoperands_begin(); 51247529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << MMO->getSize() << "-byte Spill\n"; 51347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } 51447529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } else if (TM.getInstrInfo()->hasStoreToStackSlot(&MI, MMO, FI)) { 51547529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (FrameInfo->isSpillSlotObjectIndex(FI)) 51647529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << MMO->getSize() << "-byte Folded Spill\n"; 51747529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } 51883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 51947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // Check for spill-induced copies 52004c528a0c86ddf3d6a70681f72e1b2ec07b0b53aJakob Stoklund Olesen if (MI.getAsmPrinterFlag(MachineInstr::ReloadReuse)) 52104c528a0c86ddf3d6a70681f72e1b2ec07b0b53aJakob Stoklund Olesen CommentOS << " Reload Reuse\n"; 52247529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner} 52347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 52417fedf216bc10c66e02694854f522cb602097005Chris Lattner/// EmitImplicitDef - This method emits the specified machine instruction 52517fedf216bc10c66e02694854f522cb602097005Chris Lattner/// that is an implicit def. 52617fedf216bc10c66e02694854f522cb602097005Chris Lattnerstatic void EmitImplicitDef(const MachineInstr *MI, AsmPrinter &AP) { 52717fedf216bc10c66e02694854f522cb602097005Chris Lattner unsigned RegNo = MI->getOperand(0).getReg(); 52817fedf216bc10c66e02694854f522cb602097005Chris Lattner AP.OutStreamer.AddComment(Twine("implicit-def: ") + 52917fedf216bc10c66e02694854f522cb602097005Chris Lattner AP.TM.getRegisterInfo()->getName(RegNo)); 53017fedf216bc10c66e02694854f522cb602097005Chris Lattner AP.OutStreamer.AddBlankLine(); 53117fedf216bc10c66e02694854f522cb602097005Chris Lattner} 53217fedf216bc10c66e02694854f522cb602097005Chris Lattner 53317fedf216bc10c66e02694854f522cb602097005Chris Lattnerstatic void EmitKill(const MachineInstr *MI, AsmPrinter &AP) { 53417fedf216bc10c66e02694854f522cb602097005Chris Lattner std::string Str = "kill:"; 53517fedf216bc10c66e02694854f522cb602097005Chris Lattner for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 53617fedf216bc10c66e02694854f522cb602097005Chris Lattner const MachineOperand &Op = MI->getOperand(i); 53717fedf216bc10c66e02694854f522cb602097005Chris Lattner assert(Op.isReg() && "KILL instruction must have only register operands"); 53817fedf216bc10c66e02694854f522cb602097005Chris Lattner Str += ' '; 53917fedf216bc10c66e02694854f522cb602097005Chris Lattner Str += AP.TM.getRegisterInfo()->getName(Op.getReg()); 54017fedf216bc10c66e02694854f522cb602097005Chris Lattner Str += (Op.isDef() ? "<def>" : "<kill>"); 54117fedf216bc10c66e02694854f522cb602097005Chris Lattner } 54217fedf216bc10c66e02694854f522cb602097005Chris Lattner AP.OutStreamer.AddComment(Str); 54317fedf216bc10c66e02694854f522cb602097005Chris Lattner AP.OutStreamer.AddBlankLine(); 54417fedf216bc10c66e02694854f522cb602097005Chris Lattner} 54517fedf216bc10c66e02694854f522cb602097005Chris Lattner 546343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen/// EmitDebugValueComment - This method handles the target-independent form 547343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen/// of DBG_VALUE, returning true if it was able to do so. A false return 548343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen/// means the target will need to handle MI in EmitInstruction. 549343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesenstatic bool EmitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { 550343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // This code handles only the 3-operand target-independent form. 551343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen if (MI->getNumOperands() != 3) 552343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen return false; 553343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen 554a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer SmallString<128> Str; 555a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer raw_svector_ostream OS(Str); 556a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << '\t' << AP.MAI->getCommentString() << "DEBUG_VALUE: "; 557a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer 558343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // cast away const; DIetc do not take const operands for some reason. 55900d139064e525221fdf0ff00d001ce8b584d69d6Chris Lattner DIVariable V(const_cast<MDNode*>(MI->getOperand(2).getMetadata())); 56067a444ca362b6f2dc64016494eb1165d46aef0bfDevang Patel if (V.getContext().isSubprogram()) 5612db49d797b86b7f3615bae17b2b016727778a6c4Devang Patel OS << DISubprogram(V.getContext()).getDisplayName() << ":"; 562a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << V.getName() << " <- "; 563343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen 564343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // Register or immediate value. Register 0 means undef. 565343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen if (MI->getOperand(0).isFPImm()) { 566343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen APFloat APF = APFloat(MI->getOperand(0).getFPImm()->getValueAPF()); 567343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen if (MI->getOperand(0).getFPImm()->getType()->isFloatTy()) { 568a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << (double)APF.convertToFloat(); 569343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen } else if (MI->getOperand(0).getFPImm()->getType()->isDoubleTy()) { 570a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << APF.convertToDouble(); 571343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen } else { 572343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // There is no good way to print long double. Convert a copy to 573343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // double. Ah well, it's only a comment. 574343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen bool ignored; 575343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, 576343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen &ignored); 577a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << "(long double) " << APF.convertToDouble(); 578343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen } 579343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen } else if (MI->getOperand(0).isImm()) { 580a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << MI->getOperand(0).getImm(); 5818594d429e02c688d428036f8563f09572da3fbffDevang Patel } else if (MI->getOperand(0).isCImm()) { 5828594d429e02c688d428036f8563f09572da3fbffDevang Patel MI->getOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/); 58300d139064e525221fdf0ff00d001ce8b584d69d6Chris Lattner } else { 58400d139064e525221fdf0ff00d001ce8b584d69d6Chris Lattner assert(MI->getOperand(0).isReg() && "Unknown operand type"); 585343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen if (MI->getOperand(0).getReg() == 0) { 586343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // Suppress offset, it is not meaningful here. 587a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << "undef"; 588343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // NOTE: Want this comment at start of line, don't emit with AddComment. 589a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer AP.OutStreamer.EmitRawText(OS.str()); 590343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen return true; 591343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen } 592a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << AP.TM.getRegisterInfo()->getName(MI->getOperand(0).getReg()); 59300d139064e525221fdf0ff00d001ce8b584d69d6Chris Lattner } 59483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 595a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << '+' << MI->getOperand(1).getImm(); 596343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // NOTE: Want this comment at start of line, don't emit with AddComment. 597a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer AP.OutStreamer.EmitRawText(OS.str()); 598343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen return true; 599343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen} 60047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 601e29887b4ee42ae78790a8c1886a7babee9ef18e5Rafael EspindolaAsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() { 602fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI && 603fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola MF->getFunction()->needsUnwindTableEntry()) 604fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola return CFI_M_EH; 605a432997745f668e85e45826106430f69238b1d1eRafael Espindola 606e29887b4ee42ae78790a8c1886a7babee9ef18e5Rafael Espindola if (MMI->hasDebugInfo()) 607e29887b4ee42ae78790a8c1886a7babee9ef18e5Rafael Espindola return CFI_M_Debug; 608a432997745f668e85e45826106430f69238b1d1eRafael Espindola 609e29887b4ee42ae78790a8c1886a7babee9ef18e5Rafael Espindola return CFI_M_None; 610a432997745f668e85e45826106430f69238b1d1eRafael Espindola} 611a432997745f668e85e45826106430f69238b1d1eRafael Espindola 612f46337004ab08076774932785679460ec3d3bb9aCharles Davisbool AsmPrinter::needsSEHMoves() { 613f46337004ab08076774932785679460ec3d3bb9aCharles Davis return MAI->getExceptionHandlingType() == ExceptionHandling::Win64 && 614f46337004ab08076774932785679460ec3d3bb9aCharles Davis MF->getFunction()->needsUnwindTableEntry(); 615f46337004ab08076774932785679460ec3d3bb9aCharles Davis} 616f46337004ab08076774932785679460ec3d3bb9aCharles Davis 617390c40d96adb2eb4a778a0890c6c8743057e289eNick Lewyckybool AsmPrinter::needsRelocationsForDwarfStringPool() const { 618390c40d96adb2eb4a778a0890c6c8743057e289eNick Lewycky return MAI->doesDwarfUseRelocationsForStringPool(); 619390c40d96adb2eb4a778a0890c6c8743057e289eNick Lewycky} 620390c40d96adb2eb4a778a0890c6c8743057e289eNick Lewycky 621f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindolavoid AsmPrinter::emitPrologLabel(const MachineInstr &MI) { 622f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola MCSymbol *Label = MI.getOperand(0).getMCSymbol(); 623fea8fea58328d561eeccd5e0f896dbddf17ddb38Rafael Espindola 624f2b04232006142eb7933972fb21d9ffb9b8c2646Rafael Espindola if (MAI->getExceptionHandlingType() != ExceptionHandling::DwarfCFI) 625f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola return; 626f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola 627e29887b4ee42ae78790a8c1886a7babee9ef18e5Rafael Espindola if (needsCFIMoves() == CFI_M_None) 628a432997745f668e85e45826106430f69238b1d1eRafael Espindola return; 629a432997745f668e85e45826106430f69238b1d1eRafael Espindola 630e060a5cd0688caea0e3de670f642f92a4d0b326eBill Wendling if (MMI->getCompactUnwindEncoding() != 0) 631e060a5cd0688caea0e3de670f642f92a4d0b326eBill Wendling OutStreamer.EmitCompactUnwindEncoding(MMI->getCompactUnwindEncoding()); 632e060a5cd0688caea0e3de670f642f92a4d0b326eBill Wendling 633a432997745f668e85e45826106430f69238b1d1eRafael Espindola MachineModuleInfo &MMI = MF->getMMI(); 634f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 635b28d4f152ee9b76d8798b2bdcb06cb8d106841e6Rafael Espindola bool FoundOne = false; 636b28d4f152ee9b76d8798b2bdcb06cb8d106841e6Rafael Espindola (void)FoundOne; 637f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola for (std::vector<MachineMove>::iterator I = Moves.begin(), 638f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola E = Moves.end(); I != E; ++I) { 639f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola if (I->getLabel() == Label) { 640b28d4f152ee9b76d8798b2bdcb06cb8d106841e6Rafael Espindola EmitCFIFrameMove(*I); 641b28d4f152ee9b76d8798b2bdcb06cb8d106841e6Rafael Espindola FoundOne = true; 642f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola } 643f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola } 644b28d4f152ee9b76d8798b2bdcb06cb8d106841e6Rafael Espindola assert(FoundOne); 645f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola} 646f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola 64714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner/// EmitFunctionBody - This method emits the body and trailer for a 64814c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner/// function. 64914c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattnervoid AsmPrinter::EmitFunctionBody() { 650edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner // Emit target-specific gunk before the function body. 651edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner EmitFunctionBodyStart(); 65283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 65349cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner bool ShouldPrintDebugScopes = DD && MMI->hasDebugInfo(); 65483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 65514c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Print out code for the function. 65614c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner bool HasAnyRealCode = false; 657dc86704114a065da0ff1d835edcd62aae51481ddBill Wendling const MachineInstr *LastMI = 0; 65814c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); 65914c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner I != E; ++I) { 66014c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Print a label for the basic block. 66114c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner EmitBasicBlockStart(I); 66214c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); 66314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner II != IE; ++II) { 664dc86704114a065da0ff1d835edcd62aae51481ddBill Wendling LastMI = II; 665dc86704114a065da0ff1d835edcd62aae51481ddBill Wendling 66614c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Print the assembly for the instruction. 667d014761c9337f270f497aa960d51ee424bb166d5Dale Johannesen if (!II->isLabel() && !II->isImplicitDef() && !II->isKill() && 668d014761c9337f270f497aa960d51ee424bb166d5Dale Johannesen !II->isDebugValue()) { 66914c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner HasAnyRealCode = true; 670ed33b13a10258fe1589bf6a76d6d65ec33823076Evan Cheng ++EmittedInsts; 671ed33b13a10258fe1589bf6a76d6d65ec33823076Evan Cheng } 672ed33b13a10258fe1589bf6a76d6d65ec33823076Evan Cheng 6739c4210794ee42542a20023cd0a800003797523e0Torok Edwin if (ShouldPrintDebugScopes) { 67403c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); 675cbbe287f8adc82a90827f036e048bb53d1573fedDevang Patel DD->beginInstruction(II); 6769c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 67783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 6783f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose()) 67947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner EmitComments(*II, OutStreamer.GetCommentOS()); 68047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 6810d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner switch (II->getOpcode()) { 6827431beaba2a01c3fe299c861b2ec85cbf1dc81c4Bill Wendling case TargetOpcode::PROLOG_LABEL: 683f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola emitPrologLabel(*II); 684f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola break; 685f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola 686518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::EH_LABEL: 687518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::GC_LABEL: 688300a4c5640fb1c717ba0d7108d15aec1bd7eb396Chris Lattner OutStreamer.EmitLabel(II->getOperand(0).getMCSymbol()); 6890d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 690518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::INLINEASM: 691300a4c5640fb1c717ba0d7108d15aec1bd7eb396Chris Lattner EmitInlineAsm(II); 6920d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 693343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen case TargetOpcode::DBG_VALUE: 694343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen if (isVerbose()) { 695343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen if (!EmitDebugValueComment(II, *this)) 696343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen EmitInstruction(II); 697343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen } 698343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen break; 699518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::IMPLICIT_DEF: 70017fedf216bc10c66e02694854f522cb602097005Chris Lattner if (isVerbose()) EmitImplicitDef(II, *this); 7010d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 702518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::KILL: 70317fedf216bc10c66e02694854f522cb602097005Chris Lattner if (isVerbose()) EmitKill(II, *this); 7040d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 7050d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner default: 70649a3ff9d1733cb16bdc97590e5b90508b8656565Devang Patel if (!TM.hasMCUseLoc()) 70749a3ff9d1733cb16bdc97590e5b90508b8656565Devang Patel MCLineEntry::Make(&OutStreamer, getCurrentSection()); 70849a3ff9d1733cb16bdc97590e5b90508b8656565Devang Patel 7090d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner EmitInstruction(II); 7100d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 7110d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner } 71283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 7139c4210794ee42542a20023cd0a800003797523e0Torok Edwin if (ShouldPrintDebugScopes) { 71403c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); 715cbbe287f8adc82a90827f036e048bb53d1573fedDevang Patel DD->endInstruction(II); 7169c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 71714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner } 71814c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner } 719dc86704114a065da0ff1d835edcd62aae51481ddBill Wendling 720dc86704114a065da0ff1d835edcd62aae51481ddBill Wendling // If the last instruction was a prolog label, then we have a situation where 721dc86704114a065da0ff1d835edcd62aae51481ddBill Wendling // we emitted a prolog but no function body. This results in the ending prolog 722dc86704114a065da0ff1d835edcd62aae51481ddBill Wendling // label equaling the end of function label and an invalid "row" in the 723dc86704114a065da0ff1d835edcd62aae51481ddBill Wendling // FDE. We need to emit a noop in this situation so that the FDE's rows are 724dc86704114a065da0ff1d835edcd62aae51481ddBill Wendling // valid. 7257490896f9dd4bb7955b39fa601ae7a9325e2775fBill Wendling bool RequiresNoop = LastMI && LastMI->isPrologLabel(); 726dc86704114a065da0ff1d835edcd62aae51481ddBill Wendling 72714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // If the function is empty and the object file uses .subsections_via_symbols, 728d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner // then we need to emit *something* to the function body to prevent the 729ee9eb411fffddbb8fe70418c05946a131889b487Chris Lattner // labels from collapsing together. Just emit a noop. 730dc86704114a065da0ff1d835edcd62aae51481ddBill Wendling if ((MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode) || RequiresNoop) { 731ee9eb411fffddbb8fe70418c05946a131889b487Chris Lattner MCInst Noop; 732ee9eb411fffddbb8fe70418c05946a131889b487Chris Lattner TM.getInstrInfo()->getNoopForMachoTarget(Noop); 733d61647d306bc297603c607411b2777b217cd65b6Chris Lattner if (Noop.getOpcode()) { 734d61647d306bc297603c607411b2777b217cd65b6Chris Lattner OutStreamer.AddComment("avoids zero-length function"); 735ee9eb411fffddbb8fe70418c05946a131889b487Chris Lattner OutStreamer.EmitInstruction(Noop); 736d61647d306bc297603c607411b2777b217cd65b6Chris Lattner } else // Target not mc-ized yet. 737ee9eb411fffddbb8fe70418c05946a131889b487Chris Lattner OutStreamer.EmitRawText(StringRef("\tnop\n")); 738ee9eb411fffddbb8fe70418c05946a131889b487Chris Lattner } 73983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 7406c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola const Function *F = MF->getFunction(); 7416c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola for (Function::const_iterator i = F->begin(), e = F->end(); i != e; ++i) { 7426c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola const BasicBlock *BB = i; 7436c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola if (!BB->hasAddressTaken()) 7446c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola continue; 7456c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola MCSymbol *Sym = GetBlockAddressSymbol(BB); 7466c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola if (Sym->isDefined()) 7476c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola continue; 7486c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola OutStreamer.AddComment("Address of block that was removed by CodeGen"); 7496c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola OutStreamer.EmitLabel(Sym); 7506c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola } 7516c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola 752edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner // Emit target-specific gunk after the function body. 753edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner EmitFunctionBodyEnd(); 75483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 755fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner // If the target wants a .size directive for the size of the function, emit 756fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner // it. 757fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner if (MAI->hasDotTypeDotSizeDirective()) { 7580c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner // Create a symbol for the end of function, so we can get the size as 7590c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner // difference between the function label and the temp label. 7600c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner MCSymbol *FnEndLabel = OutContext.CreateTempSymbol(); 7610c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner OutStreamer.EmitLabel(FnEndLabel); 76283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 7630c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner const MCExpr *SizeExp = 7640c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(FnEndLabel, OutContext), 765d55a2664f9493a4c3be242a75d339fac0ebe2e21Hal Finkel MCSymbolRefExpr::Create(CurrentFnSymForSize, 766d55a2664f9493a4c3be242a75d339fac0ebe2e21Hal Finkel OutContext), 7670c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner OutContext); 7680c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner OutStreamer.EmitELFSize(CurrentFnSym, SizeExp); 769fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner } 77083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 77114c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Emit post-function debug information. 7729c4210794ee42542a20023cd0a800003797523e0Torok Edwin if (DD) { 77303c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); 77403c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman DD->endFunction(MF); 7759c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 7769c4210794ee42542a20023cd0a800003797523e0Torok Edwin if (DE) { 77703c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled); 77803c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman DE->EndFunction(); 7799c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 78049cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner MMI->EndFunction(); 78183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 78214c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Print out jump tables referenced by the function. 78314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner EmitJumpTableInfo(); 78483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 785d26a80f666fb925956a4f19143265f5150756df0Chris Lattner OutStreamer.AddBlankLine(); 78614c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner} 78714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 78828ff35d030e2f49ff4e4b1544c015ebe011a530bDevang Patel/// getDebugValueLocation - Get location information encoded by DBG_VALUE 78928ff35d030e2f49ff4e4b1544c015ebe011a530bDevang Patel/// operands. 79083d808329b81ad7589ddc516566169b0331c25d1Jim GrosbachMachineLocation AsmPrinter:: 79183d808329b81ad7589ddc516566169b0331c25d1Jim GrosbachgetDebugValueLocation(const MachineInstr *MI) const { 79228ff35d030e2f49ff4e4b1544c015ebe011a530bDevang Patel // Target specific DBG_VALUE instructions are handled by each target. 79328ff35d030e2f49ff4e4b1544c015ebe011a530bDevang Patel return MachineLocation(); 79428ff35d030e2f49ff4e4b1544c015ebe011a530bDevang Patel} 79514c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 796acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel/// EmitDwarfRegOp - Emit dwarf register operation. 7970be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patelvoid AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const { 798c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel const TargetRegisterInfo *TRI = TM.getRegisterInfo(); 79937afca128db40b086752f3f62464ba08128c3b4dRafael Espindola int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false); 80037afca128db40b086752f3f62464ba08128c3b4dRafael Espindola 8019ebfbf8b9fd5f982e0db9293808bd32168615ba9Craig Topper for (const uint16_t *SR = TRI->getSuperRegisters(MLoc.getReg()); 8027bf114c1bd0390f4f485905d2fe9c7c6a048b8b7Rafael Espindola *SR && Reg < 0; ++SR) { 80337afca128db40b086752f3f62464ba08128c3b4dRafael Espindola Reg = TRI->getDwarfRegNum(*SR, false); 80437afca128db40b086752f3f62464ba08128c3b4dRafael Espindola // FIXME: Get the bit range this register uses of the superregister 80537afca128db40b086752f3f62464ba08128c3b4dRafael Espindola // so that we can produce a DW_OP_bit_piece 80637afca128db40b086752f3f62464ba08128c3b4dRafael Espindola } 80737afca128db40b086752f3f62464ba08128c3b4dRafael Espindola 80837afca128db40b086752f3f62464ba08128c3b4dRafael Espindola // FIXME: Handle cases like a super register being encoded as 80937afca128db40b086752f3f62464ba08128c3b4dRafael Espindola // DW_OP_reg 32 DW_OP_piece 4 DW_OP_reg 33 81037afca128db40b086752f3f62464ba08128c3b4dRafael Espindola 81137afca128db40b086752f3f62464ba08128c3b4dRafael Espindola // FIXME: We have no reasonable way of handling errors in here. The 81237afca128db40b086752f3f62464ba08128c3b4dRafael Espindola // caller might be in the middle of an dwarf expression. We should 81337afca128db40b086752f3f62464ba08128c3b4dRafael Espindola // probably assert that Reg >= 0 once debug info generation is more mature. 81437afca128db40b086752f3f62464ba08128c3b4dRafael Espindola 815acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel if (int Offset = MLoc.getOffset()) { 816c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel if (Reg < 32) { 817c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel OutStreamer.AddComment( 818c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel dwarf::OperationEncodingString(dwarf::DW_OP_breg0 + Reg)); 819c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel EmitInt8(dwarf::DW_OP_breg0 + Reg); 820c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel } else { 821c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel OutStreamer.AddComment("DW_OP_bregx"); 822c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel EmitInt8(dwarf::DW_OP_bregx); 823c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel OutStreamer.AddComment(Twine(Reg)); 824c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel EmitULEB128(Reg); 825c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel } 826acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel EmitSLEB128(Offset); 827acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel } else { 828acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel if (Reg < 32) { 829acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel OutStreamer.AddComment( 830acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel dwarf::OperationEncodingString(dwarf::DW_OP_reg0 + Reg)); 831acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel EmitInt8(dwarf::DW_OP_reg0 + Reg); 832acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel } else { 833c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel OutStreamer.AddComment("DW_OP_regx"); 834acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel EmitInt8(dwarf::DW_OP_regx); 835acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel OutStreamer.AddComment(Twine(Reg)); 836acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel EmitULEB128(Reg); 837acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel } 838acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel } 83937afca128db40b086752f3f62464ba08128c3b4dRafael Espindola 84037afca128db40b086752f3f62464ba08128c3b4dRafael Espindola // FIXME: Produce a DW_OP_bit_piece if we used a superregister 841acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel} 842acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel 843a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattnerbool AsmPrinter::doFinalization(Module &M) { 84440bbebde9d250b875a47a688d0c6552834ada48fChris Lattner // Emit global variables. 84540bbebde9d250b875a47a688d0c6552834ada48fChris Lattner for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 84640bbebde9d250b875a47a688d0c6552834ada48fChris Lattner I != E; ++I) 84748d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner EmitGlobalVariable(I); 8481ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola 8491ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola // Emit visibility info for declarations 8501ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) { 8511ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola const Function &F = *I; 8521ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola if (!F.isDeclaration()) 8531ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola continue; 8541ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola GlobalValue::VisibilityTypes V = F.getVisibility(); 8551ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola if (V == GlobalValue::DefaultVisibility) 8561ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola continue; 8571ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola 8581ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola MCSymbol *Name = Mang->getSymbol(&F); 8595129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastings EmitVisibility(Name, V, false); 8601ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola } 8611ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola 862b464d3ff72790260e8c2068afe856fd7299a6834Bill Wendling // Emit module flags. 863057d521e3d91a894f6c38fcbc21ee5950fbdf7b1Bill Wendling SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; 864057d521e3d91a894f6c38fcbc21ee5950fbdf7b1Bill Wendling M.getModuleFlagsMetadata(ModuleFlags); 865057d521e3d91a894f6c38fcbc21ee5950fbdf7b1Bill Wendling if (!ModuleFlags.empty()) 866057d521e3d91a894f6c38fcbc21ee5950fbdf7b1Bill Wendling getObjFileLowering().emitModuleFlags(OutStreamer, ModuleFlags, Mang, TM); 867b464d3ff72790260e8c2068afe856fd7299a6834Bill Wendling 86849cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner // Finalize debug and EH information. 86949cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner if (DE) { 87003c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman { 87103c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled); 8729c4210794ee42542a20023cd0a800003797523e0Torok Edwin DE->EndModule(); 8739c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 87449cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner delete DE; DE = 0; 87549cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner } 87649cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner if (DD) { 87703c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman { 87803c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); 8799c4210794ee42542a20023cd0a800003797523e0Torok Edwin DD->endModule(); 8809c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 88149cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner delete DD; DD = 0; 88249cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner } 88383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 8840a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // If the target wants to know about weak references, print them all. 88533adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->getWeakRefDirective()) { 8860a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // FIXME: This is not lazy, it would be nice to only print weak references 8870a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // to stuff that is actually used. Note that doing so would require targets 8880a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // to notice uses in operands (due to constant exprs etc). This should 8890a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // happen with the MC stuff eventually. 8900a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner 8910a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // Print out module-level global variables here. 8920a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 8930a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner I != E; ++I) { 89408ce3b473d06e0f7806df3d44b7b36ac40c58803Chris Lattner if (!I->hasExternalWeakLinkage()) continue; 895deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference); 8960a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner } 89783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 898c6fdced3dbfdf673cc9b01dfad4f08e316d8803dChris Lattner for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) { 89908ce3b473d06e0f7806df3d44b7b36ac40c58803Chris Lattner if (!I->hasExternalWeakLinkage()) continue; 900deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference); 9010a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner } 90215404d060ba8b604c03b9223a0f2e2abcd0fddedRafael Espindola } 90315404d060ba8b604c03b9223a0f2e2abcd0fddedRafael Espindola 904cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner if (MAI->hasSetDirective()) { 9053a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner OutStreamer.AddBlankLine(); 9068b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); 9070a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner I != E; ++I) { 908deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner MCSymbol *Name = Mang->getSymbol(I); 909325be7c608a37d87e4f3d731e11fa3dd34f529b5Anton Korobeynikov 910b899d959332871eb62dc22a9ffd81e0e97d96710Jay Foad const GlobalValue *GV = I->getAliasedGlobal(); 911deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner MCSymbol *Target = Mang->getSymbol(GV); 9125c40e694dcd679bf26b962189c1d12b32fff07cdChris Lattner 91310b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner if (I->hasExternalLinkage() || !MAI->getWeakRefDirective()) 914a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitSymbolAttribute(Name, MCSA_Global); 91510b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner else if (I->hasWeakLinkage()) 916a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitSymbolAttribute(Name, MCSA_WeakReference); 91710b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner else 91810595490ccf25b4960936638fac7a673eaf82e68Chris Lattner assert(I->hasLocalLinkage() && "Invalid alias linkage"); 91922c9e65643e0c6b43be37a19e59491ef0081092cAnton Korobeynikov 920be9dfcef82c58063708e039bea3cf972ba41581bChris Lattner EmitVisibility(Name, I->getVisibility()); 92122c9e65643e0c6b43be37a19e59491ef0081092cAnton Korobeynikov 922c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner // Emit the directives as assignments aka .set: 92383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach OutStreamer.EmitAssignment(Name, 924c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner MCSymbolRefExpr::Create(Target, OutContext)); 9258b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov } 9268b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov } 9278b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov 9281465d61bdd36cfd6021036a527895f0dd358e97dDuncan Sands GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); 9295eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen assert(MI && "AsmPrinter didn't require GCModuleInfo?"); 9305eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; ) 9315eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I)) 9327d73c7f0d618dd6661cd55834c58aa62f22b28feChris Lattner MP->finishAssembly(*this); 933ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksen 934a779a9899a5e23bd5198973f4709d66cb4bc2e64Dan Gohman // If we don't have any trampolines, then we don't require stack memory 935a779a9899a5e23bd5198973f4709d66cb4bc2e64Dan Gohman // to be executable. Some targets have a directive to declare this. 9360a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline"); 937a779a9899a5e23bd5198973f4709d66cb4bc2e64Dan Gohman if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty()) 93874aae4726a66733c5872588287535a984f9a94c7Chris Lattner if (const MCSection *S = MAI->getNonexecutableStackSection(OutContext)) 939f9f93e4388962b678fd59b7af5212d4cc0d38be2Chris Lattner OutStreamer.SwitchSection(S); 94083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 941bd23d5fda85e38c88dfa668a99777cd05c524822Chris Lattner // Allow the target to emit any magic that it wants at the end of the file, 942bd23d5fda85e38c88dfa668a99777cd05c524822Chris Lattner // after everything else has gone out. 943bd23d5fda85e38c88dfa668a99777cd05c524822Chris Lattner EmitEndOfAsmFile(M); 94483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 945a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner delete Mang; Mang = 0; 94649cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner MMI = 0; 94783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 9482b2954f00ba02ca1a902f47080cd9f06aebc0378Chris Lattner OutStreamer.Finish(); 949a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner return false; 950a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner} 951a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner 95225045bdcda822d63674e2df7e34016536c5d3fa7Chris Lattnervoid AsmPrinter::SetupMachineFunction(MachineFunction &MF) { 953b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner this->MF = &MF; 954412c3a5bc9e70fe8579551216786e70d323a3dd5Chris Lattner // Get the function symbol. 955deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner CurrentFnSym = Mang->getSymbol(MF.getFunction()); 956d55a2664f9493a4c3be242a75d339fac0ebe2e21Hal Finkel CurrentFnSymForSize = CurrentFnSym; 957b71d1b2fe2c0673005283b48be2f37c750ce367bDavid Greene 9583f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose()) 959b71d1b2fe2c0673005283b48be2f37c750ce367bDavid Greene LI = &getAnalysis<MachineLoopInfo>(); 960a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner} 961a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner 9621606e8e4cd937e6de6681f686c266cf61722d972Evan Chengnamespace { 9631606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng // SectionCPs - Keep track the alignment, constpool entries per Section. 9641606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng struct SectionCPs { 965a87dea4f8c546ca748f1777a8d1cabcc06515d91Chris Lattner const MCSection *S; 9661606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Alignment; 9671606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng SmallVector<unsigned, 4> CPEs; 968cabdd7425d30f7eb659ecb0cc5efbc4052dd78a8Douglas Gregor SectionCPs(const MCSection *s, unsigned a) : S(s), Alignment(a) {} 9691606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng }; 9701606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng} 9711606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 9723b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// EmitConstantPool - Print to the current output stream assembly 9733b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// representations of the constants in the constant pool MCP. This is 9743b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// used to print out constants which have been "spilled to memory" by 9753b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// the code generator. 9763b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// 977a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattnervoid AsmPrinter::EmitConstantPool() { 978a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner const MachineConstantPool *MCP = MF->getConstantPool(); 979fa77d43ba1d91ed39f46e11caeb28dcabae9e193Chris Lattner const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants(); 9803b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner if (CP.empty()) return; 9812d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng 982088ae8393f124564ca9ab70654645aa656e5646fAnton Korobeynikov // Calculate sections for constant pool entries. We collect entries to go into 983088ae8393f124564ca9ab70654645aa656e5646fAnton Korobeynikov // the same section together to reduce amount of section switch statements. 9841606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng SmallVector<SectionCPs, 4> CPSections; 9852d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng for (unsigned i = 0, e = CP.size(); i != e; ++i) { 986298414ec1891ce8d3a1b69e6019ad8765c8e69dcChris Lattner const MachineConstantPoolEntry &CPE = CP[i]; 9871606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Align = CPE.getAlignment(); 98883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 9895c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner SectionKind Kind; 9905c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner switch (CPE.getRelocationInfo()) { 9915c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner default: llvm_unreachable("Unknown section kind"); 9922798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner case 2: Kind = SectionKind::getReadOnlyWithRel(); break; 9934c50922f6be96fdb1e9a924aeeecf91638e2c52bChris Lattner case 1: 9942798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner Kind = SectionKind::getReadOnlyWithRelLocal(); 9954c50922f6be96fdb1e9a924aeeecf91638e2c52bChris Lattner break; 9965c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner case 0: 9974c50922f6be96fdb1e9a924aeeecf91638e2c52bChris Lattner switch (TM.getTargetData()->getTypeAllocSize(CPE.getType())) { 9982798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner case 4: Kind = SectionKind::getMergeableConst4(); break; 9992798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner case 8: Kind = SectionKind::getMergeableConst8(); break; 10002798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner case 16: Kind = SectionKind::getMergeableConst16();break; 10012798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner default: Kind = SectionKind::getMergeableConst(); break; 10024c50922f6be96fdb1e9a924aeeecf91638e2c52bChris Lattner } 10035c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner } 10045c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner 100583d77faf6e8fc2c1c2377d037283dc162d8667a1Chris Lattner const MCSection *S = getObjFileLowering().getSectionForConstant(Kind); 100683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 10071606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng // The number of sections are small, just do a linear search from the 10081606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng // last section to the first. 10091606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng bool Found = false; 10101606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned SecIdx = CPSections.size(); 10111606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng while (SecIdx != 0) { 10121606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (CPSections[--SecIdx].S == S) { 10131606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng Found = true; 10141606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng break; 10151606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng } 10161606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng } 10171606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (!Found) { 10181606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng SecIdx = CPSections.size(); 10191606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng CPSections.push_back(SectionCPs(S, Align)); 10201606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng } 10211606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 10221606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (Align > CPSections[SecIdx].Alignment) 10231606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng CPSections[SecIdx].Alignment = Align; 10241606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng CPSections[SecIdx].CPEs.push_back(i); 10252d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng } 10262d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng 1027088ae8393f124564ca9ab70654645aa656e5646fAnton Korobeynikov // Now print stuff into the calculated sections. 10281606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng for (unsigned i = 0, e = CPSections.size(); i != e; ++i) { 10296c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(CPSections[i].S); 10301606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng EmitAlignment(Log2_32(CPSections[i].Alignment)); 10312d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng 10321606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Offset = 0; 10331606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng for (unsigned j = 0, ee = CPSections[i].CPEs.size(); j != ee; ++j) { 10341606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned CPI = CPSections[i].CPEs[j]; 10351606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng MachineConstantPoolEntry CPE = CP[CPI]; 10361606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 10371606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng // Emit inter-object padding for alignment. 10381606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned AlignMask = CPE.getAlignment() - 1; 10391606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned NewOffset = (Offset + AlignMask) & ~AlignMask; 1040aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner OutStreamer.EmitFill(NewOffset - Offset, 0/*fillval*/, 0/*addrspace*/); 10411606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 1042db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty = CPE.getType(); 1043777d2306b36816a53bc1ae1244c0dc7d998ae691Duncan Sands Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty); 10443924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner OutStreamer.EmitLabel(GetCPISymbol(CPI)); 10453924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner 10461606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (CPE.isMachineConstantPoolEntry()) 10471606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng EmitMachineConstantPoolValue(CPE.Val.MachineCPVal); 1048088ae8393f124564ca9ab70654645aa656e5646fAnton Korobeynikov else 10491606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng EmitGlobalConstant(CPE.Val.ConstVal); 10503029f920519e0871a5aad5d7c592281093953733Chris Lattner } 10513b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner } 10523b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner} 10533b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner 105437efe6764568a3829fee26aba532283131d1a104Nate Begeman/// EmitJumpTableInfo - Print assembly representations of the jump tables used 105583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach/// by the current function to the current output stream. 105637efe6764568a3829fee26aba532283131d1a104Nate Begeman/// 105714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattnervoid AsmPrinter::EmitJumpTableInfo() { 105814c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 105944e87255e9b7a9d8ecb558690db1181882c08045Chris Lattner if (MJTI == 0) return; 106095da605e15a6f108b551ecc6772823ea53de3007Richard Osborne if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline) return; 106137efe6764568a3829fee26aba532283131d1a104Nate Begeman const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 106237efe6764568a3829fee26aba532283131d1a104Nate Begeman if (JT.empty()) return; 10639de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov 106483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach // Pick the directive to use to print the jump table entries, and switch to 10652f1ae88445c696a9b9d61e14747ba721190cdc99Nate Begeman // the appropriate section. 106614c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner const Function *F = MF->getFunction(); 1067b13bafe5c12dd908b55c559c93adaeb1627ed096Evan Cheng bool JTInDiffSection = false; 1068f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner if (// In PIC mode, we need to emit the jump table to the same section as the 1069f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // function body itself, otherwise the label differences won't make sense. 1070f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // FIXME: Need a better predicate for this: what about custom entries? 1071f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 || 1072f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // We should also do if the section name is NULL or function is declared 1073f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // in discardable section 1074f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // FIXME: this isn't the right predicate, should be based on the MCSection 1075f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // for the function. 1076f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner F->isWeakForLinker()) { 107714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F,Mang,TM)); 10782f1ae88445c696a9b9d61e14747ba721190cdc99Nate Begeman } else { 107983d77faf6e8fc2c1c2377d037283dc162d8667a1Chris Lattner // Otherwise, drop it in the readonly section. 108083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach const MCSection *ReadOnlySection = 10812798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner getObjFileLowering().getSectionForConstant(SectionKind::getReadOnly()); 10826c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(ReadOnlySection); 1083b13bafe5c12dd908b55c559c93adaeb1627ed096Evan Cheng JTInDiffSection = true; 10842f1ae88445c696a9b9d61e14747ba721190cdc99Nate Begeman } 1085071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner 1086071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner EmitAlignment(Log2_32(MJTI->getEntryAlignment(*TM.getTargetData()))); 108783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 10882fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson // If we know the form of the jump table, go ahead and tag it as such. 10892fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson if (!JTInDiffSection) { 10902fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32) { 10912fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson OutStreamer.EmitJumpTable32Region(); 10922fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson } else { 10932fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson OutStreamer.EmitDataRegion(); 10942fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson } 10952fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson } 10962fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson 10973b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) { 10983b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 109983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 110083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach // If this jump table was deleted, ignore it. 110107371882208f913d18a7f2a47373eaee7138416bChris Lattner if (JTBBs.empty()) continue; 110252a51e38dc312aa262b0d771419afe1785f3cb22Nate Begeman 1103e35df92eca194365f984f9d24a74e4ddd6669c40Chris Lattner // For the EK_LabelDifference32 entry, if the target supports .set, emit a 1104e35df92eca194365f984f9d24a74e4ddd6669c40Chris Lattner // .set directive for each unique entry. This reduces the number of 1105e35df92eca194365f984f9d24a74e4ddd6669c40Chris Lattner // relocations the assembler will generate for the jump table. 1106e35df92eca194365f984f9d24a74e4ddd6669c40Chris Lattner if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 && 1107cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner MAI->hasSetDirective()) { 11083b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner SmallPtrSet<const MachineBasicBlock*, 16> EmittedSets; 11093b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner const TargetLowering *TLI = TM.getTargetLowering(); 111014c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF,JTI,OutContext); 11113b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { 11123b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner const MachineBasicBlock *MBB = JTBBs[ii]; 11133b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner if (!EmittedSets.insert(MBB)) continue; 111483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1115c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner // .set LJTSet, LBB32-base 1116c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner const MCExpr *LHS = 11171b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 1118c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner OutStreamer.EmitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()), 1119c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner MCBinaryExpr::CreateSub(LHS, Base, OutContext)); 11203b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner } 112183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach } 112283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1123ab4c366274a582dd8146b2820c6b999cad5fce36Duncan Sands // On some targets (e.g. Darwin) we want to emit two consecutive labels 1124393a8eea3c15de08eaf6953aa8a65a3961b76153Chris Lattner // before each jump table. The first label is never referenced, but tells 1125393a8eea3c15de08eaf6953aa8a65a3961b76153Chris Lattner // the assembler and linker the extents of the jump table object. The 1126393a8eea3c15de08eaf6953aa8a65a3961b76153Chris Lattner // second label is actually referenced by the code. 11273924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner if (JTInDiffSection && MAI->getLinkerPrivateGlobalPrefix()[0]) 1128beeb93e6ba48af2661eabc4872d8b159fb43e5dbChris Lattner // FIXME: This doesn't have to have any specific name, just any randomly 1129beeb93e6ba48af2661eabc4872d8b159fb43e5dbChris Lattner // named and numbered 'l' label would work. Simplify GetJTISymbol. 11303b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner OutStreamer.EmitLabel(GetJTISymbol(JTI, true)); 11313924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner 11323b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner OutStreamer.EmitLabel(GetJTISymbol(JTI)); 11333924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner 11346bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) 11353b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner EmitJumpTableEntry(MJTI, JTBBs[ii], JTI); 113637efe6764568a3829fee26aba532283131d1a104Nate Begeman } 113737efe6764568a3829fee26aba532283131d1a104Nate Begeman} 113837efe6764568a3829fee26aba532283131d1a104Nate Begeman 11396bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner/// EmitJumpTableEntry - Emit a jump table entry for the specified MBB to the 11406bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner/// current stream. 11416bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattnervoid AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, 11426bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner const MachineBasicBlock *MBB, 11436bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner unsigned UID) const { 1144e5005d0062fa4c8f5707428f7b8ad8484a002d83Jakob Stoklund Olesen assert(MBB && MBB->getNumber() >= 0 && "Invalid basic block"); 1145ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner const MCExpr *Value = 0; 1146ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner switch (MJTI->getEntryKind()) { 114795da605e15a6f108b551ecc6772823ea53de3007Richard Osborne case MachineJumpTableInfo::EK_Inline: 11484d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie llvm_unreachable("Cannot emit EK_Inline jump table entry"); 114985fe07866a3b240d9facef3b2f2ea81a0a8db018Chris Lattner case MachineJumpTableInfo::EK_Custom32: 11506bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner Value = TM.getTargetLowering()->LowerCustomJumpTableEntry(MJTI, MBB, UID, 115185fe07866a3b240d9facef3b2f2ea81a0a8db018Chris Lattner OutContext); 115285fe07866a3b240d9facef3b2f2ea81a0a8db018Chris Lattner break; 1153ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner case MachineJumpTableInfo::EK_BlockAddress: 1154ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // EK_BlockAddress - Each entry is a plain address of block, e.g.: 1155ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .word LBB123 11561b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 1157ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner break; 1158ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner case MachineJumpTableInfo::EK_GPRel32BlockAddress: { 1159ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // EK_GPRel32BlockAddress - Each entry is an address of block, encoded 1160ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // with a relocation as gp-relative, e.g.: 1161ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .gprel32 LBB123 11621b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner MCSymbol *MBBSym = MBB->getSymbol(); 1163718fb59801320b8cb22363d115b5fc5ec40dc1f5Chris Lattner OutStreamer.EmitGPRel32Value(MCSymbolRefExpr::Create(MBBSym, OutContext)); 116478f485afb723121eedf4b6907ae6eb53da8af03cChris Lattner return; 11659de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov } 116685fe07866a3b240d9facef3b2f2ea81a0a8db018Chris Lattner 11676c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka case MachineJumpTableInfo::EK_GPRel64BlockAddress: { 11686c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka // EK_GPRel64BlockAddress - Each entry is an address of block, encoded 11696c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka // with a relocation as gp-relative, e.g.: 11706c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka // .gpdword LBB123 11716c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka MCSymbol *MBBSym = MBB->getSymbol(); 11726c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka OutStreamer.EmitGPRel64Value(MCSymbolRefExpr::Create(MBBSym, OutContext)); 11736c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka return; 11746c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka } 11756c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka 1176ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner case MachineJumpTableInfo::EK_LabelDifference32: { 1177ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // EK_LabelDifference32 - Each entry is the address of the block minus 1178ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // the address of the jump table. This is used for PIC jump tables where 1179ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // gprel32 is not supported. e.g.: 1180ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .word LBB123 - LJTI1_2 1181ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // If the .set directive is supported, this is emitted as: 1182ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .set L4_5_set_123, LBB123 - LJTI1_2 1183ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .word L4_5_set_123 118483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 118583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach // If we have emitted set directives for the jump table entries, print 1186ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // them rather than the entries themselves. If we're emitting PIC, then 1187ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // emit the table entries as differences between two text section labels. 1188cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner if (MAI->hasSetDirective()) { 1189ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // If we used .set, reference the .set's symbol. 11906bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner Value = MCSymbolRefExpr::Create(GetJTSetSymbol(UID, MBB->getNumber()), 1191ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner OutContext); 1192ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner break; 1193ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner } 11941aca2492526c0a1aa464f2993084f9b30b53c009Chris Lattner // Otherwise, use the difference as the jump table entry. 11951b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 11966bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner const MCExpr *JTI = MCSymbolRefExpr::Create(GetJTISymbol(UID), OutContext); 1197ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner Value = MCBinaryExpr::CreateSub(Value, JTI, OutContext); 1198ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner break; 1199ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner } 12009de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov } 120183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1202ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner assert(Value && "Unknown entry kind!"); 120383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1204071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner unsigned EntrySize = MJTI->getEntrySize(*TM.getTargetData()); 1205ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner OutStreamer.EmitValue(Value, EntrySize, /*addrspace*/0); 12069de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov} 12079de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov 12089de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov 1209ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner/// EmitSpecialLLVMGlobal - Check to see if the specified global is a 1210ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner/// special global used by LLVM. If so, emit it and return true, otherwise 1211ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner/// do nothing and return false. 1212ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattnerbool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { 121303d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar if (GV->getName() == "llvm.used") { 12143a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner if (MAI->hasNoDeadStrip()) // No need to emit this at all. 1215b753a9bb6277cd34ffc55f8674087ff8c3097a11Andrew Lenharth EmitLLVMUsedList(GV->getInitializer()); 1216b753a9bb6277cd34ffc55f8674087ff8c3097a11Andrew Lenharth return true; 1217b753a9bb6277cd34ffc55f8674087ff8c3097a11Andrew Lenharth } 1218b753a9bb6277cd34ffc55f8674087ff8c3097a11Andrew Lenharth 1219401e10c4fbfcdcfade5065093e2ca97f69a1d144Chris Lattner // Ignore debug and non-emitted data. This handles llvm.compiler.used. 1220266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner if (GV->getSection() == "llvm.metadata" || 1221266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner GV->hasAvailableExternallyLinkage()) 1222266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner return true; 122383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 12247809811e4ed3c2462efa327cef0464b9844baea2Jim Laskey if (!GV->hasAppendingLinkage()) return false; 12257809811e4ed3c2462efa327cef0464b9844baea2Jim Laskey 12267809811e4ed3c2462efa327cef0464b9844baea2Jim Laskey assert(GV->hasInitializer() && "Not a special LLVM global!"); 122783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1228f231c07228deb75b6cd5ae7c9c057bc8303c6998Chris Lattner if (GV->getName() == "llvm.global_ctors") { 12294a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov EmitXXStructorList(GV->getInitializer(), /* isCtor */ true); 123083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 123171eae713153e564ec743c5c4162ff258c255de78Chris Lattner if (TM.getRelocationModel() == Reloc::Static && 12323a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner MAI->hasStaticCtorDtorReferenceInStaticMode()) { 12333a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner StringRef Sym(".constructors_used"); 12343a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym), 1235a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner MCSA_Reference); 12363a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner } 1237ea3a9ff53d699bc22fcff52dbbce8aab6578a020Chris Lattner return true; 123883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach } 123983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1240f231c07228deb75b6cd5ae7c9c057bc8303c6998Chris Lattner if (GV->getName() == "llvm.global_dtors") { 12414a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov EmitXXStructorList(GV->getInitializer(), /* isCtor */ false); 124271eae713153e564ec743c5c4162ff258c255de78Chris Lattner 124371eae713153e564ec743c5c4162ff258c255de78Chris Lattner if (TM.getRelocationModel() == Reloc::Static && 12443a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner MAI->hasStaticCtorDtorReferenceInStaticMode()) { 12453a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner StringRef Sym(".destructors_used"); 12463a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym), 1247a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner MCSA_Reference); 12483a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner } 1249ea3a9ff53d699bc22fcff52dbbce8aab6578a020Chris Lattner return true; 1250ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner } 125183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1252ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner return false; 1253ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner} 1254ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 125533adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner/// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each 1256d2e51af0358b571367a9f1e5175b87e9dd72edf8Dale Johannesen/// global in the specified llvm.used list for which emitUsedDirectiveFor 1257d2e51af0358b571367a9f1e5175b87e9dd72edf8Dale Johannesen/// is true, as being used with this directive. 12587d715dfe6d66be257926f626df96a0e2bd38dc1fJay Foadvoid AsmPrinter::EmitLLVMUsedList(const Constant *List) { 1259a119de86a064414622562cfe32953de7f9b0ee40Dan Gohman // Should be an array of 'i8*'. 12607d715dfe6d66be257926f626df96a0e2bd38dc1fJay Foad const ConstantArray *InitList = dyn_cast<ConstantArray>(List); 1261cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner if (InitList == 0) return; 126283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1263cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { 126416fe990e56102a355f1e77aca93bf8c79d7b9eb2Chris Lattner const GlobalValue *GV = 126516fe990e56102a355f1e77aca93bf8c79d7b9eb2Chris Lattner dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts()); 12663a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner if (GV && getObjFileLowering().shouldEmitUsedDirectiveFor(GV, Mang)) 1267deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner OutStreamer.EmitSymbolAttribute(Mang->getSymbol(GV), MCSA_NoDeadStrip); 1268cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner } 1269cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner} 1270cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner 12714a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikovtypedef std::pair<unsigned, Constant*> Structor; 1272fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands 12739a7d48ae67d1f151d5339d37ce66c57179de77b4Duncan Sandsstatic bool priority_order(const Structor& lhs, const Structor& rhs) { 1274fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands return lhs.first < rhs.first; 1275fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands} 1276fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands 1277fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands/// EmitXXStructorList - Emit the ctor or dtor list taking into account the init 1278fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands/// priority. 12794a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikovvoid AsmPrinter::EmitXXStructorList(const Constant *List, bool isCtor) { 1280ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner // Should be an array of '{ int, void ()* }' structs. The first value is the 1281fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands // init priority. 1282ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner if (!isa<ConstantArray>(List)) return; 1283fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands 1284fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands // Sanity check the structors list. 1285fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands const ConstantArray *InitList = dyn_cast<ConstantArray>(List); 1286fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands if (!InitList) return; // Not an array! 1287fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands StructType *ETy = dyn_cast<StructType>(InitList->getType()->getElementType()); 1288fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands if (!ETy || ETy->getNumElements() != 2) return; // Not an array of pairs! 1289fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands if (!isa<IntegerType>(ETy->getTypeAtIndex(0U)) || 1290fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands !isa<PointerType>(ETy->getTypeAtIndex(1U))) return; // Not (int, ptr). 1291fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands 1292fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands // Gather the structors in a form that's convenient for sorting by priority. 1293fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands SmallVector<Structor, 8> Structors; 1294fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { 1295fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i)); 1296fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands if (!CS) continue; // Malformed. 1297fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands if (CS->getOperand(1)->isNullValue()) 1298fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands break; // Found a null terminator, skip the rest. 1299fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0)); 1300fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands if (!Priority) continue; // Malformed. 1301fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands Structors.push_back(std::make_pair(Priority->getLimitedValue(65535), 1302fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands CS->getOperand(1))); 1303fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands } 1304fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands 13054a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov // Emit the function pointers in the target-specific order 13064a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov const TargetData *TD = TM.getTargetData(); 13074a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov unsigned Align = Log2_32(TD->getPointerPrefAlignment()); 13084a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov std::stable_sort(Structors.begin(), Structors.end(), priority_order); 13094a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov for (unsigned i = 0, e = Structors.size(); i != e; ++i) { 13104a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov const MCSection *OutputSection = 13114a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov (isCtor ? 13124a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov getObjFileLowering().getStaticCtorSection(Structors[i].first) : 13134a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov getObjFileLowering().getStaticDtorSection(Structors[i].first)); 13144a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov OutStreamer.SwitchSection(OutputSection); 13154a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov if (OutStreamer.getCurrentSection() != OutStreamer.getPreviousSection()) 13164a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov EmitAlignment(Align); 131734982576a43887e7f062ed0a3571af2cbab003f3James Molloy EmitXXStructor(Structors[i].second); 13184a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov } 1319ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner} 13203b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner 1321f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey//===--------------------------------------------------------------------===// 1322f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey// Emission and print routines 1323f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey// 1324f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 1325f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// EmitInt8 - Emit a byte directive and value. 1326f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// 1327f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskeyvoid AsmPrinter::EmitInt8(int Value) const { 13285eaa54e210256a939f15e918303197916c992aeeChris Lattner OutStreamer.EmitIntValue(Value, 1, 0/*addrspace*/); 1329f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey} 1330f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 1331f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// EmitInt16 - Emit a short directive and value. 1332f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// 1333f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskeyvoid AsmPrinter::EmitInt16(int Value) const { 13345eaa54e210256a939f15e918303197916c992aeeChris Lattner OutStreamer.EmitIntValue(Value, 2, 0/*addrspace*/); 1335f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey} 1336f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 1337f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// EmitInt32 - Emit a long directive and value. 1338f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// 1339f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskeyvoid AsmPrinter::EmitInt32(int Value) const { 13405eaa54e210256a939f15e918303197916c992aeeChris Lattner OutStreamer.EmitIntValue(Value, 4, 0/*addrspace*/); 1341f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey} 1342f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 13430d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner/// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size 13440d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner/// in bytes of the directive is specified by Size and Hi/Lo specify the 13450d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner/// labels. This implicitly uses .set if it is available. 13460d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattnervoid AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, 13470d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner unsigned Size) const { 13480d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner // Get the Hi-Lo expression. 134983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach const MCExpr *Diff = 13500d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(Hi, OutContext), 13510d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner MCSymbolRefExpr::Create(Lo, OutContext), 13520d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner OutContext); 135383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 13540d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner if (!MAI->hasSetDirective()) { 13550d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner OutStreamer.EmitValue(Diff, Size, 0/*AddrSpace*/); 13560d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner return; 13570d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner } 13580d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner 13590d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner // Otherwise, emit with .set (aka assignment). 1360c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner MCSymbol *SetLabel = GetTempSymbol("set", SetCounter++); 13610d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner OutStreamer.EmitAssignment(SetLabel, Diff); 13626cde3e6e993126df756e3be5b9ef43540b904644Chris Lattner OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/); 13630d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner} 13640d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner 136583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach/// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo" 1366f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel/// where the size in bytes of the directive is specified by Size and Hi/Lo 1367f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel/// specify the labels. This implicitly uses .set if it is available. 1368f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patelvoid AsmPrinter::EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset, 136983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach const MCSymbol *Lo, unsigned Size) 1370f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel const { 137183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1372f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel // Emit Hi+Offset - Lo 1373f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel // Get the Hi+Offset expression. 1374f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel const MCExpr *Plus = 137583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Hi, OutContext), 1376f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel MCConstantExpr::Create(Offset, OutContext), 1377f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel OutContext); 137883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1379f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel // Get the Hi+Offset-Lo expression. 138083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach const MCExpr *Diff = 1381f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel MCBinaryExpr::CreateSub(Plus, 1382f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel MCSymbolRefExpr::Create(Lo, OutContext), 1383f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel OutContext); 138483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 138583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach if (!MAI->hasSetDirective()) 1386f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel OutStreamer.EmitValue(Diff, 4, 0/*AddrSpace*/); 1387f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel else { 1388f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel // Otherwise, emit with .set (aka assignment). 1389f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel MCSymbol *SetLabel = GetTempSymbol("set", SetCounter++); 1390f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel OutStreamer.EmitAssignment(SetLabel, Diff); 1391f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel OutStreamer.EmitSymbolValue(SetLabel, 4, 0/*AddrSpace*/); 1392f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel } 1393f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel} 1394b1fcfbe89bd155fb88485b2a3a995adba3994003Devang Patel 139583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach/// EmitLabelPlusOffset - Emit something like ".long Label+Offset" 1396b1fcfbe89bd155fb88485b2a3a995adba3994003Devang Patel/// where the size in bytes of the directive is specified by Size and Label 1397b1fcfbe89bd155fb88485b2a3a995adba3994003Devang Patel/// specifies the label. This implicitly uses .set if it is available. 1398b1fcfbe89bd155fb88485b2a3a995adba3994003Devang Patelvoid AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, 139983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach unsigned Size) 1400b1fcfbe89bd155fb88485b2a3a995adba3994003Devang Patel const { 140183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1402b1fcfbe89bd155fb88485b2a3a995adba3994003Devang Patel // Emit Label+Offset 1403b1fcfbe89bd155fb88485b2a3a995adba3994003Devang Patel const MCExpr *Plus = 140483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Label, OutContext), 1405b1fcfbe89bd155fb88485b2a3a995adba3994003Devang Patel MCConstantExpr::Create(Offset, OutContext), 1406b1fcfbe89bd155fb88485b2a3a995adba3994003Devang Patel OutContext); 140783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1408a660be7587f52d269135a54e2d485bf7a7bc9c50Devang Patel OutStreamer.EmitValue(Plus, 4, 0/*AddrSpace*/); 1409b1fcfbe89bd155fb88485b2a3a995adba3994003Devang Patel} 141083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 14110d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner 1412f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey//===----------------------------------------------------------------------===// 1413f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 14143a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// EmitAlignment - Emit an alignment directive to the specified power of 14153a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// two boundary. For example, if you pass in 3 here, you will get an 8 14163a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// byte alignment. If a global value is specified, and if that global has 1417e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner// an explicit alignment requested, it will override the alignment request 1418e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner// if required for correctness. 14193a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// 1420a7b611c10d0e5fef5870d854518e639ce3d3c6beChris Lattnervoid AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const { 1421e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner if (GV) NumBits = getGVAlignmentLog2(GV, *TM.getTargetData(), NumBits); 142283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1423e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner if (NumBits == 0) return; // 1-byte aligned: no need to emit alignment. 142483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1425dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattner if (getCurrentSection()->getKind().isText()) 14262cce3712fafb2e72e144414377cd48f5ab95a5aeChris Lattner OutStreamer.EmitCodeAlignment(1 << NumBits); 14272cce3712fafb2e72e144414377cd48f5ab95a5aeChris Lattner else 14282cce3712fafb2e72e144414377cd48f5ab95a5aeChris Lattner OutStreamer.EmitValueToAlignment(1 << NumBits, 0, 1, 0); 1429bfddc2030a7e67b9e0c42276525d6932375ff261Chris Lattner} 1430a5bb59f85613e8ce481351803e7388f5ab466e72David Greene 143144e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner//===----------------------------------------------------------------------===// 143244e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner// Constant emission. 143344e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner//===----------------------------------------------------------------------===// 143444e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner 143552492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner/// LowerConstant - Lower the specified LLVM Constant to an MCExpr. 143652492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner/// 143752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattnerstatic const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) { 143852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner MCContext &Ctx = AP.OutContext; 143983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 144052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (CV->isNullValue() || isa<UndefValue>(CV)) 144152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCConstantExpr::Create(0, Ctx); 144252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner 144352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) 144452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCConstantExpr::Create(CI->getZExtValue(), Ctx); 144583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 144652492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) 1447deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner return MCSymbolRefExpr::Create(AP.Mang->getSymbol(GV), Ctx); 14483d7ff08c82be2f95902089dd59cff2a37999a991Bill Wendling 144952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) 145052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCSymbolRefExpr::Create(AP.GetBlockAddressSymbol(BA), Ctx); 145183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1452fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV); 1453fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner if (CE == 0) { 145452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner llvm_unreachable("Unknown constant value to lower!"); 1455fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner } 145683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1457fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner switch (CE->getOpcode()) { 1458618f17702d09795279717827eeb06632d6ef49e4Dan Gohman default: 1459618f17702d09795279717827eeb06632d6ef49e4Dan Gohman // If the code isn't optimized, there may be outstanding folding 1460618f17702d09795279717827eeb06632d6ef49e4Dan Gohman // opportunities. Attempt to fold the expression using TargetData as a 1461618f17702d09795279717827eeb06632d6ef49e4Dan Gohman // last resort before giving up. 146254e72eca0c5d012546fcc6d1fdac7ee56c90686cDan Gohman if (Constant *C = 146354e72eca0c5d012546fcc6d1fdac7ee56c90686cDan Gohman ConstantFoldConstantExpression(CE, AP.TM.getTargetData())) 146454e72eca0c5d012546fcc6d1fdac7ee56c90686cDan Gohman if (C != CE) 146554e72eca0c5d012546fcc6d1fdac7ee56c90686cDan Gohman return LowerConstant(C, AP); 14669f6a6862be09df9f1e90b0560e52da7d15935f24Dan Gohman 14679f6a6862be09df9f1e90b0560e52da7d15935f24Dan Gohman // Otherwise report the problem to the user. 14689f6a6862be09df9f1e90b0560e52da7d15935f24Dan Gohman { 14699f6a6862be09df9f1e90b0560e52da7d15935f24Dan Gohman std::string S; 14709f6a6862be09df9f1e90b0560e52da7d15935f24Dan Gohman raw_string_ostream OS(S); 14719f6a6862be09df9f1e90b0560e52da7d15935f24Dan Gohman OS << "Unsupported expression in static initializer: "; 14729f6a6862be09df9f1e90b0560e52da7d15935f24Dan Gohman WriteAsOperand(OS, CE, /*PrintType=*/false, 14739f6a6862be09df9f1e90b0560e52da7d15935f24Dan Gohman !AP.MF ? 0 : AP.MF->getFunction()->getParent()); 14749f6a6862be09df9f1e90b0560e52da7d15935f24Dan Gohman report_fatal_error(OS.str()); 14759f6a6862be09df9f1e90b0560e52da7d15935f24Dan Gohman } 1476fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::GetElementPtr: { 147752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const TargetData &TD = *AP.TM.getTargetData(); 147852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // Generate a symbolic expression for the byte address 147952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const Constant *PtrVal = CE->getOperand(0); 148052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner SmallVector<Value*, 8> IdxVec(CE->op_begin()+1, CE->op_end()); 14818fbbb3980755d74539a0aed02bc18842ed2bd18dJay Foad int64_t Offset = TD.getIndexedOffset(PtrVal->getType(), IdxVec); 148283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 148352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *Base = LowerConstant(CE->getOperand(0), AP); 1484fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner if (Offset == 0) 148552492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return Base; 148683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1487fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // Truncate/sext the offset to the pointer size. 148852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (TD.getPointerSizeInBits() != 64) { 148952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner int SExtAmount = 64-TD.getPointerSizeInBits(); 1490fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner Offset = (Offset << SExtAmount) >> SExtAmount; 1491a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner } 149283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 149352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCBinaryExpr::CreateAdd(Base, MCConstantExpr::Create(Offset, Ctx), 149452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner Ctx); 1495fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner } 149683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 149752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Trunc: 149852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // We emit the value and depend on the assembler to truncate the generated 149952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // expression properly. This is important for differences between 150052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // blockaddress labels. Since the two labels are in the same function, it 150152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // is reasonable to treat their delta as a 32-bit value. 150252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // FALL THROUGH. 1503fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::BitCast: 150452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return LowerConstant(CE->getOperand(0), AP); 1505fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1506fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::IntToPtr: { 150752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const TargetData &TD = *AP.TM.getTargetData(); 1508fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // Handle casts to pointers by changing them into casts to the appropriate 1509fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // integer type. This promotes constant folding and simplifies this code. 1510fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner Constant *Op = CE->getOperand(0); 151152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner Op = ConstantExpr::getIntegerCast(Op, TD.getIntPtrType(CV->getContext()), 1512fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner false/*ZExt*/); 151352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return LowerConstant(Op, AP); 1514fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner } 151583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1516fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::PtrToInt: { 151752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const TargetData &TD = *AP.TM.getTargetData(); 1518fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // Support only foldable casts to/from pointers that can be eliminated by 1519fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // changing the pointer to the appropriately sized integer type. 1520fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner Constant *Op = CE->getOperand(0); 1521db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty = CE->getType(); 152252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner 152352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *OpExpr = LowerConstant(Op, AP); 1524fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1525fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // We can emit the pointer value into this slot if the slot is an 152652492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // integer slot equal to the size of the pointer. 152752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (TD.getTypeAllocSize(Ty) == TD.getTypeAllocSize(Op->getType())) 152852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return OpExpr; 152952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner 153052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // Otherwise the pointer is smaller than the resultant integer, mask off 153152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // the high bits so we are sure to get a proper truncation if the input is 153252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // a constant expr. 153352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner unsigned InBits = TD.getTypeAllocSizeInBits(Op->getType()); 153452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *MaskExpr = MCConstantExpr::Create(~0ULL >> (64-InBits), Ctx); 153552492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx); 1536fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner } 153783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 15385938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman // The MC library also has a right-shift operator, but it isn't consistently 15395938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman // signed or unsigned between different targets. 1540fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::Add: 1541fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::Sub: 15425938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::Mul: 15435938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::SDiv: 15445938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::SRem: 15455938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::Shl: 1546fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::And: 1547fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::Or: 154852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Xor: { 154952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *LHS = LowerConstant(CE->getOperand(0), AP); 155052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *RHS = LowerConstant(CE->getOperand(1), AP); 1551fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner switch (CE->getOpcode()) { 155252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner default: llvm_unreachable("Unknown binary operator constant cast expr"); 155352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Add: return MCBinaryExpr::CreateAdd(LHS, RHS, Ctx); 155452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Sub: return MCBinaryExpr::CreateSub(LHS, RHS, Ctx); 15555938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::Mul: return MCBinaryExpr::CreateMul(LHS, RHS, Ctx); 15565938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::SDiv: return MCBinaryExpr::CreateDiv(LHS, RHS, Ctx); 15575938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::SRem: return MCBinaryExpr::CreateMod(LHS, RHS, Ctx); 15585938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::Shl: return MCBinaryExpr::CreateShl(LHS, RHS, Ctx); 155952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::And: return MCBinaryExpr::CreateAnd(LHS, RHS, Ctx); 156052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Or: return MCBinaryExpr::CreateOr (LHS, RHS, Ctx); 156152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Xor: return MCBinaryExpr::CreateXor(LHS, RHS, Ctx); 1562a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner } 156352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner } 1564a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner } 1565a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner} 15661b7e2356ace23af872cc7d66cf45c56b10e77c4dChris Lattner 156744e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattnerstatic void EmitGlobalConstantImpl(const Constant *C, unsigned AddrSpace, 156844e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner AsmPrinter &AP); 156944e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner 1570d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene/// isRepeatedByteSequence - Determine whether the given value is 1571d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene/// composed of a repeated sequence of identical bytes and return the 1572d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene/// byte value. If it is not a repeated sequence, return -1. 15739e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattnerstatic int isRepeatedByteSequence(const ConstantDataSequential *V) { 15749e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner StringRef Data = V->getRawDataValues(); 15759e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner assert(!Data.empty() && "Empty aggregates should be CAZ node"); 15769e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner char C = Data[0]; 15779e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner for (unsigned i = 1, e = Data.size(); i != e; ++i) 15789e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner if (Data[i] != C) return -1; 1579beb05952ce27b4039c9d8bea929f154edeb19ca0Chandler Carruth return static_cast<uint8_t>(C); // Ensure 255 is not returned as -1. 15809e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner} 15819e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner 15829e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner 15839e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner/// isRepeatedByteSequence - Determine whether the given value is 15849e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner/// composed of a repeated sequence of identical bytes and return the 15859e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner/// byte value. If it is not a repeated sequence, return -1. 1586d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greenestatic int isRepeatedByteSequence(const Value *V, TargetMachine &TM) { 1587d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene 1588d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { 1589d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene if (CI->getBitWidth() > 64) return -1; 1590d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene 1591d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene uint64_t Size = TM.getTargetData()->getTypeAllocSize(V->getType()); 1592d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene uint64_t Value = CI->getZExtValue(); 1593d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene 1594d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene // Make sure the constant is at least 8 bits long and has a power 1595d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene // of 2 bit width. This guarantees the constant bit width is 1596d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene // always a multiple of 8 bits, avoiding issues with padding out 1597d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene // to Size and other such corner cases. 1598d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene if (CI->getBitWidth() < 8 || !isPowerOf2_64(CI->getBitWidth())) return -1; 1599d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene 1600d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene uint8_t Byte = static_cast<uint8_t>(Value); 1601d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene 1602d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene for (unsigned i = 1; i < Size; ++i) { 1603d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene Value >>= 8; 1604d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene if (static_cast<uint8_t>(Value) != Byte) return -1; 1605d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene } 1606d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene return Byte; 1607d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene } 1608d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene if (const ConstantArray *CA = dyn_cast<ConstantArray>(V)) { 1609d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene // Make sure all array elements are sequences of the same repeated 1610d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene // byte. 16119e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner assert(CA->getNumOperands() != 0 && "Should be a CAZ"); 1612d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene int Byte = isRepeatedByteSequence(CA->getOperand(0), TM); 1613d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene if (Byte == -1) return -1; 1614d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene 1615d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { 1616d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene int ThisByte = isRepeatedByteSequence(CA->getOperand(i), TM); 1617d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene if (ThisByte == -1) return -1; 1618d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene if (Byte != ThisByte) return -1; 1619d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene } 1620d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene return Byte; 1621d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene } 16229e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner 16239e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(V)) 16249e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner return isRepeatedByteSequence(CDS); 1625d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene 1626d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene return -1; 1627d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene} 1628d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene 16299e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattnerstatic void EmitGlobalConstantDataSequential(const ConstantDataSequential *CDS, 16309e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner unsigned AddrSpace,AsmPrinter &AP){ 16319e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner 16329e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner // See if we can aggregate this into a .fill, if so, emit it as such. 16339e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner int Value = isRepeatedByteSequence(CDS, AP.TM); 16349e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner if (Value != -1) { 16359e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CDS->getType()); 1636c63352f6336ab67cdba6d4702dc2bed5fdca1091Chris Lattner // Don't emit a 1-byte object as a .fill. 1637c63352f6336ab67cdba6d4702dc2bed5fdca1091Chris Lattner if (Bytes > 1) 1638c63352f6336ab67cdba6d4702dc2bed5fdca1091Chris Lattner return AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace); 16399e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner } 16409e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner 16419e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner // If this can be emitted with .ascii/.asciz, emit it as such. 16429e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner if (CDS->isString()) 16439e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner return AP.OutStreamer.EmitBytes(CDS->getAsString(), AddrSpace); 16449e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner 16459e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner // Otherwise, emit the values in successive locations. 16469e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner unsigned ElementByteSize = CDS->getElementByteSize(); 16479e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner if (isa<IntegerType>(CDS->getElementType())) { 16480f193b8a6846dab25323788638e760ae03b7cd87Chris Lattner for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) { 1649b66fb5acbe4bfde5264fdbbfe7f9f478ed94c68dChris Lattner if (AP.isVerbose()) 1650b66fb5acbe4bfde5264fdbbfe7f9f478ed94c68dChris Lattner AP.OutStreamer.GetCommentOS() << format("0x%" PRIx64 "\n", 1651b66fb5acbe4bfde5264fdbbfe7f9f478ed94c68dChris Lattner CDS->getElementAsInteger(i)); 16529e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner AP.OutStreamer.EmitIntValue(CDS->getElementAsInteger(i), 16539e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner ElementByteSize, AddrSpace); 16549e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner } 16556e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner } else if (ElementByteSize == 4) { 16566e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner // FP Constants are printed as integer constants to avoid losing 16576e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner // precision. 16586e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner assert(CDS->getElementType()->isFloatTy()); 16590f193b8a6846dab25323788638e760ae03b7cd87Chris Lattner for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) { 16609e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner union { 16619e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner float F; 16629e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner uint32_t I; 16639e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner }; 16649e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner 16659e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner F = CDS->getElementAsFloat(i); 16669e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner if (AP.isVerbose()) 16679e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner AP.OutStreamer.GetCommentOS() << "float " << F << '\n'; 16689e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner AP.OutStreamer.EmitIntValue(I, 4, AddrSpace); 16699e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner } 16706e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner } else { 16716e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner assert(CDS->getElementType()->isDoubleTy()); 16726e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) { 16736e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner union { 16746e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner double F; 16756e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner uint64_t I; 16766e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner }; 16776e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner 16786e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner F = CDS->getElementAsDouble(i); 16796e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner if (AP.isVerbose()) 16806e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner AP.OutStreamer.GetCommentOS() << "double " << F << '\n'; 16816e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner AP.OutStreamer.EmitIntValue(I, 8, AddrSpace); 16826e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner } 16839e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner } 16849e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner 16856e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner const TargetData &TD = *AP.TM.getTargetData(); 16866e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner unsigned Size = TD.getTypeAllocSize(CDS->getType()); 16876e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner unsigned EmittedSize = TD.getTypeAllocSize(CDS->getType()->getElementType()) * 16886e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner CDS->getNumElements(); 16896e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner if (unsigned Padding = Size - EmittedSize) 16906e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner AP.OutStreamer.EmitZeros(Padding, AddrSpace); 16916e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner 16929e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner} 16939e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner 169491093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattnerstatic void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace, 169591093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner AsmPrinter &AP) { 169618c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner // See if we can aggregate some values. Make sure it can be 169718c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner // represented as a series of bytes of the constant value. 169818c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner int Value = isRepeatedByteSequence(CA, AP.TM); 1699d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene 170018c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner if (Value != -1) { 170118c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CA->getType()); 170218c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace); 170318c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner } 170418c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner else { 170518c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) 170618c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP); 170700d448a341175556ebd86af68219f5b90b7145a3Dan Gohman } 170800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 170900d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 171091093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattnerstatic void EmitGlobalConstantVector(const ConstantVector *CV, 171191093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner unsigned AddrSpace, AsmPrinter &AP) { 1712bcb83e5b6c8e074e73986cb641801ecbedd6e4edChris Lattner for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) 171344e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner EmitGlobalConstantImpl(CV->getOperand(i), AddrSpace, AP); 17145b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky 17155b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky const TargetData &TD = *AP.TM.getTargetData(); 17165b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky unsigned Size = TD.getTypeAllocSize(CV->getType()); 17175b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky unsigned EmittedSize = TD.getTypeAllocSize(CV->getType()->getElementType()) * 17185b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky CV->getType()->getNumElements(); 17195b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky if (unsigned Padding = Size - EmittedSize) 17205b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky AP.OutStreamer.EmitZeros(Padding, AddrSpace); 172100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 172200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 172391093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattnerstatic void EmitGlobalConstantStruct(const ConstantStruct *CS, 172491093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner unsigned AddrSpace, AsmPrinter &AP) { 172500d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // Print the fields in successive locations. Pad to align if needed! 172691093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner const TargetData *TD = AP.TM.getTargetData(); 172791093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner unsigned Size = TD->getTypeAllocSize(CS->getType()); 17282dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner const StructLayout *Layout = TD->getStructLayout(CS->getType()); 172991093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner uint64_t SizeSoFar = 0; 173091093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) { 1731bcb83e5b6c8e074e73986cb641801ecbedd6e4edChris Lattner const Constant *Field = CS->getOperand(i); 173200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 173300d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // Check if padding is needed and insert one or more 0s. 1734bcb83e5b6c8e074e73986cb641801ecbedd6e4edChris Lattner uint64_t FieldSize = TD->getTypeAllocSize(Field->getType()); 17352dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner uint64_t PadSize = ((i == e-1 ? Size : Layout->getElementOffset(i+1)) 17362dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner - Layout->getElementOffset(i)) - FieldSize; 17372dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner SizeSoFar += FieldSize + PadSize; 173800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 173900d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // Now print the actual field value. 174044e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner EmitGlobalConstantImpl(Field, AddrSpace, AP); 174100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 174200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // Insert padding - this may include padding to increase the size of the 174300d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // current field up to the ABI size (if the struct is not packed) as well 174400d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // as padding to ensure that the next field starts at the right offset. 17452dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitZeros(PadSize, AddrSpace); 174600d448a341175556ebd86af68219f5b90b7145a3Dan Gohman } 17472dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner assert(SizeSoFar == Layout->getSizeInBytes() && 174800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman "Layout of constant struct may be incorrect!"); 174900d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 175000d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 17512dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattnerstatic void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace, 17522dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AsmPrinter &AP) { 1753e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman if (CFP->getType()->isHalfTy()) { 17543f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (AP.isVerbose()) { 1755e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman SmallString<10> Str; 1756e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman CFP->getValueAPF().toString(Str); 1757e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman AP.OutStreamer.GetCommentOS() << "half " << Str << '\n'; 175809ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner } 17592dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); 1760e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman AP.OutStreamer.EmitIntValue(Val, 2, AddrSpace); 176100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman return; 1762cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner } 176383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1764cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner if (CFP->getType()->isFloatTy()) { 17653f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (AP.isVerbose()) { 17660fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner float Val = CFP->getValueAPF().convertToFloat(); 17670fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner AP.OutStreamer.GetCommentOS() << "float " << Val << '\n'; 1768a12e9d751b64767a5c41a718da2a91122d5874c4Dan Gohman } 17692dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); 17702dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(Val, 4, AddrSpace); 177100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman return; 1772cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner } 177383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 1774e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman // FP Constants are printed as integer constants to avoid losing 1775e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman // precision. 1776e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman if (CFP->getType()->isDoubleTy()) { 1777e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman if (AP.isVerbose()) { 1778e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman double Val = CFP->getValueAPF().convertToDouble(); 1779e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman AP.OutStreamer.GetCommentOS() << "double " << Val << '\n'; 1780e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman } 1781e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman 1782e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); 1783e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace); 1784e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman return; 1785e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman } 1786e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman 1787cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner if (CFP->getType()->isX86_FP80Ty()) { 178800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // all long double variants are printed as hex 1789343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // API needed to prevent premature destruction 179009ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner APInt API = CFP->getValueAPF().bitcastToAPInt(); 179109ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner const uint64_t *p = API.getRawData(); 17923f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (AP.isVerbose()) { 179372b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner // Convert to double so we can print the approximate val as a comment. 179472b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner APFloat DoubleVal = CFP->getValueAPF(); 179572b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner bool ignored; 179672b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, 179772b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner &ignored); 17980fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner AP.OutStreamer.GetCommentOS() << "x86_fp80 ~= " 17990fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner << DoubleVal.convertToDouble() << '\n'; 180072b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner } 180183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 18022dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner if (AP.TM.getTargetData()->isBigEndian()) { 18032dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace); 18042dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); 180572b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner } else { 18062dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); 18072dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace); 180800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman } 180983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 18109ceff94447235a2e369d9adfdf57368f57dd3f18Chris Lattner // Emit the tail padding for the long double. 18112dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner const TargetData &TD = *AP.TM.getTargetData(); 18122dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitZeros(TD.getTypeAllocSize(CFP->getType()) - 18132dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner TD.getTypeStoreSize(CFP->getType()), AddrSpace); 181400d448a341175556ebd86af68219f5b90b7145a3Dan Gohman return; 1815cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner } 181683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 181709ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner assert(CFP->getType()->isPPC_FP128Ty() && 181809ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner "Floating point constant type not handled"); 1819343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // All long double variants are printed as hex 1820343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // API needed to prevent premature destruction. 182109ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner APInt API = CFP->getValueAPF().bitcastToAPInt(); 182209ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner const uint64_t *p = API.getRawData(); 18232dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner if (AP.TM.getTargetData()->isBigEndian()) { 18242dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); 18252dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace); 18269ceff94447235a2e369d9adfdf57368f57dd3f18Chris Lattner } else { 18272dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace); 18282dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); 182909ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner } 183000d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 183100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 18322dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattnerstatic void EmitGlobalConstantLargeInt(const ConstantInt *CI, 18332dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner unsigned AddrSpace, AsmPrinter &AP) { 18342dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner const TargetData *TD = AP.TM.getTargetData(); 183500d448a341175556ebd86af68219f5b90b7145a3Dan Gohman unsigned BitWidth = CI->getBitWidth(); 183638c2b0a99c6a3f5cdf6ef5a46e4a6826b30acbfbChris Lattner assert((BitWidth & 63) == 0 && "only support multiples of 64-bits"); 183700d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 183800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // We don't expect assemblers to support integer data directives 183900d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // for more than 64 bits, so we emit the data in at most 64-bit 184000d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // quantities at a time. 184100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman const uint64_t *RawData = CI->getValue().getRawData(); 184200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) { 18432dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner uint64_t Val = TD->isBigEndian() ? RawData[e - i - 1] : RawData[i]; 18442dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace); 184500d448a341175556ebd86af68219f5b90b7145a3Dan Gohman } 184600d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 184700d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 184844e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattnerstatic void EmitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace, 184944e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner AsmPrinter &AP) { 185021e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling const TargetData *TD = AP.TM.getTargetData(); 185121e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling uint64_t Size = TD->getTypeAllocSize(CV->getType()); 185221e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV)) 185344e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner return AP.OutStreamer.EmitZeros(Size, AddrSpace); 18542dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner 18552dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { 18562dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner switch (Size) { 18572dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner case 1: 18582dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner case 2: 18592dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner case 4: 18602dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner case 8: 186144e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner if (AP.isVerbose()) 186241a964931a0e0943ceef28b0c691843bf8ca87b7Benjamin Kramer AP.OutStreamer.GetCommentOS() << format("0x%" PRIx64 "\n", 186341a964931a0e0943ceef28b0c691843bf8ca87b7Benjamin Kramer CI->getZExtValue()); 18643d7ff08c82be2f95902089dd59cff2a37999a991Bill Wendling AP.OutStreamer.EmitIntValue(CI->getZExtValue(), Size, AddrSpace); 18652dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner return; 18662dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner default: 186744e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner EmitGlobalConstantLargeInt(CI, AddrSpace, AP); 18682dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner return; 18692dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner } 18702dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner } 187183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 187291093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) 187344e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner return EmitGlobalConstantFP(CFP, AddrSpace, AP); 18741b7e2356ace23af872cc7d66cf45c56b10e77c4dChris Lattner 1875b0bedd6ebbbf0b9791291f37da5666dd456cf5b1Chris Lattner if (isa<ConstantPointerNull>(CV)) { 187644e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner AP.OutStreamer.EmitIntValue(0, Size, AddrSpace); 1877b0bedd6ebbbf0b9791291f37da5666dd456cf5b1Chris Lattner return; 1878b0bedd6ebbbf0b9791291f37da5666dd456cf5b1Chris Lattner } 187983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 18809e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(CV)) 18819e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner return EmitGlobalConstantDataSequential(CDS, AddrSpace, AP); 18829e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner 18839e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) 18849e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner return EmitGlobalConstantArray(CVA, AddrSpace, AP); 188583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 18869e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) 18879e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner return EmitGlobalConstantStruct(CVS, AddrSpace, AP); 18889e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner 188921e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { 189021e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling // Look through bitcasts, which might not be able to be MCExpr'ized (e.g. of 189121e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling // vectors). 18929e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner if (CE->getOpcode() == Instruction::BitCast) 18939e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner return EmitGlobalConstantImpl(CE->getOperand(0), AddrSpace, AP); 189421e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling 189521e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling if (Size > 8) { 189621e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling // If the constant expression's size is greater than 64-bits, then we have 189721e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling // to emit the value in chunks. Try to constant fold the value and emit it 189821e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling // that way. 189921e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling Constant *New = ConstantFoldConstantExpression(CE, TD); 190021e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling if (New && New != CE) 190121e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling return EmitGlobalConstantImpl(New, AddrSpace, AP); 190221e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling } 190321e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling } 19049e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner 19059e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner if (const ConstantVector *V = dyn_cast<ConstantVector>(CV)) 19069e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner return EmitGlobalConstantVector(V, AddrSpace, AP); 19079e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner 190852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it 190952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // thread the streamer with EmitValue. 191021e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling AP.OutStreamer.EmitValue(LowerConstant(CV, AP), Size, AddrSpace); 191144e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner} 191244e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner 191344e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner/// EmitGlobalConstant - Print a general LLVM constant to the .s file. 191444e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattnervoid AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) { 191544e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType()); 191644e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner if (Size) 191744e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner EmitGlobalConstantImpl(CV, AddrSpace, *this); 191844e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner else if (MAI->hasSubsectionsViaSymbols()) { 191944e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner // If the global has zero size, emit a single byte so that two labels don't 192044e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner // look like they are at the same location. 192144e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner OutStreamer.EmitIntValue(0, 1, AddrSpace); 192244e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner } 19231b7e2356ace23af872cc7d66cf45c56b10e77c4dChris Lattner} 19240264d1a4777370009176157b76d116b3195e3767Chris Lattner 1925fad86b003a839cef40ec8ce8408322f4913368caChris Lattnervoid AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 1926d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng // Target doesn't support this yet! 1927c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Target does not support EmitMachineConstantPoolValue"); 1928d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng} 1929d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng 1930dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattnervoid AsmPrinter::printOffset(int64_t Offset, raw_ostream &OS) const { 1931dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner if (Offset > 0) 1932dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner OS << '+' << Offset; 1933dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner else if (Offset < 0) 1934dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner OS << Offset; 1935dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner} 1936dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner 1937c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner//===----------------------------------------------------------------------===// 1938c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner// Symbol Lowering Routines. 1939c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner//===----------------------------------------------------------------------===// 1940c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner 1941c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner/// GetTempSymbol - Return the MCSymbol corresponding to the assembler 1942c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner/// temporary label with the specified stem and unique ID. 1943c021572511f08372ae52fe8e31d3c307cab448fdChris LattnerMCSymbol *AsmPrinter::GetTempSymbol(StringRef Name, unsigned ID) const { 1944af8df264952698cfde59d99c96d4a0da9e4f5afaChris Lattner return OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + 1945c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner Name + Twine(ID)); 1946c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner} 1947c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner 1948c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner/// GetTempSymbol - Return an assembler temporary label with the specified 1949c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner/// stem. 1950c021572511f08372ae52fe8e31d3c307cab448fdChris LattnerMCSymbol *AsmPrinter::GetTempSymbol(StringRef Name) const { 1951c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner return OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix())+ 1952c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner Name); 1953c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner} 1954c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner 19556609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner 1956951755445821b92c3dc38f32b5c36e9875fa4318Chris LattnerMCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const { 19573b9d6216a41cfd43759e787db26d797e1f0ba0a8Chris Lattner return MMI->getAddrLabelSymbol(BA->getBasicBlock()); 19588c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman} 19598c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman 19603b9d6216a41cfd43759e787db26d797e1f0ba0a8Chris LattnerMCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const { 19613b9d6216a41cfd43759e787db26d797e1f0ba0a8Chris Lattner return MMI->getAddrLabelSymbol(BB); 19628c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman} 19638c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman 19643924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner/// GetCPISymbol - Return the symbol for the specified constant pool entry. 19653924868a957d5a6d468b61741cbb7db77324d1f6Chris LattnerMCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const { 19669b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol 196798cdab53c302a2d6686fa428c0e896b1fb195311Chris Lattner (Twine(MAI->getPrivateGlobalPrefix()) + "CPI" + Twine(getFunctionNumber()) 196898cdab53c302a2d6686fa428c0e896b1fb195311Chris Lattner + "_" + Twine(CPID)); 19693924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner} 19703924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner 19713924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner/// GetJTISymbol - Return the symbol for the specified jump table entry. 197207d317711781d8c9268f7d6afcf1ba7eadf1d127Bill WendlingMCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const { 197307d317711781d8c9268f7d6afcf1ba7eadf1d127Bill Wendling return MF->getJTISymbol(JTID, OutContext, isLinkerPrivate); 19747cb384dcca3f1ccfc993182ee4b972f7fffc8ffaChris Lattner} 19757cb384dcca3f1ccfc993182ee4b972f7fffc8ffaChris Lattner 1976798d1256595dcc0f5d4423572f856d239f7de0e6Chris Lattner/// GetJTSetSymbol - Return the symbol for the specified jump table .set 1977798d1256595dcc0f5d4423572f856d239f7de0e6Chris Lattner/// FIXME: privatize to AsmPrinter. 1978798d1256595dcc0f5d4423572f856d239f7de0e6Chris LattnerMCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const { 19799b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol 198098cdab53c302a2d6686fa428c0e896b1fb195311Chris Lattner (Twine(MAI->getPrivateGlobalPrefix()) + Twine(getFunctionNumber()) + "_" + 198198cdab53c302a2d6686fa428c0e896b1fb195311Chris Lattner Twine(UID) + "_set_" + Twine(MBBID)); 1982798d1256595dcc0f5d4423572f856d239f7de0e6Chris Lattner} 1983798d1256595dcc0f5d4423572f856d239f7de0e6Chris Lattner 19847a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner/// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with 1985d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner/// global value name as its base, with the specified suffix, and where the 19867a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner/// symbol is forced to have private linkage if ForcePrivate is true. 19877a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris LattnerMCSymbol *AsmPrinter::GetSymbolWithGlobalValueBase(const GlobalValue *GV, 19887a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner StringRef Suffix, 19897a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner bool ForcePrivate) const { 1990d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner SmallString<60> NameStr; 19917a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner Mang->getNameWithPrefix(NameStr, GV, ForcePrivate); 1992d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner NameStr.append(Suffix.begin(), Suffix.end()); 19939b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(NameStr.str()); 1994d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner} 1995d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner 19966b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner/// GetExternalSymbolSymbol - Return the MCSymbol for the specified 19976b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner/// ExternalSymbol. 19986b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris LattnerMCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) const { 19996b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner SmallString<60> NameStr; 20006b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner Mang->getNameWithPrefix(NameStr, Sym); 20016b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner return OutContext.GetOrCreateSymbol(NameStr.str()); 200283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach} 20036b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner 20047cb384dcca3f1ccfc993182ee4b972f7fffc8ffaChris Lattner 2005523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 2006523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner/// PrintParentLoopComment - Print comments about parent loops of this one. 2007523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattnerstatic void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop, 2008523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner unsigned FunctionNumber) { 2009523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner if (Loop == 0) return; 2010523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner PrintParentLoopComment(OS, Loop->getParentLoop(), FunctionNumber); 2011523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS.indent(Loop->getLoopDepth()*2) 2012523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << "Parent Loop BB" << FunctionNumber << "_" 2013523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << Loop->getHeader()->getNumber() 2014523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << " Depth=" << Loop->getLoopDepth() << '\n'; 2015523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner} 2016523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 2017523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 2018523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner/// PrintChildLoopComment - Print comments about child loops within 2019523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner/// the loop for this basic block, with nesting. 2020523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattnerstatic void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop, 2021523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner unsigned FunctionNumber) { 2022523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // Add child loop information 2023523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner for (MachineLoop::iterator CL = Loop->begin(), E = Loop->end();CL != E; ++CL){ 2024523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS.indent((*CL)->getLoopDepth()*2) 2025523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << "Child Loop BB" << FunctionNumber << "_" 2026523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << (*CL)->getHeader()->getNumber() << " Depth " << (*CL)->getLoopDepth() 2027523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << '\n'; 2028523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner PrintChildLoopComment(OS, *CL, FunctionNumber); 2029523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner } 2030523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner} 2031523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 2032dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner/// EmitBasicBlockLoopComments - Pretty-print comments for basic blocks. 2033dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattnerstatic void EmitBasicBlockLoopComments(const MachineBasicBlock &MBB, 2034dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner const MachineLoopInfo *LI, 2035dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner const AsmPrinter &AP) { 2036523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // Add loop depth information 2037523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner const MachineLoop *Loop = LI->getLoopFor(&MBB); 2038523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner if (Loop == 0) return; 203983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 2040523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner MachineBasicBlock *Header = Loop->getHeader(); 2041523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner assert(Header && "No header for loop"); 204283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 2043523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // If this block is not a loop header, just print out what is the loop header 2044523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // and return. 2045523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner if (Header != &MBB) { 2046523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner AP.OutStreamer.AddComment(" in Loop: Header=BB" + 2047523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner Twine(AP.getFunctionNumber())+"_" + 2048523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner Twine(Loop->getHeader()->getNumber())+ 2049523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner " Depth="+Twine(Loop->getLoopDepth())); 2050523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner return; 2051523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner } 205283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 2053523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // Otherwise, it is a loop header. Print out information about child and 2054523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // parent loops. 2055523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner raw_ostream &OS = AP.OutStreamer.GetCommentOS(); 205683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 205783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber()); 205883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 2059523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS << "=>"; 2060523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS.indent(Loop->getLoopDepth()*2-2); 206183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 2062523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS << "This "; 2063523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner if (Loop->empty()) 2064523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS << "Inner "; 2065523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n'; 206683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 2067523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner PrintChildLoopComment(OS, Loop, AP.getFunctionNumber()); 2068523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner} 2069523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 2070523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 207170a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner/// EmitBasicBlockStart - This method prints the label for the specified 207270a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner/// MachineBasicBlock, an alignment (if present) and a comment describing 207370a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner/// it if appropriate. 2074662316c997e4eb8c3fdec6999b3e9da03620847aChris Lattnervoid AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const { 2075b1cac33856687715bf8db3860ff55ad2f6ca94b5Dan Gohman // Emit an alignment directive for this block, if needed. 207670a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner if (unsigned Align = MBB->getAlignment()) 20778c741b8064f1116d8d8dc435b60b75abdf5c4d57Jakob Stoklund Olesen EmitAlignment(Align); 2078fb8075d03f5c87bd57dcc9c5f2304f6b13c55aadEvan Cheng 2079999aee24c7b7511575146b9950bb85830fab0378Chris Lattner // If the block has its address taken, emit any labels that were used to 2080999aee24c7b7511575146b9950bb85830fab0378Chris Lattner // reference the block. It is possible that there is more than one label 2081999aee24c7b7511575146b9950bb85830fab0378Chris Lattner // here, because multiple LLVM BB's may have been RAUW'd to this block after 2082999aee24c7b7511575146b9950bb85830fab0378Chris Lattner // the references were generated. 20838c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman if (MBB->hasAddressTaken()) { 2084213168ba469703a186d060281e587d828878aa75Chris Lattner const BasicBlock *BB = MBB->getBasicBlock(); 20853f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose()) 2086999aee24c7b7511575146b9950bb85830fab0378Chris Lattner OutStreamer.AddComment("Block address taken"); 208783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 2088999aee24c7b7511575146b9950bb85830fab0378Chris Lattner std::vector<MCSymbol*> Syms = MMI->getAddrLabelSymbolToEmit(BB); 2089999aee24c7b7511575146b9950bb85830fab0378Chris Lattner 2090999aee24c7b7511575146b9950bb85830fab0378Chris Lattner for (unsigned i = 0, e = Syms.size(); i != e; ++i) 2091999aee24c7b7511575146b9950bb85830fab0378Chris Lattner OutStreamer.EmitLabel(Syms[i]); 20928c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman } 20938c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman 2094c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen // Print some verbose block comments. 2095c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen if (isVerbose()) { 2096c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen if (const BasicBlock *BB = MBB->getBasicBlock()) 2097c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen if (BB->hasName()) 2098c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen OutStreamer.AddComment("%" + BB->getName()); 2099c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen EmitBasicBlockLoopComments(*MBB, LI, *this); 2100c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen } 2101c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen 2102b1cac33856687715bf8db3860ff55ad2f6ca94b5Dan Gohman // Print the main label for the block. 21030a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (MBB->pred_empty() || isBlockOnlyReachableByFallthrough(MBB)) { 21043f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose() && OutStreamer.hasRawTextSupport()) { 210558bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner // NOTE: Want this comment at start of line, don't emit with AddComment. 210658bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner OutStreamer.EmitRawText(Twine(MAI->getCommentString()) + " BB#" + 210758bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner Twine(MBB->getNumber()) + ":"); 21080fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner } 2109e3cc3f3c84abfdf8eb3bd19dfa806ceea49f15d6Dan Gohman } else { 21101b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner OutStreamer.EmitLabel(MBB->getSymbol()); 2111e3cc3f3c84abfdf8eb3bd19dfa806ceea49f15d6Dan Gohman } 211237efe6764568a3829fee26aba532283131d1a104Nate Begeman} 211352a51e38dc312aa262b0d771419afe1785f3cb22Nate Begeman 21145129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastingsvoid AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility, 21155129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastings bool IsDefinition) const { 2116152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner MCSymbolAttr Attr = MCSA_Invalid; 211783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 2118152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner switch (Visibility) { 2119152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner default: break; 2120152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner case GlobalValue::HiddenVisibility: 21215129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastings if (IsDefinition) 21225129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastings Attr = MAI->getHiddenVisibilityAttr(); 21235129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastings else 21245129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastings Attr = MAI->getHiddenDeclarationVisibilityAttr(); 2125152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner break; 2126152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner case GlobalValue::ProtectedVisibility: 2127152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner Attr = MAI->getProtectedVisibilityAttr(); 2128152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner break; 212953d4d78d9a2c26a67ac8f6e81cc149702103fc2cChris Lattner } 2130152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner 2131152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner if (Attr != MCSA_Invalid) 2132152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner OutStreamer.EmitSymbolAttribute(Sym, Attr); 213353d4d78d9a2c26a67ac8f6e81cc149702103fc2cChris Lattner} 213453d4d78d9a2c26a67ac8f6e81cc149702103fc2cChris Lattner 21350a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner/// isBlockOnlyReachableByFallthough - Return true if the basic block has 21360a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner/// exactly one predecessor and the control transfer mechanism between 21370a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner/// the predecessor and this block is a fall-through. 2138e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattnerbool AsmPrinter:: 2139e00b59f954c7e27d9d34abf90bfac969fb12f19aChris LattnerisBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { 21400a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // If this is a landing pad, it isn't a fall through. If it has no preds, 21410a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // then nothing falls through to it. 21420a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (MBB->isLandingPad() || MBB->pred_empty()) 21430a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return false; 214483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 21450a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // If there isn't exactly one predecessor, it can't be a fall through. 21460a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; 21470a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner ++PI2; 21480a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (PI2 != MBB->pred_end()) 21490a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return false; 215083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 21510a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // The predecessor has to be immediately before this block. 21520fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman MachineBasicBlock *Pred = *PI; 215383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 21540a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (!Pred->isLayoutSuccessor(MBB)) 21550a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return false; 215683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 21570a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // If the block is completely empty, then it definitely does fall through. 21580a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (Pred->empty()) 21590a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return true; 216083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 21610fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman // Check the terminators in the previous blocks 21620fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman for (MachineBasicBlock::iterator II = Pred->getFirstTerminator(), 21630fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman IE = Pred->end(); II != IE; ++II) { 21640fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman MachineInstr &MI = *II; 21650fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman 21660fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman // If it is not a simple branch, we are in a table somewhere. 21675a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (!MI.isBranch() || MI.isIndirectBranch()) 21680fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman return false; 21690fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman 21700fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman // If we are the operands of one of the branches, this is not 21710fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman // a fall through. 21720fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman for (MachineInstr::mop_iterator OI = MI.operands_begin(), 21730fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman OE = MI.operands_end(); OI != OE; ++OI) { 21740fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman const MachineOperand& OP = *OI; 2175aeb6da46ce7c55440215fca1fb11122ecddeec44Rafael Espindola if (OP.isJTI()) 2176aeb6da46ce7c55440215fca1fb11122ecddeec44Rafael Espindola return false; 21770fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman if (OP.isMBB() && OP.getMBB() == MBB) 21780fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman return false; 21790fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman } 21800fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman } 21810fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman 21820fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman return true; 21830a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner} 21840a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 21850a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 21860a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 21875eca075b74d62c621b160aa216b4cd50829a2cc7Gordon HenriksenGCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) { 21885eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen if (!S->usesMetadata()) 2189c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen return 0; 2190e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner 2191e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner gcp_map_type &GCMap = getGCMap(GCMetadataPrinters); 2192e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner gcp_map_type::iterator GCPI = GCMap.find(S); 2193e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner if (GCPI != GCMap.end()) 2194c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen return GCPI->second; 219583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 21965eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen const char *Name = S->getName().c_str(); 219783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 2198c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen for (GCMetadataPrinterRegistry::iterator 2199c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen I = GCMetadataPrinterRegistry::begin(), 2200c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen E = GCMetadataPrinterRegistry::end(); I != E; ++I) 2201c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen if (strcmp(Name, I->getName()) == 0) { 22025eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen GCMetadataPrinter *GMP = I->instantiate(); 22035eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen GMP->S = S; 2204e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner GCMap.insert(std::make_pair(S, GMP)); 22055eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen return GMP; 2206c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen } 220783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach 220875361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name)); 2209c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen} 2210