AsmPrinter.cpp revision 03c3dc7b6828d48a9f3be50896b3390a696caa64
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" 40da47e6e0d003c873da960361549e57ee4617c301Evan Cheng#include "llvm/Target/TargetRegisterInfo.h" 41fad86b003a839cef40ec8ce8408322f4913368caChris Lattner#include "llvm/ADT/SmallString.h" 4214c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner#include "llvm/ADT/Statistic.h" 4314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner#include "llvm/Support/ErrorHandling.h" 4414c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner#include "llvm/Support/Format.h" 459c4210794ee42542a20023cd0a800003797523e0Torok Edwin#include "llvm/Support/Timer.h" 46a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattnerusing namespace llvm; 47a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner 48c0561f29a8b95106c757ffa9ad186f997dabd836Chris Lattnerstatic const char *DWARFGroupName = "DWARF Emission"; 49c0561f29a8b95106c757ffa9ad186f997dabd836Chris Lattnerstatic const char *DbgTimerName = "DWARF Debug Writer"; 50c0561f29a8b95106c757ffa9ad186f997dabd836Chris Lattnerstatic const char *EHTimerName = "DWARF Exception Writer"; 519c4210794ee42542a20023cd0a800003797523e0Torok Edwin 5214c38ec2afeaf25c53a50c2c65116aca8c889401Chris LattnerSTATISTIC(EmittedInsts, "Number of machine instrs printed"); 5314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 541997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patelchar AsmPrinter::ID = 0; 5511d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner 56e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattnertypedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type; 57e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattnerstatic gcp_map_type &getGCMap(void *&P) { 58e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner if (P == 0) 59e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner P = new gcp_map_type(); 60e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner return *(gcp_map_type*)P; 61e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner} 62e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner 63e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner 64e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner/// getGVAlignmentLog2 - Return the alignment to use for the specified global 65e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner/// value in log2 form. This rounds up to the preferred alignment if possible 66e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner/// and legal. 67e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattnerstatic unsigned getGVAlignmentLog2(const GlobalValue *GV, const TargetData &TD, 68e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner unsigned InBits = 0) { 69e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner unsigned NumBits = 0; 70e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) 71e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner NumBits = TD.getPreferredAlignmentLog(GVar); 72e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner 73e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner // If InBits is specified, round it to it. 74e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner if (InBits > NumBits) 75e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner NumBits = InBits; 76e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner 77e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner // If the GV has a specified alignment, take it into account. 78e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner if (GV->getAlignment() == 0) 79e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner return NumBits; 80e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner 81e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner unsigned GVAlign = Log2_32(GV->getAlignment()); 82e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner 83e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner // If the GVAlign is larger than NumBits, or if we are required to obey 84e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner // NumBits because the GV has an assigned section, obey it. 85e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner if (GVAlign > NumBits || GV->hasSection()) 86e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner NumBits = GVAlign; 87e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner return NumBits; 88e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner} 89e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner 90e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner 91e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner 92e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner 93b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris LattnerAsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer) 94e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner : MachineFunctionPass(&ID), 959d1c1ada213c80135fbdda704175aae689daa6f9Chris Lattner TM(tm), MAI(tm.getMCAsmInfo()), 9611d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner OutContext(Streamer.getContext()), 9711d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner OutStreamer(Streamer), 98553881bddcdeb66c0ae06bf9f62ca63b9f29b2e8Devang Patel LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) { 9949cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner DD = 0; DE = 0; MMI = 0; LI = 0; 100e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner GCMetadataPrinters = 0; 10156591ab218639d8a6e4c756ca37adaf20215c3b6Chris Lattner VerboseAsm = Streamer.isVerboseAsm(); 10242bf74be1402df7409efbea089310d4c276fde37Evan Cheng} 103ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 104c317a60c2714a5b90700a11ba646285cb754a5d3Gordon HenriksenAsmPrinter::~AsmPrinter() { 10549cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner assert(DD == 0 && DE == 0 && "Debug/EH info didn't get finalized"); 10649cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner 107e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner if (GCMetadataPrinters != 0) { 108e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner gcp_map_type &GCMap = getGCMap(GCMetadataPrinters); 109e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner 110e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner for (gcp_map_type::iterator I = GCMap.begin(), E = GCMap.end(); I != E; ++I) 111e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner delete I->second; 112e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner delete &GCMap; 113e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner GCMetadataPrinters = 0; 114e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner } 1152b2954f00ba02ca1a902f47080cd9f06aebc0378Chris Lattner 1162b2954f00ba02ca1a902f47080cd9f06aebc0378Chris Lattner delete &OutStreamer; 117c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen} 118ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 119b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner/// getFunctionNumber - Return a unique ID for the current function. 120b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner/// 121b84822fb7b64977c16e97b870891da1d6c9736feChris Lattnerunsigned AsmPrinter::getFunctionNumber() const { 122b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner return MF->getFunctionNumber(); 123b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner} 124b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner 1250d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohmanconst TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const { 126f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner return TM.getTargetLowering()->getObjFileLowering(); 127f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner} 128f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner 129d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattner 130d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattner/// getTargetData - Return information about data layout. 131d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattnerconst TargetData &AsmPrinter::getTargetData() const { 132d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattner return *TM.getTargetData(); 133d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattner} 134d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattner 135dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattner/// getCurrentSection() - Return the current section we are emitting to. 136dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattnerconst MCSection *AsmPrinter::getCurrentSection() const { 137dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattner return OutStreamer.getCurrentSection(); 138b5a32e2e8ce2f3de3a340c5a2dfcd3a159968466Anton Korobeynikov} 1394632d7a57008564c4b0f8246e85bd813a200d2c6Chris Lattner 140dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattner 141d38fee8ddc6597555904b82b6471a446cc5fe183Chris Lattner 142ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksenvoid AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const { 143845012e6d31799c7fbd1193fa1af8ee2d12e9231Dan Gohman AU.setPreservesAll(); 144ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksen MachineFunctionPass::getAnalysisUsage(AU); 14511d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner AU.addRequired<MachineModuleInfo>(); 1465eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen AU.addRequired<GCModuleInfo>(); 1473f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose()) 148b71d1b2fe2c0673005283b48be2f37c750ce367bDavid Greene AU.addRequired<MachineLoopInfo>(); 149ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksen} 150ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksen 151a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattnerbool AsmPrinter::doInitialization(Module &M) { 152d32c8a561734e05ff78da4435de0e85e0eed88e1Chris Lattner MMI = getAnalysisIfAvailable<MachineModuleInfo>(); 15311d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner MMI->AnalyzeModule(M); 15411d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner 155f26e03bc7e30162197641406e37e662a15d80f7eChris Lattner // Initialize TargetLoweringObjectFile. 156f26e03bc7e30162197641406e37e662a15d80f7eChris Lattner const_cast<TargetLoweringObjectFile&>(getObjFileLowering()) 157f26e03bc7e30162197641406e37e662a15d80f7eChris Lattner .Initialize(OutContext, TM); 158f26e03bc7e30162197641406e37e662a15d80f7eChris Lattner 159b87c305fa77650ee581d4a8c65a0757f88002441Chris Lattner Mang = new Mangler(OutContext, *TM.getTargetData()); 1602c1b1597f244c836771b4f2668c0ae399d32a5e9Chris Lattner 161812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson // Allow the target to emit any magic that it wants at the start of the file. 162812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson EmitStartOfAsmFile(M); 163952b839ce9bc0c6d605d8b202c9cd76f7f05a77dRafael Espindola 164a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner // Very minimal debug info. It is ignored if we emit actual debug info. If we 165a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner // don't, this at least helps the user find where a global came from. 16633adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->hasSingleParameterDotFile()) { 167a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner // .file "foo.c" 168a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner OutStreamer.EmitFileDirective(M.getModuleIdentifier()); 169952b839ce9bc0c6d605d8b202c9cd76f7f05a77dRafael Espindola } 170952b839ce9bc0c6d605d8b202c9cd76f7f05a77dRafael Espindola 171812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); 172812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson assert(MI && "AsmPrinter didn't require GCModuleInfo?"); 1735eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I) 1745eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I)) 1757d73c7f0d618dd6661cd55834c58aa62f22b28feChris Lattner MP->beginAssembly(*this); 17691bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner 17791bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner // Emit module-level inline asm if it exists. 17847b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner if (!M.getModuleInlineAsm().empty()) { 17947b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner OutStreamer.AddComment("Start of file scope inline assembly"); 18047b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner OutStreamer.AddBlankLine(); 181885d94143d0fc02fd5c4ddf1d2a2ee74c7934bffChris Lattner EmitInlineAsm(M.getModuleInlineAsm(), 0/*no loc cookie*/); 18247b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner OutStreamer.AddComment("End of file scope inline assembly"); 18347b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner OutStreamer.AddBlankLine(); 18447b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner } 1852c1b1597f244c836771b4f2668c0ae399d32a5e9Chris Lattner 18649cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner if (MAI->doesSupportDebugInformation()) 18749cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner DD = new DwarfDebug(this, &M); 18849cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner 18949cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner if (MAI->doesSupportExceptionHandling()) 19049cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner DE = new DwarfException(this); 19114a55d952cf238fff42da53a75f39cf06dab184bDevang Patel 192a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner return false; 193a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner} 194a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner 195be9dfcef82c58063708e039bea3cf972ba41581bChris Lattnervoid AsmPrinter::EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const { 196a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner switch ((GlobalValue::LinkageTypes)Linkage) { 197a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::CommonLinkage: 198a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::LinkOnceAnyLinkage: 199a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::LinkOnceODRLinkage: 200a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::WeakAnyLinkage: 201a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::WeakODRLinkage: 202a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::LinkerPrivateLinkage: 203a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner if (MAI->getWeakDefDirective() != 0) { 204a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .globl _foo 205a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); 206a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .weak_definition _foo 207a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefinition); 2085b1b3b73f2e4fc66eb8a9273673d128b139caf03Duncan Sands } else if (MAI->getLinkOnceDirective() != 0) { 209a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .globl _foo 210a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); 2115b1b3b73f2e4fc66eb8a9273673d128b139caf03Duncan Sands //NOTE: linkonce is handled by the section the symbol was assigned to. 212a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner } else { 213a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .weak _foo 214a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak); 215a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner } 216a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner break; 217a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::DLLExportLinkage: 218a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::AppendingLinkage: 219a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // FIXME: appending linkage variables should go into a section of 220a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // their name or something. For now, just emit them as external. 221a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::ExternalLinkage: 222a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // If external or appending, declare as a global symbol. 223a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .globl _foo 224a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); 225a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner break; 226a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::PrivateLinkage: 227a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::InternalLinkage: 228a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner break; 229a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner default: 230a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner llvm_unreachable("Unknown linkage type!"); 231a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner } 232a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner} 233a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner 234a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner 23548d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner/// EmitGlobalVariable - Emit the specified global variable to the .s file. 23648d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattnervoid AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { 23748d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner if (!GV->hasInitializer()) // External globals require no code. 23848d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner return; 23948d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner 24048d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner // Check to see if this is a special global used by LLVM, if so, emit it. 24148d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner if (EmitSpecialLLVMGlobal(GV)) 24248d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner return; 24374bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 24404386ca726d726c214be15a0c3e9dbdc82b1e691Eric Christopher if (isVerbose()) { 24504386ca726d726c214be15a0c3e9dbdc82b1e691Eric Christopher WriteAsOperand(OutStreamer.GetCommentOS(), GV, 24604386ca726d726c214be15a0c3e9dbdc82b1e691Eric Christopher /*PrintType=*/false, GV->getParent()); 24704386ca726d726c214be15a0c3e9dbdc82b1e691Eric Christopher OutStreamer.GetCommentOS() << '\n'; 24804386ca726d726c214be15a0c3e9dbdc82b1e691Eric Christopher } 24904386ca726d726c214be15a0c3e9dbdc82b1e691Eric Christopher 250deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner MCSymbol *GVSym = Mang->getSymbol(GV); 251be9dfcef82c58063708e039bea3cf972ba41581bChris Lattner EmitVisibility(GVSym, GV->getVisibility()); 25274bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 253a800f7c464ef9a376057a555129f36d1f8488c3bChris Lattner if (MAI->hasDotTypeDotSizeDirective()) 254a800f7c464ef9a376057a555129f36d1f8488c3bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject); 25574bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 25674bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM); 25774bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 25874bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner const TargetData *TD = TM.getTargetData(); 259e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner uint64_t Size = TD->getTypeAllocSize(GV->getType()->getElementType()); 260567dd1f5d0ae454e7c51ef070bbb8d31a43ed4bcChris Lattner 261567dd1f5d0ae454e7c51ef070bbb8d31a43ed4bcChris Lattner // If the alignment is specified, we *must* obey it. Overaligning a global 262567dd1f5d0ae454e7c51ef070bbb8d31a43ed4bcChris Lattner // with a specified alignment is a prompt way to break globals emitted to 263567dd1f5d0ae454e7c51ef070bbb8d31a43ed4bcChris Lattner // sections and expected to be contiguous (e.g. ObjC metadata). 264e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner unsigned AlignLog = getGVAlignmentLog2(GV, *TD); 26574bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 2669744d611d7c7c1fb51c50c4e94901e4e9a905116Chris Lattner // Handle common and BSS local symbols (.lcomm). 2679744d611d7c7c1fb51c50c4e94901e4e9a905116Chris Lattner if (GVKind.isCommon() || GVKind.isBSSLocal()) { 26874bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. 26974bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 2703f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose()) { 2710fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner WriteAsOperand(OutStreamer.GetCommentOS(), GV, 2720fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner /*PrintType=*/false, GV->getParent()); 2730fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner OutStreamer.GetCommentOS() << '\n'; 27474bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner } 275814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner 276814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // Handle common symbols. 2779744d611d7c7c1fb51c50c4e94901e4e9a905116Chris Lattner if (GVKind.isCommon()) { 2789744d611d7c7c1fb51c50c4e94901e4e9a905116Chris Lattner // .comm _foo, 42, 4 2794ed5438f4882c9fe779b1a8ff546877889b222dfChris Lattner OutStreamer.EmitCommonSymbol(GVSym, Size, 1 << AlignLog); 280814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner return; 281814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner } 282814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner 283814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // Handle local BSS symbols. 284814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner if (MAI->hasMachoZeroFillDirective()) { 285814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner const MCSection *TheSection = 286814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM); 287814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // .zerofill __DATA, __bss, _foo, 400, 5 288814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog); 289814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner return; 290814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner } 291814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner 2929eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner if (MAI->hasLCOMMDirective()) { 293814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // .lcomm _foo, 42 2949eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner OutStreamer.EmitLocalCommonSymbol(GVSym, Size); 295814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner return; 29674bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner } 297814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner 298814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // .local _foo 299a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Local); 300814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // .comm _foo, 42, 4 301814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner OutStreamer.EmitCommonSymbol(GVSym, Size, 1 << AlignLog); 30274bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner return; 30374bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner } 30448d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner 30574bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner const MCSection *TheSection = 30674bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM); 30774bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 30874bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner // Handle the zerofill directive on darwin, which is a special form of BSS 30974bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner // emission. 31074bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) { 3114c4d0c0cc582a61d9e7f58594c71540aaa56b280Chris Lattner if (Size == 0) Size = 1; // zerofill of 0 bytes is undefined. 3124c4d0c0cc582a61d9e7f58594c71540aaa56b280Chris Lattner 31374bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner // .globl _foo 314a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); 31574bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner // .zerofill __DATA, __common, _foo, 400, 5 31674bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog); 31774bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner return; 31874bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner } 319c1a887d76d95100e7e05aa76e077710bc4e0b1cfEric Christopher 32002b46bc9426925b90137d264216a54aa413335fdEric Christopher // Handle thread local data for mach-o which requires us to output an 32102b46bc9426925b90137d264216a54aa413335fdEric Christopher // additional structure of data and mangle the original symbol so that we 32202b46bc9426925b90137d264216a54aa413335fdEric Christopher // can reference it later. 32302b46bc9426925b90137d264216a54aa413335fdEric Christopher if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective()) { 3248116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // Emit the .tbss symbol 3258116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher MCSymbol *MangSym = 3268116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutContext.GetOrCreateSymbol(GVSym->getName() + Twine("$tlv$init")); 32702b46bc9426925b90137d264216a54aa413335fdEric Christopher 32802b46bc9426925b90137d264216a54aa413335fdEric Christopher if (GVKind.isThreadBSS()) 32902b46bc9426925b90137d264216a54aa413335fdEric Christopher OutStreamer.EmitTBSSSymbol(TheSection, MangSym, Size, 1 << AlignLog); 33002b46bc9426925b90137d264216a54aa413335fdEric Christopher else if (GVKind.isThreadData()) { 33102b46bc9426925b90137d264216a54aa413335fdEric Christopher OutStreamer.SwitchSection(TheSection); 33202b46bc9426925b90137d264216a54aa413335fdEric Christopher 33302b46bc9426925b90137d264216a54aa413335fdEric Christopher EmitAlignment(AlignLog, GV); 33402b46bc9426925b90137d264216a54aa413335fdEric Christopher OutStreamer.EmitLabel(MangSym); 33502b46bc9426925b90137d264216a54aa413335fdEric Christopher 33602b46bc9426925b90137d264216a54aa413335fdEric Christopher EmitGlobalConstant(GV->getInitializer()); 33702b46bc9426925b90137d264216a54aa413335fdEric Christopher } 33802b46bc9426925b90137d264216a54aa413335fdEric Christopher 3398116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutStreamer.AddBlankLine(); 3408116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher 3418116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // Emit the variable struct for the runtime. 3428116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher const MCSection *TLVSect 3438116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher = getObjFileLowering().getTLSExtraDataSection(); 3448116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher 3458116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutStreamer.SwitchSection(TLVSect); 3468116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // Emit the linkage here. 3478116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher EmitLinkage(GV->getLinkage(), GVSym); 3488116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutStreamer.EmitLabel(GVSym); 3498116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher 3508116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // Three pointers in size: 3518116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // - __tlv_bootstrap - used to make sure support exists 3528116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // - spare pointer, used when mapped by the runtime 3538116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher // - pointer to mangled symbol above with initializer 3548116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher unsigned PtrSize = TD->getPointerSizeInBits()/8; 3557310064f4d14b62029805ab16a11ff443ea309d5Eric Christopher OutStreamer.EmitSymbolValue(GetExternalSymbolSymbol("_tlv_bootstrap"), 3568116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher PtrSize, 0); 3578116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutStreamer.EmitIntValue(0, PtrSize, 0); 3588116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutStreamer.EmitSymbolValue(MangSym, PtrSize, 0); 3598116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher 3608116ca5134b355b897450f9a537c9c77e1f08723Eric Christopher OutStreamer.AddBlankLine(); 361c1a887d76d95100e7e05aa76e077710bc4e0b1cfEric Christopher return; 362c1a887d76d95100e7e05aa76e077710bc4e0b1cfEric Christopher } 36374bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 36474bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner OutStreamer.SwitchSection(TheSection); 36574bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 366a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner EmitLinkage(GV->getLinkage(), GVSym); 367f74e25f60c8c63b819ff603cb4c3c18424dc87a7Chris Lattner EmitAlignment(AlignLog, GV); 368a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner 3694c8c668b57f74e2849ba198c3abfc97899e8072bChris Lattner OutStreamer.EmitLabel(GVSym); 37074bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 37174bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner EmitGlobalConstant(GV->getInitializer()); 37274bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 37374bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner if (MAI->hasDotTypeDotSizeDirective()) 3741947f242d40227d36440a2702a0a612c8077d72eChris Lattner // .size foo, 42 37599328add833807f12a4950c7de29fb2a5df04703Chris Lattner OutStreamer.EmitELFSize(GVSym, MCConstantExpr::Create(Size, OutContext)); 3760fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner 3770fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner OutStreamer.AddBlankLine(); 37848d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner} 37948d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner 380b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner/// EmitFunctionHeader - This method emits the header for the current 381b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner/// function. 382b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattnervoid AsmPrinter::EmitFunctionHeader() { 383b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner // Print out constants referenced by the function 384a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner EmitConstantPool(); 385b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 386b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner // Print the 'header' of function. 387b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner const Function *F = MF->getFunction(); 388b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 389b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM)); 390be9dfcef82c58063708e039bea3cf972ba41581bChris Lattner EmitVisibility(CurrentFnSym, F->getVisibility()); 391b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 392111a3193b5e25f8765221f2e94fba888155fe4ebChris Lattner EmitLinkage(F->getLinkage(), CurrentFnSym); 393b406a8141d704bca7a8eade3a0c46d7ec73affc8Chris Lattner EmitAlignment(MF->getAlignment(), F); 394b406a8141d704bca7a8eade3a0c46d7ec73affc8Chris Lattner 395b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner if (MAI->hasDotTypeDotSizeDirective()) 396b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction); 397b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 3983f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose()) { 3999bc20ab519d47146a9716d7cff2a892da78774a6Chris Lattner WriteAsOperand(OutStreamer.GetCommentOS(), F, 4009bc20ab519d47146a9716d7cff2a892da78774a6Chris Lattner /*PrintType=*/false, F->getParent()); 4019bc20ab519d47146a9716d7cff2a892da78774a6Chris Lattner OutStreamer.GetCommentOS() << '\n'; 402b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner } 403b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 404f451cb870efcf9e0302d25ed05f4cac6bb494e42Dan Gohman // Emit the CurrentFnSym. This is a virtual function to allow targets to 4052cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner // do their wild and crazy things as required. 4062cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner EmitFunctionEntryLabel(); 4072cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner 4089cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner // If the function had address-taken blocks that got deleted, then we have 4099cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner // references to the dangling symbols. Emit them at the start of the function 4109cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner // so that we don't get references to undefined symbols. 4119cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner std::vector<MCSymbol*> DeadBlockSyms; 4129cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner MMI->takeDeletedSymbolsForFunction(F, DeadBlockSyms); 4139cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner for (unsigned i = 0, e = DeadBlockSyms.size(); i != e; ++i) { 4149cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner OutStreamer.AddComment("Address taken block that was later removed"); 4159cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner OutStreamer.EmitLabel(DeadBlockSyms[i]); 4169cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner } 4179cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner 418b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner // Add some workaround for linkonce linkage on Cygwin\MinGW. 419b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner if (MAI->getLinkOnceDirective() != 0 && 420fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner (F->hasLinkOnceLinkage() || F->hasWeakLinkage())) { 4219bc20ab519d47146a9716d7cff2a892da78774a6Chris Lattner // FIXME: What is this? 422fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner MCSymbol *FakeStub = 423fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner OutContext.GetOrCreateSymbol(Twine("Lllvm$workaround$fake$stub$")+ 424fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner CurrentFnSym->getName()); 425fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner OutStreamer.EmitLabel(FakeStub); 426fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner } 427b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 428b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner // Emit pre-function debug and/or EH information. 4299c4210794ee42542a20023cd0a800003797523e0Torok Edwin if (DE) { 43003c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled); 43103c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman DE->BeginFunction(MF); 4329c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 4339c4210794ee42542a20023cd0a800003797523e0Torok Edwin if (DD) { 43403c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); 43503c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman DD->beginFunction(MF); 4369c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 437b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner} 438b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 4392cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the 4402cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner/// function. This can be overridden by targets as required to do custom stuff. 4412cf7251d39f28888af06b6f941eabd1d10995382Chris Lattnervoid AsmPrinter::EmitFunctionEntryLabel() { 442b4202dbb36e9799c96890fc3aa0040c1aedb33c8Chris Lattner // The function label could have already been emitted if two symbols end up 443b4202dbb36e9799c96890fc3aa0040c1aedb33c8Chris Lattner // conflicting due to asm renaming. Detect this and emit an error. 444b4202dbb36e9799c96890fc3aa0040c1aedb33c8Chris Lattner if (CurrentFnSym->isUndefined()) 445b4202dbb36e9799c96890fc3aa0040c1aedb33c8Chris Lattner return OutStreamer.EmitLabel(CurrentFnSym); 446b4202dbb36e9799c96890fc3aa0040c1aedb33c8Chris Lattner 447b4202dbb36e9799c96890fc3aa0040c1aedb33c8Chris Lattner report_fatal_error("'" + Twine(CurrentFnSym->getName()) + 448b4202dbb36e9799c96890fc3aa0040c1aedb33c8Chris Lattner "' label emitted multiple times to assembly file"); 4492cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner} 450b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 45148d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner 45247529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner/// EmitComments - Pretty-print comments for instructions. 45347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattnerstatic void EmitComments(const MachineInstr &MI, raw_ostream &CommentOS) { 45447529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner const MachineFunction *MF = MI.getParent()->getParent(); 45547529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner const TargetMachine &TM = MF->getTarget(); 45647529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 457de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner DebugLoc DL = MI.getDebugLoc(); 458de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner if (!DL.isUnknown()) { // Print source line info. 459de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner DIScope Scope(DL.getScope(MF->getFunction()->getContext())); 46047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // Omit the directory, because it's likely to be long and uninteresting. 4613c91b05d2b1751b9e4e21fd958d358ec463dcd3cDevang Patel if (Scope.Verify()) 46247529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << Scope.getFilename(); 46347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner else 46447529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << "<unknown>"; 465de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner CommentOS << ':' << DL.getLine(); 466de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner if (DL.getCol() != 0) 467de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner CommentOS << ':' << DL.getCol(); 46847529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << '\n'; 46947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } 47047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 47147529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // Check for spills and reloads 47247529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner int FI; 47347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 47447529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner const MachineFrameInfo *FrameInfo = MF->getFrameInfo(); 47547529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 47647529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // We assume a single instruction only has a spill or reload, not 47747529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // both. 47847529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner const MachineMemOperand *MMO; 47947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (TM.getInstrInfo()->isLoadFromStackSlotPostFE(&MI, FI)) { 48047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (FrameInfo->isSpillSlotObjectIndex(FI)) { 48147529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner MMO = *MI.memoperands_begin(); 48247529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << MMO->getSize() << "-byte Reload\n"; 48347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } 48447529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } else if (TM.getInstrInfo()->hasLoadFromStackSlot(&MI, MMO, FI)) { 48547529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (FrameInfo->isSpillSlotObjectIndex(FI)) 48647529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << MMO->getSize() << "-byte Folded Reload\n"; 48747529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } else if (TM.getInstrInfo()->isStoreToStackSlotPostFE(&MI, FI)) { 48847529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (FrameInfo->isSpillSlotObjectIndex(FI)) { 48947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner MMO = *MI.memoperands_begin(); 49047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << MMO->getSize() << "-byte Spill\n"; 49147529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } 49247529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } else if (TM.getInstrInfo()->hasStoreToStackSlot(&MI, MMO, FI)) { 49347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (FrameInfo->isSpillSlotObjectIndex(FI)) 49447529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << MMO->getSize() << "-byte Folded Spill\n"; 49547529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } 49647529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 49747529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // Check for spill-induced copies 49847529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; 49947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (TM.getInstrInfo()->isMoveInstr(MI, SrcReg, DstReg, 50047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner SrcSubIdx, DstSubIdx)) { 50145282aedb9c5a33d20565502c6c8fc871fa84cbeChris Lattner if (MI.getAsmPrinterFlag(MachineInstr::ReloadReuse)) 50247529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << " Reload Reuse\n"; 50347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } 50447529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner} 50547529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 50617fedf216bc10c66e02694854f522cb602097005Chris Lattner/// EmitImplicitDef - This method emits the specified machine instruction 50717fedf216bc10c66e02694854f522cb602097005Chris Lattner/// that is an implicit def. 50817fedf216bc10c66e02694854f522cb602097005Chris Lattnerstatic void EmitImplicitDef(const MachineInstr *MI, AsmPrinter &AP) { 50917fedf216bc10c66e02694854f522cb602097005Chris Lattner unsigned RegNo = MI->getOperand(0).getReg(); 51017fedf216bc10c66e02694854f522cb602097005Chris Lattner AP.OutStreamer.AddComment(Twine("implicit-def: ") + 51117fedf216bc10c66e02694854f522cb602097005Chris Lattner AP.TM.getRegisterInfo()->getName(RegNo)); 51217fedf216bc10c66e02694854f522cb602097005Chris Lattner AP.OutStreamer.AddBlankLine(); 51317fedf216bc10c66e02694854f522cb602097005Chris Lattner} 51417fedf216bc10c66e02694854f522cb602097005Chris Lattner 51517fedf216bc10c66e02694854f522cb602097005Chris Lattnerstatic void EmitKill(const MachineInstr *MI, AsmPrinter &AP) { 51617fedf216bc10c66e02694854f522cb602097005Chris Lattner std::string Str = "kill:"; 51717fedf216bc10c66e02694854f522cb602097005Chris Lattner for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 51817fedf216bc10c66e02694854f522cb602097005Chris Lattner const MachineOperand &Op = MI->getOperand(i); 51917fedf216bc10c66e02694854f522cb602097005Chris Lattner assert(Op.isReg() && "KILL instruction must have only register operands"); 52017fedf216bc10c66e02694854f522cb602097005Chris Lattner Str += ' '; 52117fedf216bc10c66e02694854f522cb602097005Chris Lattner Str += AP.TM.getRegisterInfo()->getName(Op.getReg()); 52217fedf216bc10c66e02694854f522cb602097005Chris Lattner Str += (Op.isDef() ? "<def>" : "<kill>"); 52317fedf216bc10c66e02694854f522cb602097005Chris Lattner } 52417fedf216bc10c66e02694854f522cb602097005Chris Lattner AP.OutStreamer.AddComment(Str); 52517fedf216bc10c66e02694854f522cb602097005Chris Lattner AP.OutStreamer.AddBlankLine(); 52617fedf216bc10c66e02694854f522cb602097005Chris Lattner} 52717fedf216bc10c66e02694854f522cb602097005Chris Lattner 528343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen/// EmitDebugValueComment - This method handles the target-independent form 529343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen/// of DBG_VALUE, returning true if it was able to do so. A false return 530343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen/// means the target will need to handle MI in EmitInstruction. 531343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesenstatic bool EmitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { 532343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // This code handles only the 3-operand target-independent form. 533343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen if (MI->getNumOperands() != 3) 534343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen return false; 535343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen 536a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer SmallString<128> Str; 537a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer raw_svector_ostream OS(Str); 538a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << '\t' << AP.MAI->getCommentString() << "DEBUG_VALUE: "; 539a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer 540343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // cast away const; DIetc do not take const operands for some reason. 54100d139064e525221fdf0ff00d001ce8b584d69d6Chris Lattner DIVariable V(const_cast<MDNode*>(MI->getOperand(2).getMetadata())); 54267a444ca362b6f2dc64016494eb1165d46aef0bfDevang Patel if (V.getContext().isSubprogram()) 5432db49d797b86b7f3615bae17b2b016727778a6c4Devang Patel OS << DISubprogram(V.getContext()).getDisplayName() << ":"; 544a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << V.getName() << " <- "; 545343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen 546343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // Register or immediate value. Register 0 means undef. 547343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen if (MI->getOperand(0).isFPImm()) { 548343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen APFloat APF = APFloat(MI->getOperand(0).getFPImm()->getValueAPF()); 549343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen if (MI->getOperand(0).getFPImm()->getType()->isFloatTy()) { 550a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << (double)APF.convertToFloat(); 551343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen } else if (MI->getOperand(0).getFPImm()->getType()->isDoubleTy()) { 552a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << APF.convertToDouble(); 553343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen } else { 554343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // There is no good way to print long double. Convert a copy to 555343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // double. Ah well, it's only a comment. 556343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen bool ignored; 557343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, 558343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen &ignored); 559a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << "(long double) " << APF.convertToDouble(); 560343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen } 561343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen } else if (MI->getOperand(0).isImm()) { 562a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << MI->getOperand(0).getImm(); 56300d139064e525221fdf0ff00d001ce8b584d69d6Chris Lattner } else { 56400d139064e525221fdf0ff00d001ce8b584d69d6Chris Lattner assert(MI->getOperand(0).isReg() && "Unknown operand type"); 565343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen if (MI->getOperand(0).getReg() == 0) { 566343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // Suppress offset, it is not meaningful here. 567a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << "undef"; 568343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // NOTE: Want this comment at start of line, don't emit with AddComment. 569a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer AP.OutStreamer.EmitRawText(OS.str()); 570343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen return true; 571343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen } 572a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << AP.TM.getRegisterInfo()->getName(MI->getOperand(0).getReg()); 57300d139064e525221fdf0ff00d001ce8b584d69d6Chris Lattner } 57400d139064e525221fdf0ff00d001ce8b584d69d6Chris Lattner 575a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer OS << '+' << MI->getOperand(1).getImm(); 576343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // NOTE: Want this comment at start of line, don't emit with AddComment. 577a592e671ee00e660e31274561e216f5ade39cea4Benjamin Kramer AP.OutStreamer.EmitRawText(OS.str()); 578343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen return true; 579343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen} 58047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 58114c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner/// EmitFunctionBody - This method emits the body and trailer for a 58214c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner/// function. 58314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattnervoid AsmPrinter::EmitFunctionBody() { 584edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner // Emit target-specific gunk before the function body. 585edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner EmitFunctionBodyStart(); 586edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner 58749cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner bool ShouldPrintDebugScopes = DD && MMI->hasDebugInfo(); 588285199502b08d7d2ac5f37ce5f94cb5e68cec197Chris Lattner 58914c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Print out code for the function. 59014c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner bool HasAnyRealCode = false; 59114c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); 59214c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner I != E; ++I) { 59314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Print a label for the basic block. 59414c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner EmitBasicBlockStart(I); 59514c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); 59614c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner II != IE; ++II) { 59714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Print the assembly for the instruction. 598d014761c9337f270f497aa960d51ee424bb166d5Dale Johannesen if (!II->isLabel() && !II->isImplicitDef() && !II->isKill() && 599d014761c9337f270f497aa960d51ee424bb166d5Dale Johannesen !II->isDebugValue()) { 60014c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner HasAnyRealCode = true; 601ed33b13a10258fe1589bf6a76d6d65ec33823076Evan Cheng ++EmittedInsts; 602ed33b13a10258fe1589bf6a76d6d65ec33823076Evan Cheng } 603ed33b13a10258fe1589bf6a76d6d65ec33823076Evan Cheng 6049c4210794ee42542a20023cd0a800003797523e0Torok Edwin if (ShouldPrintDebugScopes) { 60503c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); 60603c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman DD->beginScope(II); 6079c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 60814c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 6093f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose()) 61047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner EmitComments(*II, OutStreamer.GetCommentOS()); 61147529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 6120d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner switch (II->getOpcode()) { 613518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::DBG_LABEL: 614518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::EH_LABEL: 615518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::GC_LABEL: 616300a4c5640fb1c717ba0d7108d15aec1bd7eb396Chris Lattner OutStreamer.EmitLabel(II->getOperand(0).getMCSymbol()); 6170d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 618518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::INLINEASM: 619300a4c5640fb1c717ba0d7108d15aec1bd7eb396Chris Lattner EmitInlineAsm(II); 6200d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 621343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen case TargetOpcode::DBG_VALUE: 622343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen if (isVerbose()) { 623343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen if (!EmitDebugValueComment(II, *this)) 624343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen EmitInstruction(II); 625343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen } 626343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen break; 627518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::IMPLICIT_DEF: 62817fedf216bc10c66e02694854f522cb602097005Chris Lattner if (isVerbose()) EmitImplicitDef(II, *this); 6290d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 630518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::KILL: 63117fedf216bc10c66e02694854f522cb602097005Chris Lattner if (isVerbose()) EmitKill(II, *this); 6320d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 6330d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner default: 6340d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner EmitInstruction(II); 6350d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 6360d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner } 63714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 6389c4210794ee42542a20023cd0a800003797523e0Torok Edwin if (ShouldPrintDebugScopes) { 63903c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); 64003c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman DD->endScope(II); 6419c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 64214c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner } 64314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner } 64414c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 64514c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // If the function is empty and the object file uses .subsections_via_symbols, 646d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner // then we need to emit *something* to the function body to prevent the 647ee9eb411fffddbb8fe70418c05946a131889b487Chris Lattner // labels from collapsing together. Just emit a noop. 648ee9eb411fffddbb8fe70418c05946a131889b487Chris Lattner if (MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode) { 649ee9eb411fffddbb8fe70418c05946a131889b487Chris Lattner MCInst Noop; 650ee9eb411fffddbb8fe70418c05946a131889b487Chris Lattner TM.getInstrInfo()->getNoopForMachoTarget(Noop); 651d61647d306bc297603c607411b2777b217cd65b6Chris Lattner if (Noop.getOpcode()) { 652d61647d306bc297603c607411b2777b217cd65b6Chris Lattner OutStreamer.AddComment("avoids zero-length function"); 653ee9eb411fffddbb8fe70418c05946a131889b487Chris Lattner OutStreamer.EmitInstruction(Noop); 654d61647d306bc297603c607411b2777b217cd65b6Chris Lattner } else // Target not mc-ized yet. 655ee9eb411fffddbb8fe70418c05946a131889b487Chris Lattner OutStreamer.EmitRawText(StringRef("\tnop\n")); 656ee9eb411fffddbb8fe70418c05946a131889b487Chris Lattner } 65714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 658edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner // Emit target-specific gunk after the function body. 659edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner EmitFunctionBodyEnd(); 660edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner 661fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner // If the target wants a .size directive for the size of the function, emit 662fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner // it. 663fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner if (MAI->hasDotTypeDotSizeDirective()) { 6640c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner // Create a symbol for the end of function, so we can get the size as 6650c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner // difference between the function label and the temp label. 6660c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner MCSymbol *FnEndLabel = OutContext.CreateTempSymbol(); 6670c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner OutStreamer.EmitLabel(FnEndLabel); 6680c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner 6690c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner const MCExpr *SizeExp = 6700c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(FnEndLabel, OutContext), 6710c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner MCSymbolRefExpr::Create(CurrentFnSym, OutContext), 6720c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner OutContext); 6730c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner OutStreamer.EmitELFSize(CurrentFnSym, SizeExp); 674fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner } 67514c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 67614c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Emit post-function debug information. 6779c4210794ee42542a20023cd0a800003797523e0Torok Edwin if (DD) { 67803c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); 67903c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman DD->endFunction(MF); 6809c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 6819c4210794ee42542a20023cd0a800003797523e0Torok Edwin if (DE) { 68203c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled); 68303c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman DE->EndFunction(); 6849c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 68549cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner MMI->EndFunction(); 68614c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 68714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Print out jump tables referenced by the function. 68814c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner EmitJumpTableInfo(); 689d26a80f666fb925956a4f19143265f5150756df0Chris Lattner 690d26a80f666fb925956a4f19143265f5150756df0Chris Lattner OutStreamer.AddBlankLine(); 69114c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner} 69214c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 69328ff35d030e2f49ff4e4b1544c015ebe011a530bDevang Patel/// getDebugValueLocation - Get location information encoded by DBG_VALUE 69428ff35d030e2f49ff4e4b1544c015ebe011a530bDevang Patel/// operands. 69528ff35d030e2f49ff4e4b1544c015ebe011a530bDevang PatelMachineLocation AsmPrinter::getDebugValueLocation(const MachineInstr *MI) const { 69628ff35d030e2f49ff4e4b1544c015ebe011a530bDevang Patel // Target specific DBG_VALUE instructions are handled by each target. 69728ff35d030e2f49ff4e4b1544c015ebe011a530bDevang Patel return MachineLocation(); 69828ff35d030e2f49ff4e4b1544c015ebe011a530bDevang Patel} 69914c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 700a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattnerbool AsmPrinter::doFinalization(Module &M) { 70140bbebde9d250b875a47a688d0c6552834ada48fChris Lattner // Emit global variables. 70240bbebde9d250b875a47a688d0c6552834ada48fChris Lattner for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 70340bbebde9d250b875a47a688d0c6552834ada48fChris Lattner I != E; ++I) 70448d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner EmitGlobalVariable(I); 70540bbebde9d250b875a47a688d0c6552834ada48fChris Lattner 70649cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner // Finalize debug and EH information. 70749cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner if (DE) { 70803c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman { 70903c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled); 7109c4210794ee42542a20023cd0a800003797523e0Torok Edwin DE->EndModule(); 7119c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 71249cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner delete DE; DE = 0; 71349cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner } 71449cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner if (DD) { 71503c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman { 71603c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); 7179c4210794ee42542a20023cd0a800003797523e0Torok Edwin DD->endModule(); 7189c4210794ee42542a20023cd0a800003797523e0Torok Edwin } 71949cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner delete DD; DD = 0; 72049cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner } 7211f522feabf25134249bc7894e04f5b89fa071b7fChris Lattner 7220a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // If the target wants to know about weak references, print them all. 72333adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->getWeakRefDirective()) { 7240a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // FIXME: This is not lazy, it would be nice to only print weak references 7250a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // to stuff that is actually used. Note that doing so would require targets 7260a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // to notice uses in operands (due to constant exprs etc). This should 7270a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // happen with the MC stuff eventually. 7280a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner 7290a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // Print out module-level global variables here. 7300a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 7310a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner I != E; ++I) { 73208ce3b473d06e0f7806df3d44b7b36ac40c58803Chris Lattner if (!I->hasExternalWeakLinkage()) continue; 733deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference); 7340a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner } 7350a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner 736c6fdced3dbfdf673cc9b01dfad4f08e316d8803dChris Lattner for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) { 73708ce3b473d06e0f7806df3d44b7b36ac40c58803Chris Lattner if (!I->hasExternalWeakLinkage()) continue; 738deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference); 7390a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner } 74015404d060ba8b604c03b9223a0f2e2abcd0fddedRafael Espindola } 74115404d060ba8b604c03b9223a0f2e2abcd0fddedRafael Espindola 742cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner if (MAI->hasSetDirective()) { 7433a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner OutStreamer.AddBlankLine(); 7448b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); 7450a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner I != E; ++I) { 746deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner MCSymbol *Name = Mang->getSymbol(I); 747325be7c608a37d87e4f3d731e11fa3dd34f529b5Anton Korobeynikov 748325be7c608a37d87e4f3d731e11fa3dd34f529b5Anton Korobeynikov const GlobalValue *GV = cast<GlobalValue>(I->getAliasedGlobal()); 749deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner MCSymbol *Target = Mang->getSymbol(GV); 7505c40e694dcd679bf26b962189c1d12b32fff07cdChris Lattner 75110b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner if (I->hasExternalLinkage() || !MAI->getWeakRefDirective()) 752a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitSymbolAttribute(Name, MCSA_Global); 75310b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner else if (I->hasWeakLinkage()) 754a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitSymbolAttribute(Name, MCSA_WeakReference); 75510b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner else 75610595490ccf25b4960936638fac7a673eaf82e68Chris Lattner assert(I->hasLocalLinkage() && "Invalid alias linkage"); 75722c9e65643e0c6b43be37a19e59491ef0081092cAnton Korobeynikov 758be9dfcef82c58063708e039bea3cf972ba41581bChris Lattner EmitVisibility(Name, I->getVisibility()); 75922c9e65643e0c6b43be37a19e59491ef0081092cAnton Korobeynikov 760c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner // Emit the directives as assignments aka .set: 761c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner OutStreamer.EmitAssignment(Name, 762c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner MCSymbolRefExpr::Create(Target, OutContext)); 7638b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov } 7648b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov } 7658b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov 7661465d61bdd36cfd6021036a527895f0dd358e97dDuncan Sands GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); 7675eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen assert(MI && "AsmPrinter didn't require GCModuleInfo?"); 7685eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; ) 7695eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I)) 7707d73c7f0d618dd6661cd55834c58aa62f22b28feChris Lattner MP->finishAssembly(*this); 771ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksen 772a779a9899a5e23bd5198973f4709d66cb4bc2e64Dan Gohman // If we don't have any trampolines, then we don't require stack memory 773a779a9899a5e23bd5198973f4709d66cb4bc2e64Dan Gohman // to be executable. Some targets have a directive to declare this. 7740a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline"); 775a779a9899a5e23bd5198973f4709d66cb4bc2e64Dan Gohman if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty()) 77674aae4726a66733c5872588287535a984f9a94c7Chris Lattner if (const MCSection *S = MAI->getNonexecutableStackSection(OutContext)) 777f9f93e4388962b678fd59b7af5212d4cc0d38be2Chris Lattner OutStreamer.SwitchSection(S); 778bd23d5fda85e38c88dfa668a99777cd05c524822Chris Lattner 779bd23d5fda85e38c88dfa668a99777cd05c524822Chris Lattner // Allow the target to emit any magic that it wants at the end of the file, 780bd23d5fda85e38c88dfa668a99777cd05c524822Chris Lattner // after everything else has gone out. 781bd23d5fda85e38c88dfa668a99777cd05c524822Chris Lattner EmitEndOfAsmFile(M); 782bd23d5fda85e38c88dfa668a99777cd05c524822Chris Lattner 783a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner delete Mang; Mang = 0; 78449cd6649e1246c05896fadefe2fcbc4bc1f5d221Chris Lattner MMI = 0; 7852b2954f00ba02ca1a902f47080cd9f06aebc0378Chris Lattner 7862b2954f00ba02ca1a902f47080cd9f06aebc0378Chris Lattner OutStreamer.Finish(); 787a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner return false; 788a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner} 789a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner 79025045bdcda822d63674e2df7e34016536c5d3fa7Chris Lattnervoid AsmPrinter::SetupMachineFunction(MachineFunction &MF) { 791b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner this->MF = &MF; 792412c3a5bc9e70fe8579551216786e70d323a3dd5Chris Lattner // Get the function symbol. 793deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner CurrentFnSym = Mang->getSymbol(MF.getFunction()); 794b71d1b2fe2c0673005283b48be2f37c750ce367bDavid Greene 7953f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose()) 796b71d1b2fe2c0673005283b48be2f37c750ce367bDavid Greene LI = &getAnalysis<MachineLoopInfo>(); 797a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner} 798a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner 7991606e8e4cd937e6de6681f686c266cf61722d972Evan Chengnamespace { 8001606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng // SectionCPs - Keep track the alignment, constpool entries per Section. 8011606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng struct SectionCPs { 802a87dea4f8c546ca748f1777a8d1cabcc06515d91Chris Lattner const MCSection *S; 8031606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Alignment; 8041606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng SmallVector<unsigned, 4> CPEs; 805cabdd7425d30f7eb659ecb0cc5efbc4052dd78a8Douglas Gregor SectionCPs(const MCSection *s, unsigned a) : S(s), Alignment(a) {} 8061606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng }; 8071606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng} 8081606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 8093b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// EmitConstantPool - Print to the current output stream assembly 8103b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// representations of the constants in the constant pool MCP. This is 8113b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// used to print out constants which have been "spilled to memory" by 8123b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// the code generator. 8133b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// 814a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattnervoid AsmPrinter::EmitConstantPool() { 815a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner const MachineConstantPool *MCP = MF->getConstantPool(); 816fa77d43ba1d91ed39f46e11caeb28dcabae9e193Chris Lattner const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants(); 8173b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner if (CP.empty()) return; 8182d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng 819088ae8393f124564ca9ab70654645aa656e5646fAnton Korobeynikov // Calculate sections for constant pool entries. We collect entries to go into 820088ae8393f124564ca9ab70654645aa656e5646fAnton Korobeynikov // the same section together to reduce amount of section switch statements. 8211606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng SmallVector<SectionCPs, 4> CPSections; 8222d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng for (unsigned i = 0, e = CP.size(); i != e; ++i) { 823298414ec1891ce8d3a1b69e6019ad8765c8e69dcChris Lattner const MachineConstantPoolEntry &CPE = CP[i]; 8241606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Align = CPE.getAlignment(); 8255c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner 8265c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner SectionKind Kind; 8275c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner switch (CPE.getRelocationInfo()) { 8285c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner default: llvm_unreachable("Unknown section kind"); 8292798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner case 2: Kind = SectionKind::getReadOnlyWithRel(); break; 8304c50922f6be96fdb1e9a924aeeecf91638e2c52bChris Lattner case 1: 8312798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner Kind = SectionKind::getReadOnlyWithRelLocal(); 8324c50922f6be96fdb1e9a924aeeecf91638e2c52bChris Lattner break; 8335c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner case 0: 8344c50922f6be96fdb1e9a924aeeecf91638e2c52bChris Lattner switch (TM.getTargetData()->getTypeAllocSize(CPE.getType())) { 8352798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner case 4: Kind = SectionKind::getMergeableConst4(); break; 8362798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner case 8: Kind = SectionKind::getMergeableConst8(); break; 8372798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner case 16: Kind = SectionKind::getMergeableConst16();break; 8382798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner default: Kind = SectionKind::getMergeableConst(); break; 8394c50922f6be96fdb1e9a924aeeecf91638e2c52bChris Lattner } 8405c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner } 8415c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner 84283d77faf6e8fc2c1c2377d037283dc162d8667a1Chris Lattner const MCSection *S = getObjFileLowering().getSectionForConstant(Kind); 843298414ec1891ce8d3a1b69e6019ad8765c8e69dcChris Lattner 8441606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng // The number of sections are small, just do a linear search from the 8451606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng // last section to the first. 8461606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng bool Found = false; 8471606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned SecIdx = CPSections.size(); 8481606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng while (SecIdx != 0) { 8491606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (CPSections[--SecIdx].S == S) { 8501606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng Found = true; 8511606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng break; 8521606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng } 8531606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng } 8541606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (!Found) { 8551606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng SecIdx = CPSections.size(); 8561606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng CPSections.push_back(SectionCPs(S, Align)); 8571606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng } 8581606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 8591606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (Align > CPSections[SecIdx].Alignment) 8601606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng CPSections[SecIdx].Alignment = Align; 8611606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng CPSections[SecIdx].CPEs.push_back(i); 8622d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng } 8632d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng 864088ae8393f124564ca9ab70654645aa656e5646fAnton Korobeynikov // Now print stuff into the calculated sections. 8651606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng for (unsigned i = 0, e = CPSections.size(); i != e; ++i) { 8666c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(CPSections[i].S); 8671606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng EmitAlignment(Log2_32(CPSections[i].Alignment)); 8682d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng 8691606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Offset = 0; 8701606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng for (unsigned j = 0, ee = CPSections[i].CPEs.size(); j != ee; ++j) { 8711606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned CPI = CPSections[i].CPEs[j]; 8721606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng MachineConstantPoolEntry CPE = CP[CPI]; 8731606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 8741606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng // Emit inter-object padding for alignment. 8751606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned AlignMask = CPE.getAlignment() - 1; 8761606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned NewOffset = (Offset + AlignMask) & ~AlignMask; 877aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner OutStreamer.EmitFill(NewOffset - Offset, 0/*fillval*/, 0/*addrspace*/); 8781606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 8791606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng const Type *Ty = CPE.getType(); 880777d2306b36816a53bc1ae1244c0dc7d998ae691Duncan Sands Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty); 8812d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng 8823924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner // Emit the label with a comment on it. 8833f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose()) { 8843924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner OutStreamer.GetCommentOS() << "constant pool "; 8853924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner WriteTypeSymbolic(OutStreamer.GetCommentOS(), CPE.getType(), 8863924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner MF->getFunction()->getParent()); 8873924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner OutStreamer.GetCommentOS() << '\n'; 8881606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng } 8893924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner OutStreamer.EmitLabel(GetCPISymbol(CPI)); 8903924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner 8911606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (CPE.isMachineConstantPoolEntry()) 8921606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng EmitMachineConstantPoolValue(CPE.Val.MachineCPVal); 893088ae8393f124564ca9ab70654645aa656e5646fAnton Korobeynikov else 8941606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng EmitGlobalConstant(CPE.Val.ConstVal); 8953029f920519e0871a5aad5d7c592281093953733Chris Lattner } 8963b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner } 8973b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner} 8983b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner 89937efe6764568a3829fee26aba532283131d1a104Nate Begeman/// EmitJumpTableInfo - Print assembly representations of the jump tables used 90037efe6764568a3829fee26aba532283131d1a104Nate Begeman/// by the current function to the current output stream. 90137efe6764568a3829fee26aba532283131d1a104Nate Begeman/// 90214c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattnervoid AsmPrinter::EmitJumpTableInfo() { 90314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 90444e87255e9b7a9d8ecb558690db1181882c08045Chris Lattner if (MJTI == 0) return; 90595da605e15a6f108b551ecc6772823ea53de3007Richard Osborne if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline) return; 90637efe6764568a3829fee26aba532283131d1a104Nate Begeman const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 90737efe6764568a3829fee26aba532283131d1a104Nate Begeman if (JT.empty()) return; 9089de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov 9092f1ae88445c696a9b9d61e14747ba721190cdc99Nate Begeman // Pick the directive to use to print the jump table entries, and switch to 9102f1ae88445c696a9b9d61e14747ba721190cdc99Nate Begeman // the appropriate section. 91114c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner const Function *F = MF->getFunction(); 912b13bafe5c12dd908b55c559c93adaeb1627ed096Evan Cheng bool JTInDiffSection = false; 913f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner if (// In PIC mode, we need to emit the jump table to the same section as the 914f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // function body itself, otherwise the label differences won't make sense. 915f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // FIXME: Need a better predicate for this: what about custom entries? 916f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 || 917f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // We should also do if the section name is NULL or function is declared 918f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // in discardable section 919f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // FIXME: this isn't the right predicate, should be based on the MCSection 920f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // for the function. 921f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner F->isWeakForLinker()) { 92214c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F,Mang,TM)); 9232f1ae88445c696a9b9d61e14747ba721190cdc99Nate Begeman } else { 92483d77faf6e8fc2c1c2377d037283dc162d8667a1Chris Lattner // Otherwise, drop it in the readonly section. 92583d77faf6e8fc2c1c2377d037283dc162d8667a1Chris Lattner const MCSection *ReadOnlySection = 9262798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner getObjFileLowering().getSectionForConstant(SectionKind::getReadOnly()); 9276c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(ReadOnlySection); 928b13bafe5c12dd908b55c559c93adaeb1627ed096Evan Cheng JTInDiffSection = true; 9292f1ae88445c696a9b9d61e14747ba721190cdc99Nate Begeman } 930071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner 931071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner EmitAlignment(Log2_32(MJTI->getEntryAlignment(*TM.getTargetData()))); 9320c4e6789da4dba6c7b0010886776b24dec3f3bb8Chris Lattner 9333b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) { 9343b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 93507371882208f913d18a7f2a47373eaee7138416bChris Lattner 93607371882208f913d18a7f2a47373eaee7138416bChris Lattner // If this jump table was deleted, ignore it. 93707371882208f913d18a7f2a47373eaee7138416bChris Lattner if (JTBBs.empty()) continue; 93852a51e38dc312aa262b0d771419afe1785f3cb22Nate Begeman 939e35df92eca194365f984f9d24a74e4ddd6669c40Chris Lattner // For the EK_LabelDifference32 entry, if the target supports .set, emit a 940e35df92eca194365f984f9d24a74e4ddd6669c40Chris Lattner // .set directive for each unique entry. This reduces the number of 941e35df92eca194365f984f9d24a74e4ddd6669c40Chris Lattner // relocations the assembler will generate for the jump table. 942e35df92eca194365f984f9d24a74e4ddd6669c40Chris Lattner if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 && 943cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner MAI->hasSetDirective()) { 9443b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner SmallPtrSet<const MachineBasicBlock*, 16> EmittedSets; 9453b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner const TargetLowering *TLI = TM.getTargetLowering(); 94614c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF,JTI,OutContext); 9473b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { 9483b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner const MachineBasicBlock *MBB = JTBBs[ii]; 9493b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner if (!EmittedSets.insert(MBB)) continue; 9503b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner 951c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner // .set LJTSet, LBB32-base 952c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner const MCExpr *LHS = 9531b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 954c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner OutStreamer.EmitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()), 955c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner MCBinaryExpr::CreateSub(LHS, Base, OutContext)); 9563b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner } 9573b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner } 95852a51e38dc312aa262b0d771419afe1785f3cb22Nate Begeman 9597c30191393c99c9ba804f1a01942a9e130c53904Chris Lattner // On some targets (e.g. Darwin) we want to emit two consequtive labels 960393a8eea3c15de08eaf6953aa8a65a3961b76153Chris Lattner // before each jump table. The first label is never referenced, but tells 961393a8eea3c15de08eaf6953aa8a65a3961b76153Chris Lattner // the assembler and linker the extents of the jump table object. The 962393a8eea3c15de08eaf6953aa8a65a3961b76153Chris Lattner // second label is actually referenced by the code. 9633924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner if (JTInDiffSection && MAI->getLinkerPrivateGlobalPrefix()[0]) 964beeb93e6ba48af2661eabc4872d8b159fb43e5dbChris Lattner // FIXME: This doesn't have to have any specific name, just any randomly 965beeb93e6ba48af2661eabc4872d8b159fb43e5dbChris Lattner // named and numbered 'l' label would work. Simplify GetJTISymbol. 9663b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner OutStreamer.EmitLabel(GetJTISymbol(JTI, true)); 9673924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner 9683b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner OutStreamer.EmitLabel(GetJTISymbol(JTI)); 9693924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner 9706bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) 9713b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner EmitJumpTableEntry(MJTI, JTBBs[ii], JTI); 97237efe6764568a3829fee26aba532283131d1a104Nate Begeman } 97337efe6764568a3829fee26aba532283131d1a104Nate Begeman} 97437efe6764568a3829fee26aba532283131d1a104Nate Begeman 9756bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner/// EmitJumpTableEntry - Emit a jump table entry for the specified MBB to the 9766bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner/// current stream. 9776bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattnervoid AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, 9786bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner const MachineBasicBlock *MBB, 9796bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner unsigned UID) const { 980ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner const MCExpr *Value = 0; 981ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner switch (MJTI->getEntryKind()) { 98295da605e15a6f108b551ecc6772823ea53de3007Richard Osborne case MachineJumpTableInfo::EK_Inline: 98395da605e15a6f108b551ecc6772823ea53de3007Richard Osborne llvm_unreachable("Cannot emit EK_Inline jump table entry"); break; 98485fe07866a3b240d9facef3b2f2ea81a0a8db018Chris Lattner case MachineJumpTableInfo::EK_Custom32: 9856bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner Value = TM.getTargetLowering()->LowerCustomJumpTableEntry(MJTI, MBB, UID, 98685fe07866a3b240d9facef3b2f2ea81a0a8db018Chris Lattner OutContext); 98785fe07866a3b240d9facef3b2f2ea81a0a8db018Chris Lattner break; 988ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner case MachineJumpTableInfo::EK_BlockAddress: 989ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // EK_BlockAddress - Each entry is a plain address of block, e.g.: 990ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .word LBB123 9911b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 992ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner break; 993ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner case MachineJumpTableInfo::EK_GPRel32BlockAddress: { 994ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // EK_GPRel32BlockAddress - Each entry is an address of block, encoded 995ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // with a relocation as gp-relative, e.g.: 996ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .gprel32 LBB123 9971b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner MCSymbol *MBBSym = MBB->getSymbol(); 998718fb59801320b8cb22363d115b5fc5ec40dc1f5Chris Lattner OutStreamer.EmitGPRel32Value(MCSymbolRefExpr::Create(MBBSym, OutContext)); 99978f485afb723121eedf4b6907ae6eb53da8af03cChris Lattner return; 10009de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov } 100185fe07866a3b240d9facef3b2f2ea81a0a8db018Chris Lattner 1002ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner case MachineJumpTableInfo::EK_LabelDifference32: { 1003ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // EK_LabelDifference32 - Each entry is the address of the block minus 1004ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // the address of the jump table. This is used for PIC jump tables where 1005ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // gprel32 is not supported. e.g.: 1006ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .word LBB123 - LJTI1_2 1007ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // If the .set directive is supported, this is emitted as: 1008ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .set L4_5_set_123, LBB123 - LJTI1_2 1009ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .word L4_5_set_123 1010ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner 1011ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // If we have emitted set directives for the jump table entries, print 1012ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // them rather than the entries themselves. If we're emitting PIC, then 1013ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // emit the table entries as differences between two text section labels. 1014cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner if (MAI->hasSetDirective()) { 1015ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // If we used .set, reference the .set's symbol. 10166bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner Value = MCSymbolRefExpr::Create(GetJTSetSymbol(UID, MBB->getNumber()), 1017ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner OutContext); 1018ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner break; 1019ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner } 10201aca2492526c0a1aa464f2993084f9b30b53c009Chris Lattner // Otherwise, use the difference as the jump table entry. 10211b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 10226bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner const MCExpr *JTI = MCSymbolRefExpr::Create(GetJTISymbol(UID), OutContext); 1023ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner Value = MCBinaryExpr::CreateSub(Value, JTI, OutContext); 1024ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner break; 1025ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner } 10269de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov } 10271aca2492526c0a1aa464f2993084f9b30b53c009Chris Lattner 1028ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner assert(Value && "Unknown entry kind!"); 1029ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner 1030071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner unsigned EntrySize = MJTI->getEntrySize(*TM.getTargetData()); 1031ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner OutStreamer.EmitValue(Value, EntrySize, /*addrspace*/0); 10329de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov} 10339de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov 10349de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov 1035ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner/// EmitSpecialLLVMGlobal - Check to see if the specified global is a 1036ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner/// special global used by LLVM. If so, emit it and return true, otherwise 1037ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner/// do nothing and return false. 1038ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattnerbool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { 103903d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar if (GV->getName() == "llvm.used") { 10403a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner if (MAI->hasNoDeadStrip()) // No need to emit this at all. 1041b753a9bb6277cd34ffc55f8674087ff8c3097a11Andrew Lenharth EmitLLVMUsedList(GV->getInitializer()); 1042b753a9bb6277cd34ffc55f8674087ff8c3097a11Andrew Lenharth return true; 1043b753a9bb6277cd34ffc55f8674087ff8c3097a11Andrew Lenharth } 1044b753a9bb6277cd34ffc55f8674087ff8c3097a11Andrew Lenharth 1045401e10c4fbfcdcfade5065093e2ca97f69a1d144Chris Lattner // Ignore debug and non-emitted data. This handles llvm.compiler.used. 1046266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner if (GV->getSection() == "llvm.metadata" || 1047266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner GV->hasAvailableExternallyLinkage()) 1048266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner return true; 10497809811e4ed3c2462efa327cef0464b9844baea2Jim Laskey 10507809811e4ed3c2462efa327cef0464b9844baea2Jim Laskey if (!GV->hasAppendingLinkage()) return false; 10517809811e4ed3c2462efa327cef0464b9844baea2Jim Laskey 10527809811e4ed3c2462efa327cef0464b9844baea2Jim Laskey assert(GV->hasInitializer() && "Not a special LLVM global!"); 1053ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 1054916d07cdfa89e77118043ec6e14575512ae1bf85Evan Cheng const TargetData *TD = TM.getTargetData(); 1055916d07cdfa89e77118043ec6e14575512ae1bf85Evan Cheng unsigned Align = Log2_32(TD->getPointerPrefAlignment()); 1056f231c07228deb75b6cd5ae7c9c057bc8303c6998Chris Lattner if (GV->getName() == "llvm.global_ctors") { 10576c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(getObjFileLowering().getStaticCtorSection()); 1058e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner EmitAlignment(Align); 1059ea3a9ff53d699bc22fcff52dbbce8aab6578a020Chris Lattner EmitXXStructorList(GV->getInitializer()); 106071eae713153e564ec743c5c4162ff258c255de78Chris Lattner 106171eae713153e564ec743c5c4162ff258c255de78Chris Lattner if (TM.getRelocationModel() == Reloc::Static && 10623a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner MAI->hasStaticCtorDtorReferenceInStaticMode()) { 10633a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner StringRef Sym(".constructors_used"); 10643a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym), 1065a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner MCSA_Reference); 10663a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner } 1067ea3a9ff53d699bc22fcff52dbbce8aab6578a020Chris Lattner return true; 1068ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner } 1069ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 1070f231c07228deb75b6cd5ae7c9c057bc8303c6998Chris Lattner if (GV->getName() == "llvm.global_dtors") { 10716c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(getObjFileLowering().getStaticDtorSection()); 1072e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner EmitAlignment(Align); 1073ea3a9ff53d699bc22fcff52dbbce8aab6578a020Chris Lattner EmitXXStructorList(GV->getInitializer()); 107471eae713153e564ec743c5c4162ff258c255de78Chris Lattner 107571eae713153e564ec743c5c4162ff258c255de78Chris Lattner if (TM.getRelocationModel() == Reloc::Static && 10763a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner MAI->hasStaticCtorDtorReferenceInStaticMode()) { 10773a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner StringRef Sym(".destructors_used"); 10783a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym), 1079a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner MCSA_Reference); 10803a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner } 1081ea3a9ff53d699bc22fcff52dbbce8aab6578a020Chris Lattner return true; 1082ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner } 1083ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 1084ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner return false; 1085ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner} 1086ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 108733adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner/// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each 1088d2e51af0358b571367a9f1e5175b87e9dd72edf8Dale Johannesen/// global in the specified llvm.used list for which emitUsedDirectiveFor 1089d2e51af0358b571367a9f1e5175b87e9dd72edf8Dale Johannesen/// is true, as being used with this directive. 1090cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattnervoid AsmPrinter::EmitLLVMUsedList(Constant *List) { 1091a119de86a064414622562cfe32953de7f9b0ee40Dan Gohman // Should be an array of 'i8*'. 1092cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner ConstantArray *InitList = dyn_cast<ConstantArray>(List); 1093cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner if (InitList == 0) return; 1094cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner 1095cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { 109616fe990e56102a355f1e77aca93bf8c79d7b9eb2Chris Lattner const GlobalValue *GV = 109716fe990e56102a355f1e77aca93bf8c79d7b9eb2Chris Lattner dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts()); 10983a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner if (GV && getObjFileLowering().shouldEmitUsedDirectiveFor(GV, Mang)) 1099deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner OutStreamer.EmitSymbolAttribute(Mang->getSymbol(GV), MCSA_NoDeadStrip); 1100cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner } 1101cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner} 1102cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner 1103ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner/// EmitXXStructorList - Emit the ctor or dtor list. This just prints out the 1104ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner/// function pointers, ignoring the init priority. 1105ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattnervoid AsmPrinter::EmitXXStructorList(Constant *List) { 1106ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner // Should be an array of '{ int, void ()* }' structs. The first value is the 1107ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner // init priority, which we ignore. 1108ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner if (!isa<ConstantArray>(List)) return; 1109ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner ConstantArray *InitList = cast<ConstantArray>(List); 1110ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) 1111ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){ 1112ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. 11138de324b59ce81cfb4202c706c96a3140f52e00c0Chris Lattner 11148de324b59ce81cfb4202c706c96a3140f52e00c0Chris Lattner if (CS->getOperand(1)->isNullValue()) 11158de324b59ce81cfb4202c706c96a3140f52e00c0Chris Lattner return; // Found a null terminator, exit printing. 11168de324b59ce81cfb4202c706c96a3140f52e00c0Chris Lattner // Emit the function pointer. 1117ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner EmitGlobalConstant(CS->getOperand(1)); 1118ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner } 1119ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner} 11203b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner 1121f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey//===--------------------------------------------------------------------===// 1122f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey// Emission and print routines 1123f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey// 1124f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 1125f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// EmitInt8 - Emit a byte directive and value. 1126f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// 1127f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskeyvoid AsmPrinter::EmitInt8(int Value) const { 11285eaa54e210256a939f15e918303197916c992aeeChris Lattner OutStreamer.EmitIntValue(Value, 1, 0/*addrspace*/); 1129f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey} 1130f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 1131f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// EmitInt16 - Emit a short directive and value. 1132f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// 1133f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskeyvoid AsmPrinter::EmitInt16(int Value) const { 11345eaa54e210256a939f15e918303197916c992aeeChris Lattner OutStreamer.EmitIntValue(Value, 2, 0/*addrspace*/); 1135f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey} 1136f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 1137f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// EmitInt32 - Emit a long directive and value. 1138f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// 1139f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskeyvoid AsmPrinter::EmitInt32(int Value) const { 11405eaa54e210256a939f15e918303197916c992aeeChris Lattner OutStreamer.EmitIntValue(Value, 4, 0/*addrspace*/); 1141f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey} 1142f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 11430d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner/// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size 11440d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner/// in bytes of the directive is specified by Size and Hi/Lo specify the 11450d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner/// labels. This implicitly uses .set if it is available. 11460d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattnervoid AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, 11470d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner unsigned Size) const { 11480d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner // Get the Hi-Lo expression. 11490d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner const MCExpr *Diff = 11500d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(Hi, OutContext), 11510d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner MCSymbolRefExpr::Create(Lo, OutContext), 11520d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner OutContext); 11530d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner 11540d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner if (!MAI->hasSetDirective()) { 11550d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner OutStreamer.EmitValue(Diff, Size, 0/*AddrSpace*/); 11560d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner return; 11570d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner } 11580d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner 11590d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner // Otherwise, emit with .set (aka assignment). 1160c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner MCSymbol *SetLabel = GetTempSymbol("set", SetCounter++); 11610d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner OutStreamer.EmitAssignment(SetLabel, Diff); 11626cde3e6e993126df756e3be5b9ef43540b904644Chris Lattner OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/); 11630d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner} 11640d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner 1165f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel/// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo" 1166f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel/// where the size in bytes of the directive is specified by Size and Hi/Lo 1167f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel/// specify the labels. This implicitly uses .set if it is available. 1168f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patelvoid AsmPrinter::EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset, 1169f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel const MCSymbol *Lo, unsigned Size) 1170f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel const { 1171f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel 1172f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel // Emit Hi+Offset - Lo 1173f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel // Get the Hi+Offset expression. 1174f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel const MCExpr *Plus = 1175f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Hi, OutContext), 1176f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel MCConstantExpr::Create(Offset, OutContext), 1177f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel OutContext); 1178f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel 1179f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel // Get the Hi+Offset-Lo expression. 1180f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel const MCExpr *Diff = 1181f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel MCBinaryExpr::CreateSub(Plus, 1182f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel MCSymbolRefExpr::Create(Lo, OutContext), 1183f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel OutContext); 1184f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel 1185f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel if (!MAI->hasSetDirective()) 1186f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel OutStreamer.EmitValue(Diff, 4, 0/*AddrSpace*/); 1187f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel else { 1188f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel // Otherwise, emit with .set (aka assignment). 1189f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel MCSymbol *SetLabel = GetTempSymbol("set", SetCounter++); 1190f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel OutStreamer.EmitAssignment(SetLabel, Diff); 1191f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel OutStreamer.EmitSymbolValue(SetLabel, 4, 0/*AddrSpace*/); 1192f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel } 1193f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel} 1194f2548caaa8b290aa598bf49c27dff72f7751ba5cDevang Patel 11950d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner 1196f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey//===----------------------------------------------------------------------===// 1197f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 11983a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// EmitAlignment - Emit an alignment directive to the specified power of 11993a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// two boundary. For example, if you pass in 3 here, you will get an 8 12003a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// byte alignment. If a global value is specified, and if that global has 1201e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner// an explicit alignment requested, it will override the alignment request 1202e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner// if required for correctness. 12033a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// 1204a7b611c10d0e5fef5870d854518e639ce3d3c6beChris Lattnervoid AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const { 1205e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner if (GV) NumBits = getGVAlignmentLog2(GV, *TM.getTargetData(), NumBits); 12063a4205367dc845d4cd804b47e061f8281777c9daChris Lattner 1207e87f7bb50e1d08a09e29252806f6502dcff0539dChris Lattner if (NumBits == 0) return; // 1-byte aligned: no need to emit alignment. 1208663c2d2580e6e9b2435785c7e5a2de18758860a3Chris Lattner 1209dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattner if (getCurrentSection()->getKind().isText()) 12102cce3712fafb2e72e144414377cd48f5ab95a5aeChris Lattner OutStreamer.EmitCodeAlignment(1 << NumBits); 12112cce3712fafb2e72e144414377cd48f5ab95a5aeChris Lattner else 12122cce3712fafb2e72e144414377cd48f5ab95a5aeChris Lattner OutStreamer.EmitValueToAlignment(1 << NumBits, 0, 1, 0); 1213bfddc2030a7e67b9e0c42276525d6932375ff261Chris Lattner} 1214a5bb59f85613e8ce481351803e7388f5ab466e72David Greene 121544e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner//===----------------------------------------------------------------------===// 121644e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner// Constant emission. 121744e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner//===----------------------------------------------------------------------===// 121844e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner 121952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner/// LowerConstant - Lower the specified LLVM Constant to an MCExpr. 122052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner/// 122152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattnerstatic const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) { 122252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner MCContext &Ctx = AP.OutContext; 1223fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 122452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (CV->isNullValue() || isa<UndefValue>(CV)) 122552492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCConstantExpr::Create(0, Ctx); 122652492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner 122752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) 122852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCConstantExpr::Create(CI->getZExtValue(), Ctx); 1229fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 123052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) 1231deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner return MCSymbolRefExpr::Create(AP.Mang->getSymbol(GV), Ctx); 123252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) 123352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCSymbolRefExpr::Create(AP.GetBlockAddressSymbol(BA), Ctx); 1234fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1235fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV); 1236fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner if (CE == 0) { 123752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner llvm_unreachable("Unknown constant value to lower!"); 123852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCConstantExpr::Create(0, Ctx); 1239fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner } 1240fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1241fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner switch (CE->getOpcode()) { 1242618f17702d09795279717827eeb06632d6ef49e4Dan Gohman default: 1243618f17702d09795279717827eeb06632d6ef49e4Dan Gohman // If the code isn't optimized, there may be outstanding folding 1244618f17702d09795279717827eeb06632d6ef49e4Dan Gohman // opportunities. Attempt to fold the expression using TargetData as a 1245618f17702d09795279717827eeb06632d6ef49e4Dan Gohman // last resort before giving up. 124654e72eca0c5d012546fcc6d1fdac7ee56c90686cDan Gohman if (Constant *C = 124754e72eca0c5d012546fcc6d1fdac7ee56c90686cDan Gohman ConstantFoldConstantExpression(CE, AP.TM.getTargetData())) 124854e72eca0c5d012546fcc6d1fdac7ee56c90686cDan Gohman if (C != CE) 124954e72eca0c5d012546fcc6d1fdac7ee56c90686cDan Gohman return LowerConstant(C, AP); 1250618f17702d09795279717827eeb06632d6ef49e4Dan Gohman#ifndef NDEBUG 1251618f17702d09795279717827eeb06632d6ef49e4Dan Gohman CE->dump(); 1252618f17702d09795279717827eeb06632d6ef49e4Dan Gohman#endif 1253618f17702d09795279717827eeb06632d6ef49e4Dan Gohman llvm_unreachable("FIXME: Don't support this constant expr"); 1254fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::GetElementPtr: { 125552492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const TargetData &TD = *AP.TM.getTargetData(); 125652492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // Generate a symbolic expression for the byte address 125752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const Constant *PtrVal = CE->getOperand(0); 125852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner SmallVector<Value*, 8> IdxVec(CE->op_begin()+1, CE->op_end()); 125952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner int64_t Offset = TD.getIndexedOffset(PtrVal->getType(), &IdxVec[0], 126052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner IdxVec.size()); 126152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner 126252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *Base = LowerConstant(CE->getOperand(0), AP); 1263fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner if (Offset == 0) 126452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return Base; 1265fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1266fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // Truncate/sext the offset to the pointer size. 126752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (TD.getPointerSizeInBits() != 64) { 126852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner int SExtAmount = 64-TD.getPointerSizeInBits(); 1269fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner Offset = (Offset << SExtAmount) >> SExtAmount; 1270a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner } 1271fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 127252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCBinaryExpr::CreateAdd(Base, MCConstantExpr::Create(Offset, Ctx), 127352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner Ctx); 1274fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner } 127552492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner 127652492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Trunc: 127752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // We emit the value and depend on the assembler to truncate the generated 127852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // expression properly. This is important for differences between 127952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // blockaddress labels. Since the two labels are in the same function, it 128052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // is reasonable to treat their delta as a 32-bit value. 128152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // FALL THROUGH. 1282fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::BitCast: 128352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return LowerConstant(CE->getOperand(0), AP); 1284fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1285fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::IntToPtr: { 128652492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const TargetData &TD = *AP.TM.getTargetData(); 1287fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // Handle casts to pointers by changing them into casts to the appropriate 1288fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // integer type. This promotes constant folding and simplifies this code. 1289fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner Constant *Op = CE->getOperand(0); 129052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner Op = ConstantExpr::getIntegerCast(Op, TD.getIntPtrType(CV->getContext()), 1291fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner false/*ZExt*/); 129252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return LowerConstant(Op, AP); 1293fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner } 1294fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1295fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::PtrToInt: { 129652492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const TargetData &TD = *AP.TM.getTargetData(); 1297fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // Support only foldable casts to/from pointers that can be eliminated by 1298fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // changing the pointer to the appropriately sized integer type. 1299fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner Constant *Op = CE->getOperand(0); 1300fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner const Type *Ty = CE->getType(); 130152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner 130252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *OpExpr = LowerConstant(Op, AP); 1303fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1304fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // We can emit the pointer value into this slot if the slot is an 130552492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // integer slot equal to the size of the pointer. 130652492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (TD.getTypeAllocSize(Ty) == TD.getTypeAllocSize(Op->getType())) 130752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return OpExpr; 130852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner 130952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // Otherwise the pointer is smaller than the resultant integer, mask off 131052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // the high bits so we are sure to get a proper truncation if the input is 131152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // a constant expr. 131252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner unsigned InBits = TD.getTypeAllocSizeInBits(Op->getType()); 131352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *MaskExpr = MCConstantExpr::Create(~0ULL >> (64-InBits), Ctx); 131452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx); 1315fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner } 1316ddc94019916fbe4d3fff915e6002c39c63488a44Chris Lattner 13175938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman // The MC library also has a right-shift operator, but it isn't consistently 13185938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman // signed or unsigned between different targets. 1319fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::Add: 1320fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::Sub: 13215938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::Mul: 13225938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::SDiv: 13235938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::SRem: 13245938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::Shl: 1325fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::And: 1326fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::Or: 132752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Xor: { 132852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *LHS = LowerConstant(CE->getOperand(0), AP); 132952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *RHS = LowerConstant(CE->getOperand(1), AP); 1330fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner switch (CE->getOpcode()) { 133152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner default: llvm_unreachable("Unknown binary operator constant cast expr"); 133252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Add: return MCBinaryExpr::CreateAdd(LHS, RHS, Ctx); 133352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Sub: return MCBinaryExpr::CreateSub(LHS, RHS, Ctx); 13345938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::Mul: return MCBinaryExpr::CreateMul(LHS, RHS, Ctx); 13355938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::SDiv: return MCBinaryExpr::CreateDiv(LHS, RHS, Ctx); 13365938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::SRem: return MCBinaryExpr::CreateMod(LHS, RHS, Ctx); 13375938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::Shl: return MCBinaryExpr::CreateShl(LHS, RHS, Ctx); 133852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::And: return MCBinaryExpr::CreateAnd(LHS, RHS, Ctx); 133952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Or: return MCBinaryExpr::CreateOr (LHS, RHS, Ctx); 134052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Xor: return MCBinaryExpr::CreateXor(LHS, RHS, Ctx); 1341a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner } 134252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner } 1343a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner } 1344a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner} 13451b7e2356ace23af872cc7d66cf45c56b10e77c4dChris Lattner 134644e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattnerstatic void EmitGlobalConstantImpl(const Constant *C, unsigned AddrSpace, 134744e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner AsmPrinter &AP); 134844e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner 134991093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattnerstatic void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace, 135091093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner AsmPrinter &AP) { 135105f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner if (AddrSpace != 0 || !CA->isString()) { 135205f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner // Not a string. Print the values in successive locations 135391093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) 135444e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP); 135505f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner return; 135600d448a341175556ebd86af68219f5b90b7145a3Dan Gohman } 135705f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner 135805f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner // Otherwise, it can be emitted as .ascii. 135905f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner SmallVector<char, 128> TmpVec; 136005f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner TmpVec.reserve(CA->getNumOperands()); 136105f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) 136205f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner TmpVec.push_back(cast<ConstantInt>(CA->getOperand(i))->getZExtValue()); 136305f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner 136405f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner AP.OutStreamer.EmitBytes(StringRef(TmpVec.data(), TmpVec.size()), AddrSpace); 136500d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 136600d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 136791093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattnerstatic void EmitGlobalConstantVector(const ConstantVector *CV, 136891093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner unsigned AddrSpace, AsmPrinter &AP) { 1369bcb83e5b6c8e074e73986cb641801ecbedd6e4edChris Lattner for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) 137044e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner EmitGlobalConstantImpl(CV->getOperand(i), AddrSpace, AP); 137100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 137200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 137391093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattnerstatic void EmitGlobalConstantStruct(const ConstantStruct *CS, 137491093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner unsigned AddrSpace, AsmPrinter &AP) { 137500d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // Print the fields in successive locations. Pad to align if needed! 137691093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner const TargetData *TD = AP.TM.getTargetData(); 137791093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner unsigned Size = TD->getTypeAllocSize(CS->getType()); 13782dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner const StructLayout *Layout = TD->getStructLayout(CS->getType()); 137991093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner uint64_t SizeSoFar = 0; 138091093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) { 1381bcb83e5b6c8e074e73986cb641801ecbedd6e4edChris Lattner const Constant *Field = CS->getOperand(i); 138200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 138300d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // Check if padding is needed and insert one or more 0s. 1384bcb83e5b6c8e074e73986cb641801ecbedd6e4edChris Lattner uint64_t FieldSize = TD->getTypeAllocSize(Field->getType()); 13852dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner uint64_t PadSize = ((i == e-1 ? Size : Layout->getElementOffset(i+1)) 13862dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner - Layout->getElementOffset(i)) - FieldSize; 13872dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner SizeSoFar += FieldSize + PadSize; 138800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 138900d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // Now print the actual field value. 139044e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner EmitGlobalConstantImpl(Field, AddrSpace, AP); 139100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 139200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // Insert padding - this may include padding to increase the size of the 139300d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // current field up to the ABI size (if the struct is not packed) as well 139400d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // as padding to ensure that the next field starts at the right offset. 13952dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitZeros(PadSize, AddrSpace); 139600d448a341175556ebd86af68219f5b90b7145a3Dan Gohman } 13972dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner assert(SizeSoFar == Layout->getSizeInBytes() && 139800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman "Layout of constant struct may be incorrect!"); 139900d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 140000d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 140193b122d3c484a8451024d6947be0f4037f86def0Chris Lattnerstatic void EmitGlobalConstantUnion(const ConstantUnion *CU, 140293b122d3c484a8451024d6947be0f4037f86def0Chris Lattner unsigned AddrSpace, AsmPrinter &AP) { 140393b122d3c484a8451024d6947be0f4037f86def0Chris Lattner const TargetData *TD = AP.TM.getTargetData(); 140493b122d3c484a8451024d6947be0f4037f86def0Chris Lattner unsigned Size = TD->getTypeAllocSize(CU->getType()); 140593b122d3c484a8451024d6947be0f4037f86def0Chris Lattner 140693b122d3c484a8451024d6947be0f4037f86def0Chris Lattner const Constant *Contents = CU->getOperand(0); 140793b122d3c484a8451024d6947be0f4037f86def0Chris Lattner unsigned FilledSize = TD->getTypeAllocSize(Contents->getType()); 140893b122d3c484a8451024d6947be0f4037f86def0Chris Lattner 140993b122d3c484a8451024d6947be0f4037f86def0Chris Lattner // Print the actually filled part 141044e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner EmitGlobalConstantImpl(Contents, AddrSpace, AP); 141193b122d3c484a8451024d6947be0f4037f86def0Chris Lattner 141293b122d3c484a8451024d6947be0f4037f86def0Chris Lattner // And pad with enough zeroes 141393b122d3c484a8451024d6947be0f4037f86def0Chris Lattner AP.OutStreamer.EmitZeros(Size-FilledSize, AddrSpace); 141493b122d3c484a8451024d6947be0f4037f86def0Chris Lattner} 141593b122d3c484a8451024d6947be0f4037f86def0Chris Lattner 14162dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattnerstatic void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace, 14172dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AsmPrinter &AP) { 141800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // FP Constants are printed as integer constants to avoid losing 14199ceff94447235a2e369d9adfdf57368f57dd3f18Chris Lattner // precision. 1420cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner if (CFP->getType()->isDoubleTy()) { 14213f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (AP.isVerbose()) { 1422d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner double Val = CFP->getValueAPF().convertToDouble(); 1423d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner AP.OutStreamer.GetCommentOS() << "double " << Val << '\n'; 142409ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner } 142509ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner 14262dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); 14272dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace); 142800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman return; 1429cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner } 1430cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner 1431cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner if (CFP->getType()->isFloatTy()) { 14323f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (AP.isVerbose()) { 14330fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner float Val = CFP->getValueAPF().convertToFloat(); 14340fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner AP.OutStreamer.GetCommentOS() << "float " << Val << '\n'; 1435a12e9d751b64767a5c41a718da2a91122d5874c4Dan Gohman } 14362dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); 14372dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(Val, 4, AddrSpace); 143800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman return; 1439cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner } 1440cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner 1441cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner if (CFP->getType()->isX86_FP80Ty()) { 144200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // all long double variants are printed as hex 1443343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // API needed to prevent premature destruction 144409ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner APInt API = CFP->getValueAPF().bitcastToAPInt(); 144509ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner const uint64_t *p = API.getRawData(); 14463f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (AP.isVerbose()) { 144772b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner // Convert to double so we can print the approximate val as a comment. 144872b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner APFloat DoubleVal = CFP->getValueAPF(); 144972b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner bool ignored; 145072b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, 145172b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner &ignored); 14520fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner AP.OutStreamer.GetCommentOS() << "x86_fp80 ~= " 14530fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner << DoubleVal.convertToDouble() << '\n'; 145472b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner } 145572b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner 14562dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner if (AP.TM.getTargetData()->isBigEndian()) { 14572dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace); 14582dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); 145972b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner } else { 14602dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); 14612dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace); 146200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman } 14639ceff94447235a2e369d9adfdf57368f57dd3f18Chris Lattner 14649ceff94447235a2e369d9adfdf57368f57dd3f18Chris Lattner // Emit the tail padding for the long double. 14652dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner const TargetData &TD = *AP.TM.getTargetData(); 14662dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitZeros(TD.getTypeAllocSize(CFP->getType()) - 14672dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner TD.getTypeStoreSize(CFP->getType()), AddrSpace); 146800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman return; 1469cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner } 1470cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner 147109ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner assert(CFP->getType()->isPPC_FP128Ty() && 147209ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner "Floating point constant type not handled"); 1473343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // All long double variants are printed as hex 1474343b42e428079363ab09828734b2debfd7dbdc9eDale Johannesen // API needed to prevent premature destruction. 147509ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner APInt API = CFP->getValueAPF().bitcastToAPInt(); 147609ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner const uint64_t *p = API.getRawData(); 14772dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner if (AP.TM.getTargetData()->isBigEndian()) { 14782dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); 14792dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace); 14809ceff94447235a2e369d9adfdf57368f57dd3f18Chris Lattner } else { 14812dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace); 14822dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); 148309ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner } 148400d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 148500d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 14862dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattnerstatic void EmitGlobalConstantLargeInt(const ConstantInt *CI, 14872dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner unsigned AddrSpace, AsmPrinter &AP) { 14882dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner const TargetData *TD = AP.TM.getTargetData(); 148900d448a341175556ebd86af68219f5b90b7145a3Dan Gohman unsigned BitWidth = CI->getBitWidth(); 149038c2b0a99c6a3f5cdf6ef5a46e4a6826b30acbfbChris Lattner assert((BitWidth & 63) == 0 && "only support multiples of 64-bits"); 149100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 149200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // We don't expect assemblers to support integer data directives 149300d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // for more than 64 bits, so we emit the data in at most 64-bit 149400d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // quantities at a time. 149500d448a341175556ebd86af68219f5b90b7145a3Dan Gohman const uint64_t *RawData = CI->getValue().getRawData(); 149600d448a341175556ebd86af68219f5b90b7145a3Dan Gohman for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) { 14972dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner uint64_t Val = TD->isBigEndian() ? RawData[e - i - 1] : RawData[i]; 14982dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace); 149900d448a341175556ebd86af68219f5b90b7145a3Dan Gohman } 150000d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 150100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 150244e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattnerstatic void EmitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace, 150344e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner AsmPrinter &AP) { 1504043c4e5c1d012c8131c7f2fa27a4def32740c42fChris Lattner if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV)) { 150544e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner uint64_t Size = AP.TM.getTargetData()->getTypeAllocSize(CV->getType()); 150644e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner return AP.OutStreamer.EmitZeros(Size, AddrSpace); 15072dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner } 15082dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner 15092dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { 151044e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner unsigned Size = AP.TM.getTargetData()->getTypeAllocSize(CV->getType()); 15112dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner switch (Size) { 15122dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner case 1: 15132dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner case 2: 15142dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner case 4: 15152dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner case 8: 151644e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner if (AP.isVerbose()) 151744e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner AP.OutStreamer.GetCommentOS() << format("0x%llx\n", CI->getZExtValue()); 151844e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner AP.OutStreamer.EmitIntValue(CI->getZExtValue(), Size, AddrSpace); 15192dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner return; 15202dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner default: 152144e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner EmitGlobalConstantLargeInt(CI, AddrSpace, AP); 15222dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner return; 15232dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner } 15242dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner } 15253cc3a00570e8263369346cf2eef9a72488326952Chris Lattner 152691093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) 152744e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner return EmitGlobalConstantArray(CVA, AddrSpace, AP); 15283cc3a00570e8263369346cf2eef9a72488326952Chris Lattner 152991093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) 153044e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner return EmitGlobalConstantStruct(CVS, AddrSpace, AP); 15313cc3a00570e8263369346cf2eef9a72488326952Chris Lattner 153291093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) 153344e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner return EmitGlobalConstantFP(CFP, AddrSpace, AP); 15341b7e2356ace23af872cc7d66cf45c56b10e77c4dChris Lattner 1535b0bedd6ebbbf0b9791291f37da5666dd456cf5b1Chris Lattner if (isa<ConstantPointerNull>(CV)) { 153644e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner unsigned Size = AP.TM.getTargetData()->getTypeAllocSize(CV->getType()); 153744e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner AP.OutStreamer.EmitIntValue(0, Size, AddrSpace); 1538b0bedd6ebbbf0b9791291f37da5666dd456cf5b1Chris Lattner return; 1539b0bedd6ebbbf0b9791291f37da5666dd456cf5b1Chris Lattner } 1540b0bedd6ebbbf0b9791291f37da5666dd456cf5b1Chris Lattner 154193b122d3c484a8451024d6947be0f4037f86def0Chris Lattner if (const ConstantUnion *CVU = dyn_cast<ConstantUnion>(CV)) 154244e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner return EmitGlobalConstantUnion(CVU, AddrSpace, AP); 154393b122d3c484a8451024d6947be0f4037f86def0Chris Lattner 154493b122d3c484a8451024d6947be0f4037f86def0Chris Lattner if (const ConstantVector *V = dyn_cast<ConstantVector>(CV)) 154544e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner return EmitGlobalConstantVector(V, AddrSpace, AP); 154693b122d3c484a8451024d6947be0f4037f86def0Chris Lattner 154752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it 154852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // thread the streamer with EmitValue. 154944e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner AP.OutStreamer.EmitValue(LowerConstant(CV, AP), 155044e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner AP.TM.getTargetData()->getTypeAllocSize(CV->getType()), 155144e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner AddrSpace); 155244e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner} 155344e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner 155444e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner/// EmitGlobalConstant - Print a general LLVM constant to the .s file. 155544e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattnervoid AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) { 155644e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType()); 155744e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner if (Size) 155844e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner EmitGlobalConstantImpl(CV, AddrSpace, *this); 155944e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner else if (MAI->hasSubsectionsViaSymbols()) { 156044e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner // If the global has zero size, emit a single byte so that two labels don't 156144e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner // look like they are at the same location. 156244e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner OutStreamer.EmitIntValue(0, 1, AddrSpace); 156344e05080f828e80e262fc00cc1fa48a8a37b7f3eChris Lattner } 15641b7e2356ace23af872cc7d66cf45c56b10e77c4dChris Lattner} 15650264d1a4777370009176157b76d116b3195e3767Chris Lattner 1566fad86b003a839cef40ec8ce8408322f4913368caChris Lattnervoid AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 1567d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng // Target doesn't support this yet! 1568c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Target does not support EmitMachineConstantPoolValue"); 1569d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng} 1570d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng 1571dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattnervoid AsmPrinter::printOffset(int64_t Offset, raw_ostream &OS) const { 1572dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner if (Offset > 0) 1573dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner OS << '+' << Offset; 1574dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner else if (Offset < 0) 1575dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner OS << Offset; 1576dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner} 1577dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner 1578c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner//===----------------------------------------------------------------------===// 1579c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner// Symbol Lowering Routines. 1580c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner//===----------------------------------------------------------------------===// 1581c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner 1582c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner/// GetTempSymbol - Return the MCSymbol corresponding to the assembler 1583c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner/// temporary label with the specified stem and unique ID. 1584c021572511f08372ae52fe8e31d3c307cab448fdChris LattnerMCSymbol *AsmPrinter::GetTempSymbol(StringRef Name, unsigned ID) const { 1585af8df264952698cfde59d99c96d4a0da9e4f5afaChris Lattner return OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + 1586c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner Name + Twine(ID)); 1587c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner} 1588c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner 1589c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner/// GetTempSymbol - Return an assembler temporary label with the specified 1590c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner/// stem. 1591c021572511f08372ae52fe8e31d3c307cab448fdChris LattnerMCSymbol *AsmPrinter::GetTempSymbol(StringRef Name) const { 1592c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner return OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix())+ 1593c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner Name); 1594c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner} 1595c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner 15966609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner 1597951755445821b92c3dc38f32b5c36e9875fa4318Chris LattnerMCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const { 15983b9d6216a41cfd43759e787db26d797e1f0ba0a8Chris Lattner return MMI->getAddrLabelSymbol(BA->getBasicBlock()); 15998c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman} 16008c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman 16013b9d6216a41cfd43759e787db26d797e1f0ba0a8Chris LattnerMCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const { 16023b9d6216a41cfd43759e787db26d797e1f0ba0a8Chris Lattner return MMI->getAddrLabelSymbol(BB); 16038c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman} 16048c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman 16053924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner/// GetCPISymbol - Return the symbol for the specified constant pool entry. 16063924868a957d5a6d468b61741cbb7db77324d1f6Chris LattnerMCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const { 16079b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol 160898cdab53c302a2d6686fa428c0e896b1fb195311Chris Lattner (Twine(MAI->getPrivateGlobalPrefix()) + "CPI" + Twine(getFunctionNumber()) 160998cdab53c302a2d6686fa428c0e896b1fb195311Chris Lattner + "_" + Twine(CPID)); 16103924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner} 16113924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner 16123924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner/// GetJTISymbol - Return the symbol for the specified jump table entry. 16133924868a957d5a6d468b61741cbb7db77324d1f6Chris LattnerMCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const { 1614589c6f620e8dcf3d59af1ae0e15372c934647c82Chris Lattner return MF->getJTISymbol(JTID, OutContext, isLinkerPrivate); 16157cb384dcca3f1ccfc993182ee4b972f7fffc8ffaChris Lattner} 16167cb384dcca3f1ccfc993182ee4b972f7fffc8ffaChris Lattner 1617798d1256595dcc0f5d4423572f856d239f7de0e6Chris Lattner/// GetJTSetSymbol - Return the symbol for the specified jump table .set 1618798d1256595dcc0f5d4423572f856d239f7de0e6Chris Lattner/// FIXME: privatize to AsmPrinter. 1619798d1256595dcc0f5d4423572f856d239f7de0e6Chris LattnerMCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const { 16209b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol 162198cdab53c302a2d6686fa428c0e896b1fb195311Chris Lattner (Twine(MAI->getPrivateGlobalPrefix()) + Twine(getFunctionNumber()) + "_" + 162298cdab53c302a2d6686fa428c0e896b1fb195311Chris Lattner Twine(UID) + "_set_" + Twine(MBBID)); 1623798d1256595dcc0f5d4423572f856d239f7de0e6Chris Lattner} 1624798d1256595dcc0f5d4423572f856d239f7de0e6Chris Lattner 16257a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner/// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with 1626d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner/// global value name as its base, with the specified suffix, and where the 16277a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner/// symbol is forced to have private linkage if ForcePrivate is true. 16287a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris LattnerMCSymbol *AsmPrinter::GetSymbolWithGlobalValueBase(const GlobalValue *GV, 16297a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner StringRef Suffix, 16307a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner bool ForcePrivate) const { 1631d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner SmallString<60> NameStr; 16327a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner Mang->getNameWithPrefix(NameStr, GV, ForcePrivate); 1633d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner NameStr.append(Suffix.begin(), Suffix.end()); 16349b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(NameStr.str()); 1635d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner} 1636d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner 16376b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner/// GetExternalSymbolSymbol - Return the MCSymbol for the specified 16386b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner/// ExternalSymbol. 16396b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris LattnerMCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) const { 16406b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner SmallString<60> NameStr; 16416b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner Mang->getNameWithPrefix(NameStr, Sym); 16426b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner return OutContext.GetOrCreateSymbol(NameStr.str()); 16436b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner} 16446b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner 16457cb384dcca3f1ccfc993182ee4b972f7fffc8ffaChris Lattner 1646523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1647523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner/// PrintParentLoopComment - Print comments about parent loops of this one. 1648523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattnerstatic void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop, 1649523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner unsigned FunctionNumber) { 1650523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner if (Loop == 0) return; 1651523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner PrintParentLoopComment(OS, Loop->getParentLoop(), FunctionNumber); 1652523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS.indent(Loop->getLoopDepth()*2) 1653523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << "Parent Loop BB" << FunctionNumber << "_" 1654523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << Loop->getHeader()->getNumber() 1655523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << " Depth=" << Loop->getLoopDepth() << '\n'; 1656523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner} 1657523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1658523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1659523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner/// PrintChildLoopComment - Print comments about child loops within 1660523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner/// the loop for this basic block, with nesting. 1661523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattnerstatic void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop, 1662523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner unsigned FunctionNumber) { 1663523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // Add child loop information 1664523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner for (MachineLoop::iterator CL = Loop->begin(), E = Loop->end();CL != E; ++CL){ 1665523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS.indent((*CL)->getLoopDepth()*2) 1666523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << "Child Loop BB" << FunctionNumber << "_" 1667523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << (*CL)->getHeader()->getNumber() << " Depth " << (*CL)->getLoopDepth() 1668523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << '\n'; 1669523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner PrintChildLoopComment(OS, *CL, FunctionNumber); 1670523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner } 1671523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner} 1672523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1673dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner/// EmitBasicBlockLoopComments - Pretty-print comments for basic blocks. 1674dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattnerstatic void EmitBasicBlockLoopComments(const MachineBasicBlock &MBB, 1675dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner const MachineLoopInfo *LI, 1676dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner const AsmPrinter &AP) { 1677523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // Add loop depth information 1678523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner const MachineLoop *Loop = LI->getLoopFor(&MBB); 1679523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner if (Loop == 0) return; 1680523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1681523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner MachineBasicBlock *Header = Loop->getHeader(); 1682523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner assert(Header && "No header for loop"); 1683523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1684523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // If this block is not a loop header, just print out what is the loop header 1685523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // and return. 1686523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner if (Header != &MBB) { 1687523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner AP.OutStreamer.AddComment(" in Loop: Header=BB" + 1688523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner Twine(AP.getFunctionNumber())+"_" + 1689523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner Twine(Loop->getHeader()->getNumber())+ 1690523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner " Depth="+Twine(Loop->getLoopDepth())); 1691523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner return; 1692523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner } 1693523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1694523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // Otherwise, it is a loop header. Print out information about child and 1695523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // parent loops. 1696523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner raw_ostream &OS = AP.OutStreamer.GetCommentOS(); 1697523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1698523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber()); 1699523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1700523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS << "=>"; 1701523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS.indent(Loop->getLoopDepth()*2-2); 1702523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1703523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS << "This "; 1704523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner if (Loop->empty()) 1705523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS << "Inner "; 1706523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n'; 1707523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1708523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner PrintChildLoopComment(OS, Loop, AP.getFunctionNumber()); 1709523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner} 1710523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1711523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 171270a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner/// EmitBasicBlockStart - This method prints the label for the specified 171370a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner/// MachineBasicBlock, an alignment (if present) and a comment describing 171470a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner/// it if appropriate. 1715662316c997e4eb8c3fdec6999b3e9da03620847aChris Lattnervoid AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const { 1716b1cac33856687715bf8db3860ff55ad2f6ca94b5Dan Gohman // Emit an alignment directive for this block, if needed. 171770a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner if (unsigned Align = MBB->getAlignment()) 171870a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner EmitAlignment(Log2_32(Align)); 1719fb8075d03f5c87bd57dcc9c5f2304f6b13c55aadEvan Cheng 1720999aee24c7b7511575146b9950bb85830fab0378Chris Lattner // If the block has its address taken, emit any labels that were used to 1721999aee24c7b7511575146b9950bb85830fab0378Chris Lattner // reference the block. It is possible that there is more than one label 1722999aee24c7b7511575146b9950bb85830fab0378Chris Lattner // here, because multiple LLVM BB's may have been RAUW'd to this block after 1723999aee24c7b7511575146b9950bb85830fab0378Chris Lattner // the references were generated. 17248c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman if (MBB->hasAddressTaken()) { 1725213168ba469703a186d060281e587d828878aa75Chris Lattner const BasicBlock *BB = MBB->getBasicBlock(); 17263f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose()) 1727999aee24c7b7511575146b9950bb85830fab0378Chris Lattner OutStreamer.AddComment("Block address taken"); 1728999aee24c7b7511575146b9950bb85830fab0378Chris Lattner 1729999aee24c7b7511575146b9950bb85830fab0378Chris Lattner std::vector<MCSymbol*> Syms = MMI->getAddrLabelSymbolToEmit(BB); 1730999aee24c7b7511575146b9950bb85830fab0378Chris Lattner 1731999aee24c7b7511575146b9950bb85830fab0378Chris Lattner for (unsigned i = 0, e = Syms.size(); i != e; ++i) 1732999aee24c7b7511575146b9950bb85830fab0378Chris Lattner OutStreamer.EmitLabel(Syms[i]); 17338c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman } 17348c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman 1735b1cac33856687715bf8db3860ff55ad2f6ca94b5Dan Gohman // Print the main label for the block. 17360a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (MBB->pred_empty() || isBlockOnlyReachableByFallthrough(MBB)) { 17373f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose() && OutStreamer.hasRawTextSupport()) { 17380fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner if (const BasicBlock *BB = MBB->getBasicBlock()) 17390fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner if (BB->hasName()) 17400fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner OutStreamer.AddComment("%" + BB->getName()); 1741d8d0aee26a5a759085bfa9114302e507c8685599Chris Lattner 1742dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner EmitBasicBlockLoopComments(*MBB, LI, *this); 174358bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner 174458bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner // NOTE: Want this comment at start of line, don't emit with AddComment. 174558bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner OutStreamer.EmitRawText(Twine(MAI->getCommentString()) + " BB#" + 174658bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner Twine(MBB->getNumber()) + ":"); 17470fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner } 1748e3cc3f3c84abfdf8eb3bd19dfa806ceea49f15d6Dan Gohman } else { 17493f53c8398d81065736a784469c9dd5afff85673fChris Lattner if (isVerbose()) { 17500fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner if (const BasicBlock *BB = MBB->getBasicBlock()) 17510fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner if (BB->hasName()) 17520fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner OutStreamer.AddComment("%" + BB->getName()); 1753dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner EmitBasicBlockLoopComments(*MBB, LI, *this); 17540fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner } 1755d8d0aee26a5a759085bfa9114302e507c8685599Chris Lattner 17561b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner OutStreamer.EmitLabel(MBB->getSymbol()); 1757e3cc3f3c84abfdf8eb3bd19dfa806ceea49f15d6Dan Gohman } 175837efe6764568a3829fee26aba532283131d1a104Nate Begeman} 175952a51e38dc312aa262b0d771419afe1785f3cb22Nate Begeman 1760be9dfcef82c58063708e039bea3cf972ba41581bChris Lattnervoid AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility) const { 1761152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner MCSymbolAttr Attr = MCSA_Invalid; 1762152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner 1763152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner switch (Visibility) { 1764152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner default: break; 1765152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner case GlobalValue::HiddenVisibility: 1766152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner Attr = MAI->getHiddenVisibilityAttr(); 1767152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner break; 1768152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner case GlobalValue::ProtectedVisibility: 1769152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner Attr = MAI->getProtectedVisibilityAttr(); 1770152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner break; 177153d4d78d9a2c26a67ac8f6e81cc149702103fc2cChris Lattner } 1772152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner 1773152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner if (Attr != MCSA_Invalid) 1774152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner OutStreamer.EmitSymbolAttribute(Sym, Attr); 177553d4d78d9a2c26a67ac8f6e81cc149702103fc2cChris Lattner} 177653d4d78d9a2c26a67ac8f6e81cc149702103fc2cChris Lattner 17770a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner/// isBlockOnlyReachableByFallthough - Return true if the basic block has 17780a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner/// exactly one predecessor and the control transfer mechanism between 17790a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner/// the predecessor and this block is a fall-through. 1780e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattnerbool AsmPrinter:: 1781e00b59f954c7e27d9d34abf90bfac969fb12f19aChris LattnerisBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { 17820a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // If this is a landing pad, it isn't a fall through. If it has no preds, 17830a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // then nothing falls through to it. 17840a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (MBB->isLandingPad() || MBB->pred_empty()) 17850a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return false; 17860a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 17870a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // If there isn't exactly one predecessor, it can't be a fall through. 17880a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; 17890a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner ++PI2; 17900a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (PI2 != MBB->pred_end()) 17910a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return false; 17920a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 17930a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // The predecessor has to be immediately before this block. 17940a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner const MachineBasicBlock *Pred = *PI; 17950a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 17960a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (!Pred->isLayoutSuccessor(MBB)) 17970a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return false; 17980a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 17990a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // If the block is completely empty, then it definitely does fall through. 18000a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (Pred->empty()) 18010a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return true; 18020a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 18030a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // Otherwise, check the last instruction. 18040a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner const MachineInstr &LastInst = Pred->back(); 18050a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return !LastInst.getDesc().isBarrier(); 18060a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner} 18070a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 18080a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 18090a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 18105eca075b74d62c621b160aa216b4cd50829a2cc7Gordon HenriksenGCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) { 18115eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen if (!S->usesMetadata()) 1812c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen return 0; 1813e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner 1814e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner gcp_map_type &GCMap = getGCMap(GCMetadataPrinters); 1815e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner gcp_map_type::iterator GCPI = GCMap.find(S); 1816e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner if (GCPI != GCMap.end()) 1817c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen return GCPI->second; 1818c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen 18195eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen const char *Name = S->getName().c_str(); 1820c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen 1821c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen for (GCMetadataPrinterRegistry::iterator 1822c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen I = GCMetadataPrinterRegistry::begin(), 1823c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen E = GCMetadataPrinterRegistry::end(); I != E; ++I) 1824c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen if (strcmp(Name, I->getName()) == 0) { 18255eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen GCMetadataPrinter *GMP = I->instantiate(); 18265eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen GMP->S = S; 1827e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner GCMap.insert(std::make_pair(S, GMP)); 18285eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen return GMP; 1829c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen } 1830c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen 183175361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name)); 183252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return 0; 1833c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen} 1834014700c1a8cba203fd21ff129426ba8a426ab244David Greene 1835