AsmPrinter.cpp revision dfa107e45ac6a145c03376ecc0530d8ece358238
1a80ba71efe5be5012128e2db0dd29b024e00105aChris 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" 16246ae0dcf750401ee84e1319ebe0b790744097a5Evan Cheng#include "llvm/Assembly/Writer.h" 178cfa57b1b4eade4e0101195b2f94ab288cd03563Nate Begeman#include "llvm/DerivedTypes.h" 18a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner#include "llvm/Constants.h" 19450de393acdf4be89db8558522b04d8111e4562bChris Lattner#include "llvm/Module.h" 2045111d160cf0910030eeb6a949c69273502e5ad5Chris Lattner#include "llvm/CodeGen/DwarfWriter.h" 215eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen#include "llvm/CodeGen/GCMetadataPrinter.h" 223b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner#include "llvm/CodeGen/MachineConstantPool.h" 231924aabf996be9335fab34e7ee4fa2aa5911389cDavid Greene#include "llvm/CodeGen/MachineFrameInfo.h" 24fe37ab335be5632eab561d49984c95cb06b946d4David Greene#include "llvm/CodeGen/MachineFunction.h" 2537efe6764568a3829fee26aba532283131d1a104Nate Begeman#include "llvm/CodeGen/MachineJumpTableInfo.h" 26b71d1b2fe2c0673005283b48be2f37c750ce367bDavid Greene#include "llvm/CodeGen/MachineLoopInfo.h" 2784bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner#include "llvm/CodeGen/MachineModuleInfo.h" 28618f17702d09795279717827eeb06632d6ef49e4Dan Gohman#include "llvm/Analysis/ConstantFolding.h" 29cd76240f3d0f6c5f8c80e4762a8fe3a4de22e059Argyrios Kyrtzidis#include "llvm/Analysis/DebugInfo.h" 302b2954f00ba02ca1a902f47080cd9f06aebc0378Chris Lattner#include "llvm/MC/MCContext.h" 3152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner#include "llvm/MC/MCExpr.h" 323ac1ab835caacdeebbd0d7b4d69160f283928d21David Greene#include "llvm/MC/MCInst.h" 33a87dea4f8c546ca748f1777a8d1cabcc06515d91Chris Lattner#include "llvm/MC/MCSection.h" 34a87dea4f8c546ca748f1777a8d1cabcc06515d91Chris Lattner#include "llvm/MC/MCStreamer.h" 357cb384dcca3f1ccfc993182ee4b972f7fffc8ffaChris Lattner#include "llvm/MC/MCSymbol.h" 36af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner#include "llvm/MC/MCAsmInfo.h" 3745111d160cf0910030eeb6a949c69273502e5ad5Chris Lattner#include "llvm/Target/Mangler.h" 3807000c6f01d8f57170f2d4c77a86d934bdc5c696Owen Anderson#include "llvm/Target/TargetData.h" 391924aabf996be9335fab34e7ee4fa2aa5911389cDavid Greene#include "llvm/Target/TargetInstrInfo.h" 400336fdba858830d515bf53ac29b8e5ff24dfa823Chris Lattner#include "llvm/Target/TargetLowering.h" 41f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner#include "llvm/Target/TargetLoweringObjectFile.h" 426547e406cf934346db7a206b61bcf09635afff0dEvan Cheng#include "llvm/Target/TargetOptions.h" 43da47e6e0d003c873da960361549e57ee4617c301Evan Cheng#include "llvm/Target/TargetRegisterInfo.h" 44cc41586b9d79532172b37e1f44a9077da4b73fc9Evan Cheng#include "llvm/ADT/SmallPtrSet.h" 45fad86b003a839cef40ec8ce8408322f4913368caChris Lattner#include "llvm/ADT/SmallString.h" 4614c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner#include "llvm/ADT/Statistic.h" 4714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner#include "llvm/Support/CommandLine.h" 4814c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner#include "llvm/Support/Debug.h" 4914c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner#include "llvm/Support/ErrorHandling.h" 5014c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner#include "llvm/Support/Format.h" 516609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner#include <cerrno> 52a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattnerusing namespace llvm; 53a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner 5414c38ec2afeaf25c53a50c2c65116aca8c889401Chris LattnerSTATISTIC(EmittedInsts, "Number of machine instrs printed"); 5514c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 561997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patelchar AsmPrinter::ID = 0; 5711d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner 58e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattnertypedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type; 59e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattnerstatic gcp_map_type &getGCMap(void *&P) { 60e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner if (P == 0) 61e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner P = new gcp_map_type(); 62e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner return *(gcp_map_type*)P; 63e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner} 64e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner 65e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner 66b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris LattnerAsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer) 67e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner : MachineFunctionPass(&ID), 689d1c1ada213c80135fbdda704175aae689daa6f9Chris Lattner TM(tm), MAI(tm.getMCAsmInfo()), 6911d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner OutContext(Streamer.getContext()), 7011d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner OutStreamer(Streamer), 71553881bddcdeb66c0ae06bf9f62ca63b9f29b2e8Devang Patel LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) { 720de1fc4f416b3e94749ca84cdaede55b040a8b60Chris Lattner DW = 0; MMI = 0; 73e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner GCMetadataPrinters = 0; 7456591ab218639d8a6e4c756ca37adaf20215c3b6Chris Lattner VerboseAsm = Streamer.isVerboseAsm(); 7542bf74be1402df7409efbea089310d4c276fde37Evan Cheng} 76ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 77c317a60c2714a5b90700a11ba646285cb754a5d3Gordon HenriksenAsmPrinter::~AsmPrinter() { 78e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner if (GCMetadataPrinters != 0) { 79e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner gcp_map_type &GCMap = getGCMap(GCMetadataPrinters); 80e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner 81e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner for (gcp_map_type::iterator I = GCMap.begin(), E = GCMap.end(); I != E; ++I) 82e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner delete I->second; 83e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner delete &GCMap; 84e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner GCMetadataPrinters = 0; 85e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner } 862b2954f00ba02ca1a902f47080cd9f06aebc0378Chris Lattner 872b2954f00ba02ca1a902f47080cd9f06aebc0378Chris Lattner delete &OutStreamer; 88c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen} 89ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 90b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner/// getFunctionNumber - Return a unique ID for the current function. 91b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner/// 92b84822fb7b64977c16e97b870891da1d6c9736feChris Lattnerunsigned AsmPrinter::getFunctionNumber() const { 93b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner return MF->getFunctionNumber(); 94b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner} 95b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner 9638c398808cff7defdf013fa750dfac8e66302975Chris LattnerTargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const { 97f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner return TM.getTargetLowering()->getObjFileLowering(); 98f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner} 99f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner 100dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattner/// getCurrentSection() - Return the current section we are emitting to. 101dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattnerconst MCSection *AsmPrinter::getCurrentSection() const { 102dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattner return OutStreamer.getCurrentSection(); 103b5a32e2e8ce2f3de3a340c5a2dfcd3a159968466Anton Korobeynikov} 1044632d7a57008564c4b0f8246e85bd813a200d2c6Chris Lattner 105dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattner 106ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksenvoid AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const { 107845012e6d31799c7fbd1193fa1af8ee2d12e9231Dan Gohman AU.setPreservesAll(); 108ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksen MachineFunctionPass::getAnalysisUsage(AU); 10911d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner AU.addRequired<MachineModuleInfo>(); 1105eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen AU.addRequired<GCModuleInfo>(); 111fe37ab335be5632eab561d49984c95cb06b946d4David Greene if (VerboseAsm) 112b71d1b2fe2c0673005283b48be2f37c750ce367bDavid Greene AU.addRequired<MachineLoopInfo>(); 113ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksen} 114ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksen 115a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattnerbool AsmPrinter::doInitialization(Module &M) { 116d32c8a561734e05ff78da4435de0e85e0eed88e1Chris Lattner MMI = getAnalysisIfAvailable<MachineModuleInfo>(); 11711d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner MMI->AnalyzeModule(M); 11811d53c129fc9c2a4510605ec0a1696f58750af52Chris Lattner 119f26e03bc7e30162197641406e37e662a15d80f7eChris Lattner // Initialize TargetLoweringObjectFile. 120f26e03bc7e30162197641406e37e662a15d80f7eChris Lattner const_cast<TargetLoweringObjectFile&>(getObjFileLowering()) 121f26e03bc7e30162197641406e37e662a15d80f7eChris Lattner .Initialize(OutContext, TM); 122f26e03bc7e30162197641406e37e662a15d80f7eChris Lattner 123b87c305fa77650ee581d4a8c65a0757f88002441Chris Lattner Mang = new Mangler(OutContext, *TM.getTargetData()); 1242c1b1597f244c836771b4f2668c0ae399d32a5e9Chris Lattner 125812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson // Allow the target to emit any magic that it wants at the start of the file. 126812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson EmitStartOfAsmFile(M); 127952b839ce9bc0c6d605d8b202c9cd76f7f05a77dRafael Espindola 128a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner // Very minimal debug info. It is ignored if we emit actual debug info. If we 129a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner // don't, this at least helps the user find where a global came from. 13033adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->hasSingleParameterDotFile()) { 131a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner // .file "foo.c" 132a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner OutStreamer.EmitFileDirective(M.getModuleIdentifier()); 133952b839ce9bc0c6d605d8b202c9cd76f7f05a77dRafael Espindola } 134952b839ce9bc0c6d605d8b202c9cd76f7f05a77dRafael Espindola 135812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); 136812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson assert(MI && "AsmPrinter didn't require GCModuleInfo?"); 1375eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I) 1385eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I)) 1397d73c7f0d618dd6661cd55834c58aa62f22b28feChris Lattner MP->beginAssembly(*this); 14091bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner 14191bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner // Emit module-level inline asm if it exists. 14247b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner if (!M.getModuleInlineAsm().empty()) { 14347b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner OutStreamer.AddComment("Start of file scope inline assembly"); 14447b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner OutStreamer.AddBlankLine(); 14591bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner EmitInlineAsm(M.getModuleInlineAsm()); 14647b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner OutStreamer.AddComment("End of file scope inline assembly"); 14747b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner OutStreamer.AddBlankLine(); 14847b7e5dae911bc98aa76fa5d2ee506c9304f941aChris Lattner } 1492c1b1597f244c836771b4f2668c0ae399d32a5e9Chris Lattner 150b55e068e53fccc609b7d9cd198ed9818c188a196Chris Lattner DW = getAnalysisIfAvailable<DwarfWriter>(); 1519a501cf19dbf1f56f0782ddba4c1931565af9610Sanjiv Gupta if (DW) 15275f50725c1d7f86ee545337b155b4feac66627f6Chris Lattner DW->BeginModule(&M, this); 15314a55d952cf238fff42da53a75f39cf06dab184bDevang Patel 154a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner return false; 155a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner} 156a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner 157be9dfcef82c58063708e039bea3cf972ba41581bChris Lattnervoid AsmPrinter::EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const { 158a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner switch ((GlobalValue::LinkageTypes)Linkage) { 159a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::CommonLinkage: 160a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::LinkOnceAnyLinkage: 161a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::LinkOnceODRLinkage: 162a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::WeakAnyLinkage: 163a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::WeakODRLinkage: 164a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::LinkerPrivateLinkage: 165a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner if (MAI->getWeakDefDirective() != 0) { 166a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .globl _foo 167a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); 168a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .weak_definition _foo 169a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefinition); 170a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner } else if (const char *LinkOnce = MAI->getLinkOnceDirective()) { 171a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .globl _foo 172a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); 173a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // FIXME: linkonce should be a section attribute, handled by COFF Section 174a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // assignment. 175a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // http://sourceware.org/binutils/docs-2.20/as/Linkonce.html#Linkonce 176111a3193b5e25f8765221f2e94fba888155fe4ebChris Lattner // .linkonce discard 177111a3193b5e25f8765221f2e94fba888155fe4ebChris Lattner // FIXME: It would be nice to use .linkonce samesize for non-common 178111a3193b5e25f8765221f2e94fba888155fe4ebChris Lattner // globals. 179fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner OutStreamer.EmitRawText(StringRef(LinkOnce)); 180a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner } else { 181a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .weak _foo 182a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak); 183a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner } 184a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner break; 185a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::DLLExportLinkage: 186a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::AppendingLinkage: 187a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // FIXME: appending linkage variables should go into a section of 188a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // their name or something. For now, just emit them as external. 189a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::ExternalLinkage: 190a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // If external or appending, declare as a global symbol. 191a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner // .globl _foo 192a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); 193a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner break; 194a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::PrivateLinkage: 195a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner case GlobalValue::InternalLinkage: 196a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner break; 197a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner default: 198a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner llvm_unreachable("Unknown linkage type!"); 199a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner } 200a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner} 201a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner 202a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner 20348d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner/// EmitGlobalVariable - Emit the specified global variable to the .s file. 20448d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattnervoid AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { 20548d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner if (!GV->hasInitializer()) // External globals require no code. 20648d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner return; 20748d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner 20848d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner // Check to see if this is a special global used by LLVM, if so, emit it. 20948d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner if (EmitSpecialLLVMGlobal(GV)) 21048d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner return; 21174bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 212deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner MCSymbol *GVSym = Mang->getSymbol(GV); 213be9dfcef82c58063708e039bea3cf972ba41581bChris Lattner EmitVisibility(GVSym, GV->getVisibility()); 21474bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 215a800f7c464ef9a376057a555129f36d1f8488c3bChris Lattner if (MAI->hasDotTypeDotSizeDirective()) 216a800f7c464ef9a376057a555129f36d1f8488c3bChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject); 21774bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 21874bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM); 21974bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 22074bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner const TargetData *TD = TM.getTargetData(); 22174bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner unsigned Size = TD->getTypeAllocSize(GV->getType()->getElementType()); 22274bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner unsigned AlignLog = TD->getPreferredAlignmentLog(GV); 22374bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 2249744d611d7c7c1fb51c50c4e94901e4e9a905116Chris Lattner // Handle common and BSS local symbols (.lcomm). 2259744d611d7c7c1fb51c50c4e94901e4e9a905116Chris Lattner if (GVKind.isCommon() || GVKind.isBSSLocal()) { 22674bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. 22774bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 22874bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner if (VerboseAsm) { 2290fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner WriteAsOperand(OutStreamer.GetCommentOS(), GV, 2300fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner /*PrintType=*/false, GV->getParent()); 2310fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner OutStreamer.GetCommentOS() << '\n'; 23274bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner } 233814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner 234814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // Handle common symbols. 2359744d611d7c7c1fb51c50c4e94901e4e9a905116Chris Lattner if (GVKind.isCommon()) { 2369744d611d7c7c1fb51c50c4e94901e4e9a905116Chris Lattner // .comm _foo, 42, 4 2374ed5438f4882c9fe779b1a8ff546877889b222dfChris Lattner OutStreamer.EmitCommonSymbol(GVSym, Size, 1 << AlignLog); 238814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner return; 239814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner } 240814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner 241814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // Handle local BSS symbols. 242814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner if (MAI->hasMachoZeroFillDirective()) { 243814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner const MCSection *TheSection = 244814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM); 245814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // .zerofill __DATA, __bss, _foo, 400, 5 246814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog); 247814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner return; 248814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner } 249814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner 2509eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner if (MAI->hasLCOMMDirective()) { 251814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // .lcomm _foo, 42 2529eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner OutStreamer.EmitLocalCommonSymbol(GVSym, Size); 253814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner return; 25474bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner } 255814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner 256814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // .local _foo 257a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Local); 258814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner // .comm _foo, 42, 4 259814819f6ea7fb0638fe73920299fda0da941a59eChris Lattner OutStreamer.EmitCommonSymbol(GVSym, Size, 1 << AlignLog); 26074bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner return; 26174bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner } 26248d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner 26374bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner const MCSection *TheSection = 26474bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM); 26574bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 26674bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner // Handle the zerofill directive on darwin, which is a special form of BSS 26774bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner // emission. 26874bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) { 26974bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner // .globl _foo 270a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); 27174bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner // .zerofill __DATA, __common, _foo, 400, 5 27274bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog); 27374bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner return; 27474bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner } 27574bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 27674bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner OutStreamer.SwitchSection(TheSection); 27774bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 278a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner EmitLinkage(GV->getLinkage(), GVSym); 27974bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner EmitAlignment(AlignLog, GV); 280a3e8883d710c435d640d65e52f0c6dcce21cad5bChris Lattner 28174bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner if (VerboseAsm) { 2820fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner WriteAsOperand(OutStreamer.GetCommentOS(), GV, 2830fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner /*PrintType=*/false, GV->getParent()); 2840fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner OutStreamer.GetCommentOS() << '\n'; 28574bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner } 2864c8c668b57f74e2849ba198c3abfc97899e8072bChris Lattner OutStreamer.EmitLabel(GVSym); 28774bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 28874bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner EmitGlobalConstant(GV->getInitializer()); 28974bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner 29074bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner if (MAI->hasDotTypeDotSizeDirective()) 2911947f242d40227d36440a2702a0a612c8077d72eChris Lattner // .size foo, 42 29299328add833807f12a4950c7de29fb2a5df04703Chris Lattner OutStreamer.EmitELFSize(GVSym, MCConstantExpr::Create(Size, OutContext)); 2930fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner 2940fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner OutStreamer.AddBlankLine(); 29548d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner} 29648d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner 297b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner/// EmitFunctionHeader - This method emits the header for the current 298b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner/// function. 299b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattnervoid AsmPrinter::EmitFunctionHeader() { 300b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner // Print out constants referenced by the function 301a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner EmitConstantPool(); 302b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 303b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner // Print the 'header' of function. 304b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner const Function *F = MF->getFunction(); 305b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 306b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM)); 307be9dfcef82c58063708e039bea3cf972ba41581bChris Lattner EmitVisibility(CurrentFnSym, F->getVisibility()); 308b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 309111a3193b5e25f8765221f2e94fba888155fe4ebChris Lattner EmitLinkage(F->getLinkage(), CurrentFnSym); 310b406a8141d704bca7a8eade3a0c46d7ec73affc8Chris Lattner EmitAlignment(MF->getAlignment(), F); 311b406a8141d704bca7a8eade3a0c46d7ec73affc8Chris Lattner 312b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner if (MAI->hasDotTypeDotSizeDirective()) 313b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction); 314b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 315b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner if (VerboseAsm) { 3169bc20ab519d47146a9716d7cff2a892da78774a6Chris Lattner WriteAsOperand(OutStreamer.GetCommentOS(), F, 3179bc20ab519d47146a9716d7cff2a892da78774a6Chris Lattner /*PrintType=*/false, F->getParent()); 3189bc20ab519d47146a9716d7cff2a892da78774a6Chris Lattner OutStreamer.GetCommentOS() << '\n'; 319b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner } 320b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 321f451cb870efcf9e0302d25ed05f4cac6bb494e42Dan Gohman // Emit the CurrentFnSym. This is a virtual function to allow targets to 3222cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner // do their wild and crazy things as required. 3232cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner EmitFunctionEntryLabel(); 3242cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner 3259cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner // If the function had address-taken blocks that got deleted, then we have 3269cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner // references to the dangling symbols. Emit them at the start of the function 3279cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner // so that we don't get references to undefined symbols. 3289cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner std::vector<MCSymbol*> DeadBlockSyms; 3299cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner MMI->takeDeletedSymbolsForFunction(F, DeadBlockSyms); 3309cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner for (unsigned i = 0, e = DeadBlockSyms.size(); i != e; ++i) { 3319cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner OutStreamer.AddComment("Address taken block that was later removed"); 3329cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner OutStreamer.EmitLabel(DeadBlockSyms[i]); 3339cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner } 3349cc0da9c29302e9463a6f31ba705c8e1b6f4cea1Chris Lattner 335b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner // Add some workaround for linkonce linkage on Cygwin\MinGW. 336b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner if (MAI->getLinkOnceDirective() != 0 && 337fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner (F->hasLinkOnceLinkage() || F->hasWeakLinkage())) { 3389bc20ab519d47146a9716d7cff2a892da78774a6Chris Lattner // FIXME: What is this? 339fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner MCSymbol *FakeStub = 340fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner OutContext.GetOrCreateSymbol(Twine("Lllvm$workaround$fake$stub$")+ 341fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner CurrentFnSym->getName()); 342fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner OutStreamer.EmitLabel(FakeStub); 343fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner } 344b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 345b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner // Emit pre-function debug and/or EH information. 346b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling()) 347b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner DW->BeginFunction(MF); 348b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner} 349b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 3502cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the 3512cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner/// function. This can be overridden by targets as required to do custom stuff. 3522cf7251d39f28888af06b6f941eabd1d10995382Chris Lattnervoid AsmPrinter::EmitFunctionEntryLabel() { 3532cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner OutStreamer.EmitLabel(CurrentFnSym); 3542cf7251d39f28888af06b6f941eabd1d10995382Chris Lattner} 355b11caedd6f36afc6518cf0ea9bbff6500fd77334Chris Lattner 35648d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner 35747529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner/// EmitComments - Pretty-print comments for instructions. 35847529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattnerstatic void EmitComments(const MachineInstr &MI, raw_ostream &CommentOS) { 35947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner const MachineFunction *MF = MI.getParent()->getParent(); 36047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner const TargetMachine &TM = MF->getTarget(); 36147529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 362de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner DebugLoc DL = MI.getDebugLoc(); 363de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner if (!DL.isUnknown()) { // Print source line info. 364de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner DIScope Scope(DL.getScope(MF->getFunction()->getContext())); 36547529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // Omit the directory, because it's likely to be long and uninteresting. 3663c91b05d2b1751b9e4e21fd958d358ec463dcd3cDevang Patel if (Scope.Verify()) 36747529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << Scope.getFilename(); 36847529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner else 36947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << "<unknown>"; 370de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner CommentOS << ':' << DL.getLine(); 371de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner if (DL.getCol() != 0) 372de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner CommentOS << ':' << DL.getCol(); 37347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << '\n'; 37447529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } 37547529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 37647529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // Check for spills and reloads 37747529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner int FI; 37847529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 37947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner const MachineFrameInfo *FrameInfo = MF->getFrameInfo(); 38047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 38147529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // We assume a single instruction only has a spill or reload, not 38247529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // both. 38347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner const MachineMemOperand *MMO; 38447529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (TM.getInstrInfo()->isLoadFromStackSlotPostFE(&MI, FI)) { 38547529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (FrameInfo->isSpillSlotObjectIndex(FI)) { 38647529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner MMO = *MI.memoperands_begin(); 38747529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << MMO->getSize() << "-byte Reload\n"; 38847529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } 38947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } else if (TM.getInstrInfo()->hasLoadFromStackSlot(&MI, MMO, FI)) { 39047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (FrameInfo->isSpillSlotObjectIndex(FI)) 39147529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << MMO->getSize() << "-byte Folded Reload\n"; 39247529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } else if (TM.getInstrInfo()->isStoreToStackSlotPostFE(&MI, FI)) { 39347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (FrameInfo->isSpillSlotObjectIndex(FI)) { 39447529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner MMO = *MI.memoperands_begin(); 39547529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << MMO->getSize() << "-byte Spill\n"; 39647529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } 39747529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } else if (TM.getInstrInfo()->hasStoreToStackSlot(&MI, MMO, FI)) { 39847529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (FrameInfo->isSpillSlotObjectIndex(FI)) 39947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << MMO->getSize() << "-byte Folded Spill\n"; 40047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } 40147529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 40247529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner // Check for spill-induced copies 40347529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; 40447529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (TM.getInstrInfo()->isMoveInstr(MI, SrcReg, DstReg, 40547529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner SrcSubIdx, DstSubIdx)) { 40645282aedb9c5a33d20565502c6c8fc871fa84cbeChris Lattner if (MI.getAsmPrinterFlag(MachineInstr::ReloadReuse)) 40747529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner CommentOS << " Reload Reuse\n"; 40847529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner } 40947529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner} 41047529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 41147529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 41247529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 41314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner/// EmitFunctionBody - This method emits the body and trailer for a 41414c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner/// function. 41514c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattnervoid AsmPrinter::EmitFunctionBody() { 416edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner // Emit target-specific gunk before the function body. 417edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner EmitFunctionBodyStart(); 418edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner 41914c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Print out code for the function. 42014c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner bool HasAnyRealCode = false; 42114c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); 42214c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner I != E; ++I) { 42314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Print a label for the basic block. 42414c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner EmitBasicBlockStart(I); 42514c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); 42614c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner II != IE; ++II) { 42714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Print the assembly for the instruction. 42814c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner if (!II->isLabel()) 42914c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner HasAnyRealCode = true; 43014c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 43114c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner ++EmittedInsts; 43214c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 43314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // FIXME: Clean up processDebugLoc. 43414c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner processDebugLoc(II, true); 43514c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 43647529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner if (VerboseAsm) 43747529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner EmitComments(*II, OutStreamer.GetCommentOS()); 43847529c9ac6d4731e9f5a1b2d3c64769b1b2d5f1dChris Lattner 4390d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner switch (II->getOpcode()) { 440518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::DBG_LABEL: 441518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::EH_LABEL: 442518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::GC_LABEL: 443300a4c5640fb1c717ba0d7108d15aec1bd7eb396Chris Lattner OutStreamer.EmitLabel(II->getOperand(0).getMCSymbol()); 4440d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 445518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::INLINEASM: 446300a4c5640fb1c717ba0d7108d15aec1bd7eb396Chris Lattner EmitInlineAsm(II); 4470d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 448518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::IMPLICIT_DEF: 449300a4c5640fb1c717ba0d7108d15aec1bd7eb396Chris Lattner EmitImplicitDef(II); 4500d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 451518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner case TargetOpcode::KILL: 452300a4c5640fb1c717ba0d7108d15aec1bd7eb396Chris Lattner EmitKill(II); 4530d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 4540d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner default: 4550d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner EmitInstruction(II); 4560d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner break; 4570d883e3f8484491d010b8f8b7a1aecc58cb5fa8eChris Lattner } 45814c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 45914c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // FIXME: Clean up processDebugLoc. 46014c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner processDebugLoc(II, false); 46114c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner } 46214c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner } 46314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 46414c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // If the function is empty and the object file uses .subsections_via_symbols, 465d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner // then we need to emit *something* to the function body to prevent the 466d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner // labels from collapsing together. Just emit a 0 byte. 46710e7c60c0444a766c256f6c7c922e43963590a5cChris Lattner if (MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode) 46810e7c60c0444a766c256f6c7c922e43963590a5cChris Lattner OutStreamer.EmitIntValue(0, 1, 0/*addrspace*/); 46914c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 470edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner // Emit target-specific gunk after the function body. 471edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner EmitFunctionBodyEnd(); 472edfe776ac29d9fd48ae8967f6742400aad65e39cChris Lattner 473fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner // If the target wants a .size directive for the size of the function, emit 474fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner // it. 475fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner if (MAI->hasDotTypeDotSizeDirective()) { 4760c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner // Create a symbol for the end of function, so we can get the size as 4770c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner // difference between the function label and the temp label. 4780c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner MCSymbol *FnEndLabel = OutContext.CreateTempSymbol(); 4790c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner OutStreamer.EmitLabel(FnEndLabel); 4800c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner 4810c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner const MCExpr *SizeExp = 4820c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(FnEndLabel, OutContext), 4830c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner MCSymbolRefExpr::Create(CurrentFnSym, OutContext), 4840c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner OutContext); 4850c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner OutStreamer.EmitELFSize(CurrentFnSym, SizeExp); 486fd60b8b4842c04e272a5cbdd404ed88d63d6df61Chris Lattner } 48714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 48814c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Emit post-function debug information. 48914c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling()) 49014c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner DW->EndFunction(MF); 49114c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 49214c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner // Print out jump tables referenced by the function. 49314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner EmitJumpTableInfo(); 494d26a80f666fb925956a4f19143265f5150756df0Chris Lattner 495d26a80f666fb925956a4f19143265f5150756df0Chris Lattner OutStreamer.AddBlankLine(); 49614c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner} 49714c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 49814c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner 499a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattnerbool AsmPrinter::doFinalization(Module &M) { 50040bbebde9d250b875a47a688d0c6552834ada48fChris Lattner // Emit global variables. 50140bbebde9d250b875a47a688d0c6552834ada48fChris Lattner for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 50240bbebde9d250b875a47a688d0c6552834ada48fChris Lattner I != E; ++I) 50348d64ba9d846229339b2431b298620cb8a01ffc5Chris Lattner EmitGlobalVariable(I); 50440bbebde9d250b875a47a688d0c6552834ada48fChris Lattner 5051f522feabf25134249bc7894e04f5b89fa071b7fChris Lattner // Emit final debug information. 50633adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling()) 5071f522feabf25134249bc7894e04f5b89fa071b7fChris Lattner DW->EndModule(); 5081f522feabf25134249bc7894e04f5b89fa071b7fChris Lattner 5090a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // If the target wants to know about weak references, print them all. 51033adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->getWeakRefDirective()) { 5110a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // FIXME: This is not lazy, it would be nice to only print weak references 5120a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // to stuff that is actually used. Note that doing so would require targets 5130a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // to notice uses in operands (due to constant exprs etc). This should 5140a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // happen with the MC stuff eventually. 5150a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner 5160a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner // Print out module-level global variables here. 5170a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 5180a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner I != E; ++I) { 51908ce3b473d06e0f7806df3d44b7b36ac40c58803Chris Lattner if (!I->hasExternalWeakLinkage()) continue; 520deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference); 5210a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner } 5220a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner 523c6fdced3dbfdf673cc9b01dfad4f08e316d8803dChris Lattner for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) { 52408ce3b473d06e0f7806df3d44b7b36ac40c58803Chris Lattner if (!I->hasExternalWeakLinkage()) continue; 525deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference); 5260a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner } 52715404d060ba8b604c03b9223a0f2e2abcd0fddedRafael Espindola } 52815404d060ba8b604c03b9223a0f2e2abcd0fddedRafael Espindola 529cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner if (MAI->hasSetDirective()) { 5303a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner OutStreamer.AddBlankLine(); 5318b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); 5320a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner I != E; ++I) { 533deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner MCSymbol *Name = Mang->getSymbol(I); 534325be7c608a37d87e4f3d731e11fa3dd34f529b5Anton Korobeynikov 535325be7c608a37d87e4f3d731e11fa3dd34f529b5Anton Korobeynikov const GlobalValue *GV = cast<GlobalValue>(I->getAliasedGlobal()); 536deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner MCSymbol *Target = Mang->getSymbol(GV); 5375c40e694dcd679bf26b962189c1d12b32fff07cdChris Lattner 53810b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner if (I->hasExternalLinkage() || !MAI->getWeakRefDirective()) 539a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitSymbolAttribute(Name, MCSA_Global); 54010b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner else if (I->hasWeakLinkage()) 541a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitSymbolAttribute(Name, MCSA_WeakReference); 54210b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner else 54310595490ccf25b4960936638fac7a673eaf82e68Chris Lattner assert(I->hasLocalLinkage() && "Invalid alias linkage"); 54422c9e65643e0c6b43be37a19e59491ef0081092cAnton Korobeynikov 545be9dfcef82c58063708e039bea3cf972ba41581bChris Lattner EmitVisibility(Name, I->getVisibility()); 54622c9e65643e0c6b43be37a19e59491ef0081092cAnton Korobeynikov 547c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner // Emit the directives as assignments aka .set: 548c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner OutStreamer.EmitAssignment(Name, 549c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner MCSymbolRefExpr::Create(Target, OutContext)); 5508b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov } 5518b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov } 5528b0a8c84da2030ee8f4440d5b60a8033de691222Anton Korobeynikov 5531465d61bdd36cfd6021036a527895f0dd358e97dDuncan Sands GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); 5545eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen assert(MI && "AsmPrinter didn't require GCModuleInfo?"); 5555eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; ) 5565eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I)) 5577d73c7f0d618dd6661cd55834c58aa62f22b28feChris Lattner MP->finishAssembly(*this); 558ce2247755e56f99a2377b64a1a9d393726582b85Gordon Henriksen 559a779a9899a5e23bd5198973f4709d66cb4bc2e64Dan Gohman // If we don't have any trampolines, then we don't require stack memory 560a779a9899a5e23bd5198973f4709d66cb4bc2e64Dan Gohman // to be executable. Some targets have a directive to declare this. 5610a7befa8bd56621f51eaf9196417b866962bf7b1Chris Lattner Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline"); 562a779a9899a5e23bd5198973f4709d66cb4bc2e64Dan Gohman if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty()) 563f9f93e4388962b678fd59b7af5212d4cc0d38be2Chris Lattner if (MCSection *S = MAI->getNonexecutableStackSection(OutContext)) 564f9f93e4388962b678fd59b7af5212d4cc0d38be2Chris Lattner OutStreamer.SwitchSection(S); 565bd23d5fda85e38c88dfa668a99777cd05c524822Chris Lattner 566bd23d5fda85e38c88dfa668a99777cd05c524822Chris Lattner // Allow the target to emit any magic that it wants at the end of the file, 567bd23d5fda85e38c88dfa668a99777cd05c524822Chris Lattner // after everything else has gone out. 568bd23d5fda85e38c88dfa668a99777cd05c524822Chris Lattner EmitEndOfAsmFile(M); 569bd23d5fda85e38c88dfa668a99777cd05c524822Chris Lattner 570a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner delete Mang; Mang = 0; 5710de1fc4f416b3e94749ca84cdaede55b040a8b60Chris Lattner DW = 0; MMI = 0; 5722b2954f00ba02ca1a902f47080cd9f06aebc0378Chris Lattner 5732b2954f00ba02ca1a902f47080cd9f06aebc0378Chris Lattner OutStreamer.Finish(); 574a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner return false; 575a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner} 576a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner 57725045bdcda822d63674e2df7e34016536c5d3fa7Chris Lattnervoid AsmPrinter::SetupMachineFunction(MachineFunction &MF) { 578b84822fb7b64977c16e97b870891da1d6c9736feChris Lattner this->MF = &MF; 579412c3a5bc9e70fe8579551216786e70d323a3dd5Chris Lattner // Get the function symbol. 580deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner CurrentFnSym = Mang->getSymbol(MF.getFunction()); 581b71d1b2fe2c0673005283b48be2f37c750ce367bDavid Greene 58225d812bd7d1f58f2ba1b598b1425a2e146e27381Chris Lattner if (VerboseAsm) 583b71d1b2fe2c0673005283b48be2f37c750ce367bDavid Greene LI = &getAnalysis<MachineLoopInfo>(); 584a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner} 585a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner 5861606e8e4cd937e6de6681f686c266cf61722d972Evan Chengnamespace { 5871606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng // SectionCPs - Keep track the alignment, constpool entries per Section. 5881606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng struct SectionCPs { 589a87dea4f8c546ca748f1777a8d1cabcc06515d91Chris Lattner const MCSection *S; 5901606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Alignment; 5911606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng SmallVector<unsigned, 4> CPEs; 592cabdd7425d30f7eb659ecb0cc5efbc4052dd78a8Douglas Gregor SectionCPs(const MCSection *s, unsigned a) : S(s), Alignment(a) {} 5931606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng }; 5941606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng} 5951606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 5963b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// EmitConstantPool - Print to the current output stream assembly 5973b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// representations of the constants in the constant pool MCP. This is 5983b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// used to print out constants which have been "spilled to memory" by 5993b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// the code generator. 6003b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner/// 601a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattnervoid AsmPrinter::EmitConstantPool() { 602a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner const MachineConstantPool *MCP = MF->getConstantPool(); 603fa77d43ba1d91ed39f46e11caeb28dcabae9e193Chris Lattner const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants(); 6043b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner if (CP.empty()) return; 6052d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng 606088ae8393f124564ca9ab70654645aa656e5646fAnton Korobeynikov // Calculate sections for constant pool entries. We collect entries to go into 607088ae8393f124564ca9ab70654645aa656e5646fAnton Korobeynikov // the same section together to reduce amount of section switch statements. 6081606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng SmallVector<SectionCPs, 4> CPSections; 6092d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng for (unsigned i = 0, e = CP.size(); i != e; ++i) { 610298414ec1891ce8d3a1b69e6019ad8765c8e69dcChris Lattner const MachineConstantPoolEntry &CPE = CP[i]; 6111606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Align = CPE.getAlignment(); 6125c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner 6135c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner SectionKind Kind; 6145c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner switch (CPE.getRelocationInfo()) { 6155c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner default: llvm_unreachable("Unknown section kind"); 6162798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner case 2: Kind = SectionKind::getReadOnlyWithRel(); break; 6174c50922f6be96fdb1e9a924aeeecf91638e2c52bChris Lattner case 1: 6182798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner Kind = SectionKind::getReadOnlyWithRelLocal(); 6194c50922f6be96fdb1e9a924aeeecf91638e2c52bChris Lattner break; 6205c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner case 0: 6214c50922f6be96fdb1e9a924aeeecf91638e2c52bChris Lattner switch (TM.getTargetData()->getTypeAllocSize(CPE.getType())) { 6222798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner case 4: Kind = SectionKind::getMergeableConst4(); break; 6232798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner case 8: Kind = SectionKind::getMergeableConst8(); break; 6242798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner case 16: Kind = SectionKind::getMergeableConst16();break; 6252798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner default: Kind = SectionKind::getMergeableConst(); break; 6264c50922f6be96fdb1e9a924aeeecf91638e2c52bChris Lattner } 6275c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner } 6285c2f789952ff315021afb10381f141f2ac3b1a6bChris Lattner 62983d77faf6e8fc2c1c2377d037283dc162d8667a1Chris Lattner const MCSection *S = getObjFileLowering().getSectionForConstant(Kind); 630298414ec1891ce8d3a1b69e6019ad8765c8e69dcChris Lattner 6311606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng // The number of sections are small, just do a linear search from the 6321606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng // last section to the first. 6331606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng bool Found = false; 6341606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned SecIdx = CPSections.size(); 6351606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng while (SecIdx != 0) { 6361606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (CPSections[--SecIdx].S == S) { 6371606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng Found = true; 6381606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng break; 6391606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng } 6401606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng } 6411606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (!Found) { 6421606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng SecIdx = CPSections.size(); 6431606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng CPSections.push_back(SectionCPs(S, Align)); 6441606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng } 6451606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 6461606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (Align > CPSections[SecIdx].Alignment) 6471606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng CPSections[SecIdx].Alignment = Align; 6481606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng CPSections[SecIdx].CPEs.push_back(i); 6492d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng } 6502d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng 651088ae8393f124564ca9ab70654645aa656e5646fAnton Korobeynikov // Now print stuff into the calculated sections. 6521606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng for (unsigned i = 0, e = CPSections.size(); i != e; ++i) { 6536c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(CPSections[i].S); 6541606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng EmitAlignment(Log2_32(CPSections[i].Alignment)); 6552d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng 6561606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Offset = 0; 6571606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng for (unsigned j = 0, ee = CPSections[i].CPEs.size(); j != ee; ++j) { 6581606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned CPI = CPSections[i].CPEs[j]; 6591606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng MachineConstantPoolEntry CPE = CP[CPI]; 6601606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 6611606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng // Emit inter-object padding for alignment. 6621606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned AlignMask = CPE.getAlignment() - 1; 6631606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned NewOffset = (Offset + AlignMask) & ~AlignMask; 664aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner OutStreamer.EmitFill(NewOffset - Offset, 0/*fillval*/, 0/*addrspace*/); 6651606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 6661606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng const Type *Ty = CPE.getType(); 667777d2306b36816a53bc1ae1244c0dc7d998ae691Duncan Sands Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty); 6682d2cec1e9e93a388bd8448f4bad661ac89a49de3Evan Cheng 6693924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner // Emit the label with a comment on it. 6701606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (VerboseAsm) { 6713924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner OutStreamer.GetCommentOS() << "constant pool "; 6723924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner WriteTypeSymbolic(OutStreamer.GetCommentOS(), CPE.getType(), 6733924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner MF->getFunction()->getParent()); 6743924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner OutStreamer.GetCommentOS() << '\n'; 6751606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng } 6763924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner OutStreamer.EmitLabel(GetCPISymbol(CPI)); 6773924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner 6781606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (CPE.isMachineConstantPoolEntry()) 6791606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng EmitMachineConstantPoolValue(CPE.Val.MachineCPVal); 680088ae8393f124564ca9ab70654645aa656e5646fAnton Korobeynikov else 6811606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng EmitGlobalConstant(CPE.Val.ConstVal); 6823029f920519e0871a5aad5d7c592281093953733Chris Lattner } 6833b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner } 6843b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner} 6853b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner 68637efe6764568a3829fee26aba532283131d1a104Nate Begeman/// EmitJumpTableInfo - Print assembly representations of the jump tables used 68737efe6764568a3829fee26aba532283131d1a104Nate Begeman/// by the current function to the current output stream. 68837efe6764568a3829fee26aba532283131d1a104Nate Begeman/// 68914c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattnervoid AsmPrinter::EmitJumpTableInfo() { 69014c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 69144e87255e9b7a9d8ecb558690db1181882c08045Chris Lattner if (MJTI == 0) return; 69295da605e15a6f108b551ecc6772823ea53de3007Richard Osborne if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline) return; 69337efe6764568a3829fee26aba532283131d1a104Nate Begeman const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 69437efe6764568a3829fee26aba532283131d1a104Nate Begeman if (JT.empty()) return; 6959de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov 6962f1ae88445c696a9b9d61e14747ba721190cdc99Nate Begeman // Pick the directive to use to print the jump table entries, and switch to 6972f1ae88445c696a9b9d61e14747ba721190cdc99Nate Begeman // the appropriate section. 69814c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner const Function *F = MF->getFunction(); 699b13bafe5c12dd908b55c559c93adaeb1627ed096Evan Cheng bool JTInDiffSection = false; 700f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner if (// In PIC mode, we need to emit the jump table to the same section as the 701f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // function body itself, otherwise the label differences won't make sense. 702f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // FIXME: Need a better predicate for this: what about custom entries? 703f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 || 704f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // We should also do if the section name is NULL or function is declared 705f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // in discardable section 706f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // FIXME: this isn't the right predicate, should be based on the MCSection 707f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner // for the function. 708f1214cbf3c2d151d3a2353d82143da186313a42aChris Lattner F->isWeakForLinker()) { 70914c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F,Mang,TM)); 7102f1ae88445c696a9b9d61e14747ba721190cdc99Nate Begeman } else { 71183d77faf6e8fc2c1c2377d037283dc162d8667a1Chris Lattner // Otherwise, drop it in the readonly section. 71283d77faf6e8fc2c1c2377d037283dc162d8667a1Chris Lattner const MCSection *ReadOnlySection = 7132798119ab4d7e0b42812b3acdf37821f40dee627Chris Lattner getObjFileLowering().getSectionForConstant(SectionKind::getReadOnly()); 7146c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(ReadOnlySection); 715b13bafe5c12dd908b55c559c93adaeb1627ed096Evan Cheng JTInDiffSection = true; 7162f1ae88445c696a9b9d61e14747ba721190cdc99Nate Begeman } 717071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner 718071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner EmitAlignment(Log2_32(MJTI->getEntryAlignment(*TM.getTargetData()))); 7190c4e6789da4dba6c7b0010886776b24dec3f3bb8Chris Lattner 7203b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) { 7213b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 72207371882208f913d18a7f2a47373eaee7138416bChris Lattner 72307371882208f913d18a7f2a47373eaee7138416bChris Lattner // If this jump table was deleted, ignore it. 72407371882208f913d18a7f2a47373eaee7138416bChris Lattner if (JTBBs.empty()) continue; 72552a51e38dc312aa262b0d771419afe1785f3cb22Nate Begeman 726e35df92eca194365f984f9d24a74e4ddd6669c40Chris Lattner // For the EK_LabelDifference32 entry, if the target supports .set, emit a 727e35df92eca194365f984f9d24a74e4ddd6669c40Chris Lattner // .set directive for each unique entry. This reduces the number of 728e35df92eca194365f984f9d24a74e4ddd6669c40Chris Lattner // relocations the assembler will generate for the jump table. 729e35df92eca194365f984f9d24a74e4ddd6669c40Chris Lattner if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 && 730cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner MAI->hasSetDirective()) { 7313b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner SmallPtrSet<const MachineBasicBlock*, 16> EmittedSets; 7323b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner const TargetLowering *TLI = TM.getTargetLowering(); 73314c38ec2afeaf25c53a50c2c65116aca8c889401Chris Lattner const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF,JTI,OutContext); 7343b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { 7353b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner const MachineBasicBlock *MBB = JTBBs[ii]; 7363b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner if (!EmittedSets.insert(MBB)) continue; 7373b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner 738c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner // .set LJTSet, LBB32-base 739c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner const MCExpr *LHS = 7401b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 741c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner OutStreamer.EmitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()), 742c618c8aff46a8ec4d209d041404e780a0caaf77dChris Lattner MCBinaryExpr::CreateSub(LHS, Base, OutContext)); 7433b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner } 7443b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner } 74552a51e38dc312aa262b0d771419afe1785f3cb22Nate Begeman 7467c30191393c99c9ba804f1a01942a9e130c53904Chris Lattner // On some targets (e.g. Darwin) we want to emit two consequtive labels 747393a8eea3c15de08eaf6953aa8a65a3961b76153Chris Lattner // before each jump table. The first label is never referenced, but tells 748393a8eea3c15de08eaf6953aa8a65a3961b76153Chris Lattner // the assembler and linker the extents of the jump table object. The 749393a8eea3c15de08eaf6953aa8a65a3961b76153Chris Lattner // second label is actually referenced by the code. 7503924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner if (JTInDiffSection && MAI->getLinkerPrivateGlobalPrefix()[0]) 751beeb93e6ba48af2661eabc4872d8b159fb43e5dbChris Lattner // FIXME: This doesn't have to have any specific name, just any randomly 752beeb93e6ba48af2661eabc4872d8b159fb43e5dbChris Lattner // named and numbered 'l' label would work. Simplify GetJTISymbol. 7533b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner OutStreamer.EmitLabel(GetJTISymbol(JTI, true)); 7543924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner 7553b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner OutStreamer.EmitLabel(GetJTISymbol(JTI)); 7563924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner 7576bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) 7583b131d7cc4dc4bbb329c136705b37dc255995fbdChris Lattner EmitJumpTableEntry(MJTI, JTBBs[ii], JTI); 75937efe6764568a3829fee26aba532283131d1a104Nate Begeman } 76037efe6764568a3829fee26aba532283131d1a104Nate Begeman} 76137efe6764568a3829fee26aba532283131d1a104Nate Begeman 7626bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner/// EmitJumpTableEntry - Emit a jump table entry for the specified MBB to the 7636bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner/// current stream. 7646bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattnervoid AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, 7656bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner const MachineBasicBlock *MBB, 7666bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner unsigned UID) const { 767ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner const MCExpr *Value = 0; 768ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner switch (MJTI->getEntryKind()) { 76995da605e15a6f108b551ecc6772823ea53de3007Richard Osborne case MachineJumpTableInfo::EK_Inline: 77095da605e15a6f108b551ecc6772823ea53de3007Richard Osborne llvm_unreachable("Cannot emit EK_Inline jump table entry"); break; 77185fe07866a3b240d9facef3b2f2ea81a0a8db018Chris Lattner case MachineJumpTableInfo::EK_Custom32: 7726bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner Value = TM.getTargetLowering()->LowerCustomJumpTableEntry(MJTI, MBB, UID, 77385fe07866a3b240d9facef3b2f2ea81a0a8db018Chris Lattner OutContext); 77485fe07866a3b240d9facef3b2f2ea81a0a8db018Chris Lattner break; 775ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner case MachineJumpTableInfo::EK_BlockAddress: 776ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // EK_BlockAddress - Each entry is a plain address of block, e.g.: 777ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .word LBB123 7781b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 779ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner break; 780ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner case MachineJumpTableInfo::EK_GPRel32BlockAddress: { 781ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // EK_GPRel32BlockAddress - Each entry is an address of block, encoded 782ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // with a relocation as gp-relative, e.g.: 783ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .gprel32 LBB123 7841b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner MCSymbol *MBBSym = MBB->getSymbol(); 785718fb59801320b8cb22363d115b5fc5ec40dc1f5Chris Lattner OutStreamer.EmitGPRel32Value(MCSymbolRefExpr::Create(MBBSym, OutContext)); 78678f485afb723121eedf4b6907ae6eb53da8af03cChris Lattner return; 7879de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov } 78885fe07866a3b240d9facef3b2f2ea81a0a8db018Chris Lattner 789ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner case MachineJumpTableInfo::EK_LabelDifference32: { 790ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // EK_LabelDifference32 - Each entry is the address of the block minus 791ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // the address of the jump table. This is used for PIC jump tables where 792ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // gprel32 is not supported. e.g.: 793ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .word LBB123 - LJTI1_2 794ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // If the .set directive is supported, this is emitted as: 795ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .set L4_5_set_123, LBB123 - LJTI1_2 796ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // .word L4_5_set_123 797ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner 798ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // If we have emitted set directives for the jump table entries, print 799ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // them rather than the entries themselves. If we're emitting PIC, then 800ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // emit the table entries as differences between two text section labels. 801cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner if (MAI->hasSetDirective()) { 802ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner // If we used .set, reference the .set's symbol. 8036bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner Value = MCSymbolRefExpr::Create(GetJTSetSymbol(UID, MBB->getNumber()), 804ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner OutContext); 805ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner break; 806ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner } 8071aca2492526c0a1aa464f2993084f9b30b53c009Chris Lattner // Otherwise, use the difference as the jump table entry. 8081b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 8096bf1def1598f9c7a699ce4874e7d2575212b4232Chris Lattner const MCExpr *JTI = MCSymbolRefExpr::Create(GetJTISymbol(UID), OutContext); 810ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner Value = MCBinaryExpr::CreateSub(Value, JTI, OutContext); 811ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner break; 812ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner } 8139de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov } 8141aca2492526c0a1aa464f2993084f9b30b53c009Chris Lattner 815ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner assert(Value && "Unknown entry kind!"); 816ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner 817071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner unsigned EntrySize = MJTI->getEntrySize(*TM.getTargetData()); 818ff537cec2e7ee34d6879de0c8a39a3c65f6ab003Chris Lattner OutStreamer.EmitValue(Value, EntrySize, /*addrspace*/0); 8199de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov} 8209de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov 8219de1934099f4eedaeb2f3a023411b2cd3e0e1eaeAnton Korobeynikov 822ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner/// EmitSpecialLLVMGlobal - Check to see if the specified global is a 823ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner/// special global used by LLVM. If so, emit it and return true, otherwise 824ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner/// do nothing and return false. 825ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattnerbool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { 82603d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar if (GV->getName() == "llvm.used") { 8273a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner if (MAI->hasNoDeadStrip()) // No need to emit this at all. 828b753a9bb6277cd34ffc55f8674087ff8c3097a11Andrew Lenharth EmitLLVMUsedList(GV->getInitializer()); 829b753a9bb6277cd34ffc55f8674087ff8c3097a11Andrew Lenharth return true; 830b753a9bb6277cd34ffc55f8674087ff8c3097a11Andrew Lenharth } 831b753a9bb6277cd34ffc55f8674087ff8c3097a11Andrew Lenharth 832401e10c4fbfcdcfade5065093e2ca97f69a1d144Chris Lattner // Ignore debug and non-emitted data. This handles llvm.compiler.used. 833266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner if (GV->getSection() == "llvm.metadata" || 834266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner GV->hasAvailableExternallyLinkage()) 835266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner return true; 8367809811e4ed3c2462efa327cef0464b9844baea2Jim Laskey 8377809811e4ed3c2462efa327cef0464b9844baea2Jim Laskey if (!GV->hasAppendingLinkage()) return false; 8387809811e4ed3c2462efa327cef0464b9844baea2Jim Laskey 8397809811e4ed3c2462efa327cef0464b9844baea2Jim Laskey assert(GV->hasInitializer() && "Not a special LLVM global!"); 840ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 841916d07cdfa89e77118043ec6e14575512ae1bf85Evan Cheng const TargetData *TD = TM.getTargetData(); 842916d07cdfa89e77118043ec6e14575512ae1bf85Evan Cheng unsigned Align = Log2_32(TD->getPointerPrefAlignment()); 843f231c07228deb75b6cd5ae7c9c057bc8303c6998Chris Lattner if (GV->getName() == "llvm.global_ctors") { 8446c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(getObjFileLowering().getStaticCtorSection()); 845ea3a9ff53d699bc22fcff52dbbce8aab6578a020Chris Lattner EmitAlignment(Align, 0); 846ea3a9ff53d699bc22fcff52dbbce8aab6578a020Chris Lattner EmitXXStructorList(GV->getInitializer()); 84771eae713153e564ec743c5c4162ff258c255de78Chris Lattner 84871eae713153e564ec743c5c4162ff258c255de78Chris Lattner if (TM.getRelocationModel() == Reloc::Static && 8493a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner MAI->hasStaticCtorDtorReferenceInStaticMode()) { 8503a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner StringRef Sym(".constructors_used"); 8513a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym), 852a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner MCSA_Reference); 8533a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner } 854ea3a9ff53d699bc22fcff52dbbce8aab6578a020Chris Lattner return true; 855ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner } 856ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 857f231c07228deb75b6cd5ae7c9c057bc8303c6998Chris Lattner if (GV->getName() == "llvm.global_dtors") { 8586c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(getObjFileLowering().getStaticDtorSection()); 859ea3a9ff53d699bc22fcff52dbbce8aab6578a020Chris Lattner EmitAlignment(Align, 0); 860ea3a9ff53d699bc22fcff52dbbce8aab6578a020Chris Lattner EmitXXStructorList(GV->getInitializer()); 86171eae713153e564ec743c5c4162ff258c255de78Chris Lattner 86271eae713153e564ec743c5c4162ff258c255de78Chris Lattner if (TM.getRelocationModel() == Reloc::Static && 8633a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner MAI->hasStaticCtorDtorReferenceInStaticMode()) { 8643a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner StringRef Sym(".destructors_used"); 8653a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym), 866a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner MCSA_Reference); 8673a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner } 868ea3a9ff53d699bc22fcff52dbbce8aab6578a020Chris Lattner return true; 869ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner } 870ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 871ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner return false; 872ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner} 873ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner 87433adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner/// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each 875d2e51af0358b571367a9f1e5175b87e9dd72edf8Dale Johannesen/// global in the specified llvm.used list for which emitUsedDirectiveFor 876d2e51af0358b571367a9f1e5175b87e9dd72edf8Dale Johannesen/// is true, as being used with this directive. 877cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattnervoid AsmPrinter::EmitLLVMUsedList(Constant *List) { 878a119de86a064414622562cfe32953de7f9b0ee40Dan Gohman // Should be an array of 'i8*'. 879cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner ConstantArray *InitList = dyn_cast<ConstantArray>(List); 880cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner if (InitList == 0) return; 881cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner 882cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { 88316fe990e56102a355f1e77aca93bf8c79d7b9eb2Chris Lattner const GlobalValue *GV = 88416fe990e56102a355f1e77aca93bf8c79d7b9eb2Chris Lattner dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts()); 8853a9be0ee36fe2143f514d28315f3dc1bda132b2eChris Lattner if (GV && getObjFileLowering().shouldEmitUsedDirectiveFor(GV, Mang)) 886deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner OutStreamer.EmitSymbolAttribute(Mang->getSymbol(GV), MCSA_NoDeadStrip); 887cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner } 888cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner} 889cb05af852f1d346ac07b84c74a930a5cdbd6d427Chris Lattner 890ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner/// EmitXXStructorList - Emit the ctor or dtor list. This just prints out the 891ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner/// function pointers, ignoring the init priority. 892ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattnervoid AsmPrinter::EmitXXStructorList(Constant *List) { 893ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner // Should be an array of '{ int, void ()* }' structs. The first value is the 894ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner // init priority, which we ignore. 895ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner if (!isa<ConstantArray>(List)) return; 896ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner ConstantArray *InitList = cast<ConstantArray>(List); 897ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) 898ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){ 899ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. 9008de324b59ce81cfb4202c706c96a3140f52e00c0Chris Lattner 9018de324b59ce81cfb4202c706c96a3140f52e00c0Chris Lattner if (CS->getOperand(1)->isNullValue()) 9028de324b59ce81cfb4202c706c96a3140f52e00c0Chris Lattner return; // Found a null terminator, exit printing. 9038de324b59ce81cfb4202c706c96a3140f52e00c0Chris Lattner // Emit the function pointer. 904ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner EmitGlobalConstant(CS->getOperand(1)); 905ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner } 906ed13893ff729bc3b91697f6d80a3ba303782efccChris Lattner} 9073b4fd32a41a90ea67fd09a020d480c20e9c40dafChris Lattner 90891bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner/// EmitInlineAsm - Emit a blob of inline asm to the output streamer. 909f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattnervoid AsmPrinter::EmitInlineAsm(StringRef Str) const { 91091bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner assert(!Str.empty() && "Can't emit empty inline asm block"); 91191bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner 91291bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner // If the output streamer is actually a .s file, just emit the blob textually. 91391bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner // This is useful in case the asm parser doesn't handle something but the 91491bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner // system assembler does. 91591bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner if (OutStreamer.hasRawTextSupport()) { 91691bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner OutStreamer.EmitRawText(Str); 91791bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner return; 91891bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner } 91991bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner 92091bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner errs() << "Inline asm not supported by this streamer!\n"; 92191bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner} 92291bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner 92391bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner 924f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey//===--------------------------------------------------------------------===// 925f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey// Emission and print routines 926f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey// 927f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 928f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// EmitInt8 - Emit a byte directive and value. 929f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// 930f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskeyvoid AsmPrinter::EmitInt8(int Value) const { 9315eaa54e210256a939f15e918303197916c992aeeChris Lattner OutStreamer.EmitIntValue(Value, 1, 0/*addrspace*/); 932f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey} 933f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 934f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// EmitInt16 - Emit a short directive and value. 935f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// 936f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskeyvoid AsmPrinter::EmitInt16(int Value) const { 9375eaa54e210256a939f15e918303197916c992aeeChris Lattner OutStreamer.EmitIntValue(Value, 2, 0/*addrspace*/); 938f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey} 939f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 940f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// EmitInt32 - Emit a long directive and value. 941f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey/// 942f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskeyvoid AsmPrinter::EmitInt32(int Value) const { 9435eaa54e210256a939f15e918303197916c992aeeChris Lattner OutStreamer.EmitIntValue(Value, 4, 0/*addrspace*/); 944f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey} 945f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 9460d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner/// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size 9470d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner/// in bytes of the directive is specified by Size and Hi/Lo specify the 9480d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner/// labels. This implicitly uses .set if it is available. 9490d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattnervoid AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, 9500d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner unsigned Size) const { 9510d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner // Get the Hi-Lo expression. 9520d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner const MCExpr *Diff = 9530d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(Hi, OutContext), 9540d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner MCSymbolRefExpr::Create(Lo, OutContext), 9550d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner OutContext); 9560d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner 9570d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner if (!MAI->hasSetDirective()) { 9580d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner OutStreamer.EmitValue(Diff, Size, 0/*AddrSpace*/); 9590d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner return; 9600d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner } 9610d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner 9620d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner // Otherwise, emit with .set (aka assignment). 9630d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner MCSymbol *SetLabel = 9649b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + 9659b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner "set" + Twine(SetCounter++)); 9660d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner OutStreamer.EmitAssignment(SetLabel, Diff); 9676cde3e6e993126df756e3be5b9ef43540b904644Chris Lattner OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/); 9680d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner} 9690d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner 9700d50c7620d92762eaa5c9dedd07c94f5a6a19935Chris Lattner 971f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey//===----------------------------------------------------------------------===// 972f1cdea1d021068f5c9e118d68321ce28fcea63faJim Laskey 9733a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// EmitAlignment - Emit an alignment directive to the specified power of 9743a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// two boundary. For example, if you pass in 3 here, you will get an 8 9753a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// byte alignment. If a global value is specified, and if that global has 9763a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// an explicit alignment requested, it will unconditionally override the 9773a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// alignment request. However, if ForcedAlignBits is specified, this value 9783a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// has final say: the ultimate alignment will be the max of ForcedAlignBits 9793a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// and the alignment computed with NumBits and the global. 9803a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// 9813a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// The algorithm is: 9823a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// Align = NumBits; 9833a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// if (GV && GV->hasalignment) Align = GV->getalignment(); 9843a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// Align = std::max(Align, ForcedAlignBits); 9853a4205367dc845d4cd804b47e061f8281777c9daChris Lattner// 9863a4205367dc845d4cd804b47e061f8281777c9daChris Lattnervoid AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV, 98705548eb174dd694b651de334b73197a62e5071f1Evan Cheng unsigned ForcedAlignBits, 98805548eb174dd694b651de334b73197a62e5071f1Evan Cheng bool UseFillExpr) const { 98900d56b96e599acbc4f895e86e17029ae7c45f142Dale Johannesen if (GV && GV->getAlignment()) 9903a4205367dc845d4cd804b47e061f8281777c9daChris Lattner NumBits = Log2_32(GV->getAlignment()); 9913a4205367dc845d4cd804b47e061f8281777c9daChris Lattner NumBits = std::max(NumBits, ForcedAlignBits); 9923a4205367dc845d4cd804b47e061f8281777c9daChris Lattner 9932a21c6e86101c857d683e7bdefb775654ccab7e3Chris Lattner if (NumBits == 0) return; // No need to emit alignment. 994663c2d2580e6e9b2435785c7e5a2de18758860a3Chris Lattner 995dabf07c70a5e13a4560d75667fa5c7db28921a92Chris Lattner if (getCurrentSection()->getKind().isText()) 9962cce3712fafb2e72e144414377cd48f5ab95a5aeChris Lattner OutStreamer.EmitCodeAlignment(1 << NumBits); 9972cce3712fafb2e72e144414377cd48f5ab95a5aeChris Lattner else 9982cce3712fafb2e72e144414377cd48f5ab95a5aeChris Lattner OutStreamer.EmitValueToAlignment(1 << NumBits, 0, 1, 0); 999bfddc2030a7e67b9e0c42276525d6932375ff261Chris Lattner} 1000a5bb59f85613e8ce481351803e7388f5ab466e72David Greene 100152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner/// LowerConstant - Lower the specified LLVM Constant to an MCExpr. 100252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner/// 100352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattnerstatic const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) { 100452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner MCContext &Ctx = AP.OutContext; 1005fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 100652492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (CV->isNullValue() || isa<UndefValue>(CV)) 100752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCConstantExpr::Create(0, Ctx); 100852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner 100952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) 101052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCConstantExpr::Create(CI->getZExtValue(), Ctx); 1011fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 101252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) 1013deb0cba1bad5a46bbecb75666e415c3dee9c89ebChris Lattner return MCSymbolRefExpr::Create(AP.Mang->getSymbol(GV), Ctx); 101452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) 101552492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCSymbolRefExpr::Create(AP.GetBlockAddressSymbol(BA), Ctx); 1016fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1017fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV); 1018fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner if (CE == 0) { 101952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner llvm_unreachable("Unknown constant value to lower!"); 102052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCConstantExpr::Create(0, Ctx); 1021fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner } 1022fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1023fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner switch (CE->getOpcode()) { 1024618f17702d09795279717827eeb06632d6ef49e4Dan Gohman default: 1025618f17702d09795279717827eeb06632d6ef49e4Dan Gohman // If the code isn't optimized, there may be outstanding folding 1026618f17702d09795279717827eeb06632d6ef49e4Dan Gohman // opportunities. Attempt to fold the expression using TargetData as a 1027618f17702d09795279717827eeb06632d6ef49e4Dan Gohman // last resort before giving up. 102854e72eca0c5d012546fcc6d1fdac7ee56c90686cDan Gohman if (Constant *C = 102954e72eca0c5d012546fcc6d1fdac7ee56c90686cDan Gohman ConstantFoldConstantExpression(CE, AP.TM.getTargetData())) 103054e72eca0c5d012546fcc6d1fdac7ee56c90686cDan Gohman if (C != CE) 103154e72eca0c5d012546fcc6d1fdac7ee56c90686cDan Gohman return LowerConstant(C, AP); 1032618f17702d09795279717827eeb06632d6ef49e4Dan Gohman#ifndef NDEBUG 1033618f17702d09795279717827eeb06632d6ef49e4Dan Gohman CE->dump(); 1034618f17702d09795279717827eeb06632d6ef49e4Dan Gohman#endif 1035618f17702d09795279717827eeb06632d6ef49e4Dan Gohman llvm_unreachable("FIXME: Don't support this constant expr"); 1036fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::GetElementPtr: { 103752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const TargetData &TD = *AP.TM.getTargetData(); 103852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // Generate a symbolic expression for the byte address 103952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const Constant *PtrVal = CE->getOperand(0); 104052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner SmallVector<Value*, 8> IdxVec(CE->op_begin()+1, CE->op_end()); 104152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner int64_t Offset = TD.getIndexedOffset(PtrVal->getType(), &IdxVec[0], 104252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner IdxVec.size()); 104352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner 104452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *Base = LowerConstant(CE->getOperand(0), AP); 1045fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner if (Offset == 0) 104652492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return Base; 1047fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1048fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // Truncate/sext the offset to the pointer size. 104952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (TD.getPointerSizeInBits() != 64) { 105052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner int SExtAmount = 64-TD.getPointerSizeInBits(); 1051fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner Offset = (Offset << SExtAmount) >> SExtAmount; 1052a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner } 1053fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 105452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCBinaryExpr::CreateAdd(Base, MCConstantExpr::Create(Offset, Ctx), 105552492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner Ctx); 1056fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner } 105752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner 105852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Trunc: 105952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // We emit the value and depend on the assembler to truncate the generated 106052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // expression properly. This is important for differences between 106152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // blockaddress labels. Since the two labels are in the same function, it 106252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // is reasonable to treat their delta as a 32-bit value. 106352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // FALL THROUGH. 1064fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::BitCast: 106552492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return LowerConstant(CE->getOperand(0), AP); 1066fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1067fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::IntToPtr: { 106852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const TargetData &TD = *AP.TM.getTargetData(); 1069fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // Handle casts to pointers by changing them into casts to the appropriate 1070fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // integer type. This promotes constant folding and simplifies this code. 1071fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner Constant *Op = CE->getOperand(0); 107252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner Op = ConstantExpr::getIntegerCast(Op, TD.getIntPtrType(CV->getContext()), 1073fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner false/*ZExt*/); 107452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return LowerConstant(Op, AP); 1075fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner } 1076fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1077fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::PtrToInt: { 107852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const TargetData &TD = *AP.TM.getTargetData(); 1079fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // Support only foldable casts to/from pointers that can be eliminated by 1080fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // changing the pointer to the appropriately sized integer type. 1081fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner Constant *Op = CE->getOperand(0); 1082fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner const Type *Ty = CE->getType(); 108352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner 108452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *OpExpr = LowerConstant(Op, AP); 1085fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner 1086fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner // We can emit the pointer value into this slot if the slot is an 108752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // integer slot equal to the size of the pointer. 108852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner if (TD.getTypeAllocSize(Ty) == TD.getTypeAllocSize(Op->getType())) 108952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return OpExpr; 109052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner 109152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // Otherwise the pointer is smaller than the resultant integer, mask off 109252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // the high bits so we are sure to get a proper truncation if the input is 109352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // a constant expr. 109452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner unsigned InBits = TD.getTypeAllocSizeInBits(Op->getType()); 109552492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *MaskExpr = MCConstantExpr::Create(~0ULL >> (64-InBits), Ctx); 109652492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx); 1097fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner } 1098ddc94019916fbe4d3fff915e6002c39c63488a44Chris Lattner 10995938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman // The MC library also has a right-shift operator, but it isn't consistently 11005938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman // signed or unsigned between different targets. 1101fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::Add: 1102fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::Sub: 11035938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::Mul: 11045938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::SDiv: 11055938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::SRem: 11065938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::Shl: 1107fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::And: 1108fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner case Instruction::Or: 110952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Xor: { 111052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *LHS = LowerConstant(CE->getOperand(0), AP); 111152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner const MCExpr *RHS = LowerConstant(CE->getOperand(1), AP); 1112fe0e7ed6b077360dbcc6d9f0bc0a4dfeb77c8e9bChris Lattner switch (CE->getOpcode()) { 111352492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner default: llvm_unreachable("Unknown binary operator constant cast expr"); 111452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Add: return MCBinaryExpr::CreateAdd(LHS, RHS, Ctx); 111552492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Sub: return MCBinaryExpr::CreateSub(LHS, RHS, Ctx); 11165938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::Mul: return MCBinaryExpr::CreateMul(LHS, RHS, Ctx); 11175938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::SDiv: return MCBinaryExpr::CreateDiv(LHS, RHS, Ctx); 11185938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::SRem: return MCBinaryExpr::CreateMod(LHS, RHS, Ctx); 11195938a3e681ab7612f5921c5ccaca5d2e0851c60fDan Gohman case Instruction::Shl: return MCBinaryExpr::CreateShl(LHS, RHS, Ctx); 112052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::And: return MCBinaryExpr::CreateAnd(LHS, RHS, Ctx); 112152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Or: return MCBinaryExpr::CreateOr (LHS, RHS, Ctx); 112252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner case Instruction::Xor: return MCBinaryExpr::CreateXor(LHS, RHS, Ctx); 1123a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner } 112452492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner } 1125a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner } 1126a80ba71efe5be5012128e2db0dd29b024e00105aChris Lattner} 11271b7e2356ace23af872cc7d66cf45c56b10e77c4dChris Lattner 112891093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattnerstatic void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace, 112991093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner AsmPrinter &AP) { 113005f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner if (AddrSpace != 0 || !CA->isString()) { 113105f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner // Not a string. Print the values in successive locations 113291093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) 113391093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner AP.EmitGlobalConstant(CA->getOperand(i), AddrSpace); 113405f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner return; 113500d448a341175556ebd86af68219f5b90b7145a3Dan Gohman } 113605f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner 113705f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner // Otherwise, it can be emitted as .ascii. 113805f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner SmallVector<char, 128> TmpVec; 113905f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner TmpVec.reserve(CA->getNumOperands()); 114005f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) 114105f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner TmpVec.push_back(cast<ConstantInt>(CA->getOperand(i))->getZExtValue()); 114205f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner 114305f845314a67f9c30a67e55ce1e3168ff6732ce8Chris Lattner AP.OutStreamer.EmitBytes(StringRef(TmpVec.data(), TmpVec.size()), AddrSpace); 114400d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 114500d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 114691093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattnerstatic void EmitGlobalConstantVector(const ConstantVector *CV, 114791093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner unsigned AddrSpace, AsmPrinter &AP) { 1148bcb83e5b6c8e074e73986cb641801ecbedd6e4edChris Lattner for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) 114991093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner AP.EmitGlobalConstant(CV->getOperand(i), AddrSpace); 115000d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 115100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 115291093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattnerstatic void EmitGlobalConstantStruct(const ConstantStruct *CS, 115391093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner unsigned AddrSpace, AsmPrinter &AP) { 115400d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // Print the fields in successive locations. Pad to align if needed! 115591093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner const TargetData *TD = AP.TM.getTargetData(); 115691093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner unsigned Size = TD->getTypeAllocSize(CS->getType()); 11572dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner const StructLayout *Layout = TD->getStructLayout(CS->getType()); 115891093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner uint64_t SizeSoFar = 0; 115991093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) { 1160bcb83e5b6c8e074e73986cb641801ecbedd6e4edChris Lattner const Constant *Field = CS->getOperand(i); 116100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 116200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // Check if padding is needed and insert one or more 0s. 1163bcb83e5b6c8e074e73986cb641801ecbedd6e4edChris Lattner uint64_t FieldSize = TD->getTypeAllocSize(Field->getType()); 11642dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner uint64_t PadSize = ((i == e-1 ? Size : Layout->getElementOffset(i+1)) 11652dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner - Layout->getElementOffset(i)) - FieldSize; 11662dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner SizeSoFar += FieldSize + PadSize; 116700d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 116800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // Now print the actual field value. 1169bcb83e5b6c8e074e73986cb641801ecbedd6e4edChris Lattner AP.EmitGlobalConstant(Field, AddrSpace); 117000d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 117100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // Insert padding - this may include padding to increase the size of the 117200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // current field up to the ABI size (if the struct is not packed) as well 117300d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // as padding to ensure that the next field starts at the right offset. 11742dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitZeros(PadSize, AddrSpace); 117500d448a341175556ebd86af68219f5b90b7145a3Dan Gohman } 11762dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner assert(SizeSoFar == Layout->getSizeInBytes() && 117700d448a341175556ebd86af68219f5b90b7145a3Dan Gohman "Layout of constant struct may be incorrect!"); 117800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 117900d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 118093b122d3c484a8451024d6947be0f4037f86def0Chris Lattnerstatic void EmitGlobalConstantUnion(const ConstantUnion *CU, 118193b122d3c484a8451024d6947be0f4037f86def0Chris Lattner unsigned AddrSpace, AsmPrinter &AP) { 118293b122d3c484a8451024d6947be0f4037f86def0Chris Lattner const TargetData *TD = AP.TM.getTargetData(); 118393b122d3c484a8451024d6947be0f4037f86def0Chris Lattner unsigned Size = TD->getTypeAllocSize(CU->getType()); 118493b122d3c484a8451024d6947be0f4037f86def0Chris Lattner 118593b122d3c484a8451024d6947be0f4037f86def0Chris Lattner const Constant *Contents = CU->getOperand(0); 118693b122d3c484a8451024d6947be0f4037f86def0Chris Lattner unsigned FilledSize = TD->getTypeAllocSize(Contents->getType()); 118793b122d3c484a8451024d6947be0f4037f86def0Chris Lattner 118893b122d3c484a8451024d6947be0f4037f86def0Chris Lattner // Print the actually filled part 118993b122d3c484a8451024d6947be0f4037f86def0Chris Lattner AP.EmitGlobalConstant(Contents, AddrSpace); 119093b122d3c484a8451024d6947be0f4037f86def0Chris Lattner 119193b122d3c484a8451024d6947be0f4037f86def0Chris Lattner // And pad with enough zeroes 119293b122d3c484a8451024d6947be0f4037f86def0Chris Lattner AP.OutStreamer.EmitZeros(Size-FilledSize, AddrSpace); 119393b122d3c484a8451024d6947be0f4037f86def0Chris Lattner} 119493b122d3c484a8451024d6947be0f4037f86def0Chris Lattner 11952dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattnerstatic void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace, 11962dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AsmPrinter &AP) { 119700d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // FP Constants are printed as integer constants to avoid losing 11989ceff94447235a2e369d9adfdf57368f57dd3f18Chris Lattner // precision. 1199cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner if (CFP->getType()->isDoubleTy()) { 12002dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner if (AP.VerboseAsm) { 1201d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner double Val = CFP->getValueAPF().convertToDouble(); 1202d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner AP.OutStreamer.GetCommentOS() << "double " << Val << '\n'; 120309ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner } 120409ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner 12052dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); 12062dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace); 120700d448a341175556ebd86af68219f5b90b7145a3Dan Gohman return; 1208cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner } 1209cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner 1210cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner if (CFP->getType()->isFloatTy()) { 12112dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner if (AP.VerboseAsm) { 12120fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner float Val = CFP->getValueAPF().convertToFloat(); 12130fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner AP.OutStreamer.GetCommentOS() << "float " << Val << '\n'; 1214a12e9d751b64767a5c41a718da2a91122d5874c4Dan Gohman } 12152dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); 12162dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(Val, 4, AddrSpace); 121700d448a341175556ebd86af68219f5b90b7145a3Dan Gohman return; 1218cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner } 1219cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner 1220cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner if (CFP->getType()->isX86_FP80Ty()) { 122100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // all long double variants are printed as hex 122200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // api needed to prevent premature destruction 122309ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner APInt API = CFP->getValueAPF().bitcastToAPInt(); 122409ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner const uint64_t *p = API.getRawData(); 12252dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner if (AP.VerboseAsm) { 122672b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner // Convert to double so we can print the approximate val as a comment. 122772b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner APFloat DoubleVal = CFP->getValueAPF(); 122872b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner bool ignored; 122972b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, 123072b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner &ignored); 12310fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner AP.OutStreamer.GetCommentOS() << "x86_fp80 ~= " 12320fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner << DoubleVal.convertToDouble() << '\n'; 123372b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner } 123472b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner 12352dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner if (AP.TM.getTargetData()->isBigEndian()) { 12362dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace); 12372dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); 123872b5ebc6be0fcfa36583367bc20afadb2c24d985Chris Lattner } else { 12392dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); 12402dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace); 124100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman } 12429ceff94447235a2e369d9adfdf57368f57dd3f18Chris Lattner 12439ceff94447235a2e369d9adfdf57368f57dd3f18Chris Lattner // Emit the tail padding for the long double. 12442dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner const TargetData &TD = *AP.TM.getTargetData(); 12452dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitZeros(TD.getTypeAllocSize(CFP->getType()) - 12462dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner TD.getTypeStoreSize(CFP->getType()), AddrSpace); 124700d448a341175556ebd86af68219f5b90b7145a3Dan Gohman return; 1248cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner } 1249cf0fe8d813727383d630055bb9d1cde21b00b7e7Chris Lattner 125009ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner assert(CFP->getType()->isPPC_FP128Ty() && 125109ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner "Floating point constant type not handled"); 125209ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner // All long double variants are printed as hex api needed to prevent 125309ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner // premature destruction. 125409ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner APInt API = CFP->getValueAPF().bitcastToAPInt(); 125509ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner const uint64_t *p = API.getRawData(); 12562dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner if (AP.TM.getTargetData()->isBigEndian()) { 12572dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); 12582dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace); 12599ceff94447235a2e369d9adfdf57368f57dd3f18Chris Lattner } else { 12602dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace); 12612dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); 126209ce674ce81cfa0de096f19833ae7bc7549d851aChris Lattner } 126300d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 126400d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 12652dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattnerstatic void EmitGlobalConstantLargeInt(const ConstantInt *CI, 12662dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner unsigned AddrSpace, AsmPrinter &AP) { 12672dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner const TargetData *TD = AP.TM.getTargetData(); 126800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman unsigned BitWidth = CI->getBitWidth(); 126938c2b0a99c6a3f5cdf6ef5a46e4a6826b30acbfbChris Lattner assert((BitWidth & 63) == 0 && "only support multiples of 64-bits"); 127000d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 127100d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // We don't expect assemblers to support integer data directives 127200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // for more than 64 bits, so we emit the data in at most 64-bit 127300d448a341175556ebd86af68219f5b90b7145a3Dan Gohman // quantities at a time. 127400d448a341175556ebd86af68219f5b90b7145a3Dan Gohman const uint64_t *RawData = CI->getValue().getRawData(); 127500d448a341175556ebd86af68219f5b90b7145a3Dan Gohman for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) { 12762dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner uint64_t Val = TD->isBigEndian() ? RawData[e - i - 1] : RawData[i]; 12772dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace); 127800d448a341175556ebd86af68219f5b90b7145a3Dan Gohman } 127900d448a341175556ebd86af68219f5b90b7145a3Dan Gohman} 128000d448a341175556ebd86af68219f5b90b7145a3Dan Gohman 128125045bdcda822d63674e2df7e34016536c5d3fa7Chris Lattner/// EmitGlobalConstant - Print a general LLVM constant to the .s file. 1282c8d7bc850ddf5a5df503a173b0bc0f8c03ffec96Sanjiv Guptavoid AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) { 1283043c4e5c1d012c8131c7f2fa27a4def32740c42fChris Lattner if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV)) { 12842dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType()); 1285744f579b63987854ac1b3f2f9c8d2659c5b5ee40Bill Wendling if (Size == 0) Size = 1; // An empty "_foo:" followed by a section is undef. 12866449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner return OutStreamer.EmitZeros(Size, AddrSpace); 12872dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner } 12882dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner 12892dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { 12902dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner unsigned Size = TM.getTargetData()->getTypeAllocSize(CV->getType()); 12912dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner switch (Size) { 12922dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner case 1: 12932dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner case 2: 12942dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner case 4: 12952dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner case 8: 12960fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner if (VerboseAsm) 12970fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner OutStreamer.GetCommentOS() << format("0x%llx\n", CI->getZExtValue()); 12982dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner OutStreamer.EmitIntValue(CI->getZExtValue(), Size, AddrSpace); 12992dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner return; 13002dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner default: 13012dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner EmitGlobalConstantLargeInt(CI, AddrSpace, *this); 13022dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner return; 13032dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner } 13042dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner } 13053cc3a00570e8263369346cf2eef9a72488326952Chris Lattner 130691093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) 130791093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner return EmitGlobalConstantArray(CVA, AddrSpace, *this); 13083cc3a00570e8263369346cf2eef9a72488326952Chris Lattner 130991093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) 131091093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner return EmitGlobalConstantStruct(CVS, AddrSpace, *this); 13113cc3a00570e8263369346cf2eef9a72488326952Chris Lattner 131291093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) 13132dd245c469f4d842f2b7af80582fb4769a914b23Chris Lattner return EmitGlobalConstantFP(CFP, AddrSpace, *this); 13141b7e2356ace23af872cc7d66cf45c56b10e77c4dChris Lattner 1315b0bedd6ebbbf0b9791291f37da5666dd456cf5b1Chris Lattner if (isa<ConstantPointerNull>(CV)) { 1316b0bedd6ebbbf0b9791291f37da5666dd456cf5b1Chris Lattner unsigned Size = TM.getTargetData()->getTypeAllocSize(CV->getType()); 1317b0bedd6ebbbf0b9791291f37da5666dd456cf5b1Chris Lattner OutStreamer.EmitIntValue(0, Size, AddrSpace); 1318b0bedd6ebbbf0b9791291f37da5666dd456cf5b1Chris Lattner return; 1319b0bedd6ebbbf0b9791291f37da5666dd456cf5b1Chris Lattner } 1320b0bedd6ebbbf0b9791291f37da5666dd456cf5b1Chris Lattner 132193b122d3c484a8451024d6947be0f4037f86def0Chris Lattner if (const ConstantUnion *CVU = dyn_cast<ConstantUnion>(CV)) 132293b122d3c484a8451024d6947be0f4037f86def0Chris Lattner return EmitGlobalConstantUnion(CVU, AddrSpace, *this); 132393b122d3c484a8451024d6947be0f4037f86def0Chris Lattner 132493b122d3c484a8451024d6947be0f4037f86def0Chris Lattner if (const ConstantVector *V = dyn_cast<ConstantVector>(CV)) 132593b122d3c484a8451024d6947be0f4037f86def0Chris Lattner return EmitGlobalConstantVector(V, AddrSpace, *this); 132693b122d3c484a8451024d6947be0f4037f86def0Chris Lattner 132752492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it 132852492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner // thread the streamer with EmitValue. 132952492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner OutStreamer.EmitValue(LowerConstant(CV, *this), 133052492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner TM.getTargetData()->getTypeAllocSize(CV->getType()), 133152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner AddrSpace); 13321b7e2356ace23af872cc7d66cf45c56b10e77c4dChris Lattner} 13330264d1a4777370009176157b76d116b3195e3767Chris Lattner 1334fad86b003a839cef40ec8ce8408322f4913368caChris Lattnervoid AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 1335d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng // Target doesn't support this yet! 1336c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Target does not support EmitMachineConstantPoolValue"); 1337d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng} 1338d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng 1339dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattnervoid AsmPrinter::printOffset(int64_t Offset, raw_ostream &OS) const { 1340dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner if (Offset > 0) 1341dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner OS << '+' << Offset; 1342dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner else if (Offset < 0) 1343dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner OS << Offset; 1344dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner} 1345dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner 13463ce9b67e0c0f171c6d09c19407930ce6989f1b9dChris Lattner/// PrintSpecial - Print information related to the specified machine instr 13473ce9b67e0c0f171c6d09c19407930ce6989f1b9dChris Lattner/// that is independent of the operand, and may be independent of the instr 13483ce9b67e0c0f171c6d09c19407930ce6989f1b9dChris Lattner/// itself. This can be useful for portably encoding the comment character 13493ce9b67e0c0f171c6d09c19407930ce6989f1b9dChris Lattner/// or other bits of target-specific knowledge into the asmstrings. The 13503ce9b67e0c0f171c6d09c19407930ce6989f1b9dChris Lattner/// syntax used is ${:comment}. Targets can override this to add support 13513ce9b67e0c0f171c6d09c19407930ce6989f1b9dChris Lattner/// for their own strange codes. 135235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid AsmPrinter::PrintSpecial(const MachineInstr *MI, raw_ostream &OS, 135335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner const char *Code) const { 1354bae02cfd46c569bb571a234544fb1bbe19c43b59Chris Lattner if (!strcmp(Code, "private")) { 135535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner OS << MAI->getPrivateGlobalPrefix(); 1356bae02cfd46c569bb571a234544fb1bbe19c43b59Chris Lattner } else if (!strcmp(Code, "comment")) { 135735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner OS << MAI->getCommentString(); 13583ce9b67e0c0f171c6d09c19407930ce6989f1b9dChris Lattner } else if (!strcmp(Code, "uid")) { 1359b6a24bfa9550e5561da3091f7e5132575bf5a19eChris Lattner // Comparing the address of MI isn't sufficient, because machineinstrs may 1360b6a24bfa9550e5561da3091f7e5132575bf5a19eChris Lattner // be allocated to the same address across functions. 1361b6a24bfa9550e5561da3091f7e5132575bf5a19eChris Lattner const Function *ThisF = MI->getParent()->getParent()->getFunction(); 1362b6a24bfa9550e5561da3091f7e5132575bf5a19eChris Lattner 1363bd58edf59128d2acb5ae48c76ef8a108fd587db2Owen Anderson // If this is a new LastFn instruction, bump the counter. 1364bd58edf59128d2acb5ae48c76ef8a108fd587db2Owen Anderson if (LastMI != MI || LastFn != ThisF) { 1365b6a24bfa9550e5561da3091f7e5132575bf5a19eChris Lattner ++Counter; 1366b6a24bfa9550e5561da3091f7e5132575bf5a19eChris Lattner LastMI = MI; 1367bd58edf59128d2acb5ae48c76ef8a108fd587db2Owen Anderson LastFn = ThisF; 1368b6a24bfa9550e5561da3091f7e5132575bf5a19eChris Lattner } 136935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner OS << Counter; 13703ce9b67e0c0f171c6d09c19407930ce6989f1b9dChris Lattner } else { 13717d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin std::string msg; 13727d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin raw_string_ostream Msg(msg); 13737d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin Msg << "Unknown special formatter '" << Code 1374e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling << "' for machine instr: " << *MI; 13757d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin llvm_report_error(Msg.str()); 13763ce9b67e0c0f171c6d09c19407930ce6989f1b9dChris Lattner } 13773ce9b67e0c0f171c6d09c19407930ce6989f1b9dChris Lattner} 13783ce9b67e0c0f171c6d09c19407930ce6989f1b9dChris Lattner 1379cd76240f3d0f6c5f8c80e4762a8fe3a4de22e059Argyrios Kyrtzidis/// processDebugLoc - Processes the debug information of each machine 1380cd76240f3d0f6c5f8c80e4762a8fe3a4de22e059Argyrios Kyrtzidis/// instruction's DebugLoc. 1381af0e2726835e096e32c30c1b88cc7a6232a6ef69Devang Patelvoid AsmPrinter::processDebugLoc(const MachineInstr *MI, 1382af0e2726835e096e32c30c1b88cc7a6232a6ef69Devang Patel bool BeforePrintingInsn) { 1383dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner if (!DW || !MAI->doesSupportDebugInformation() || !DW->ShouldEmitDwarfDebug()) 1384d250329291dd9fe0d5f0e72e6cf1e287558a7cbaChris Lattner return; 138553bb5c95afe4ff2627cac513221af2e4e7c5d2e3Devang Patel 1386553881bddcdeb66c0ae06bf9f62ca63b9f29b2e8Devang Patel if (!BeforePrintingInsn) 138753bb5c95afe4ff2627cac513221af2e4e7c5d2e3Devang Patel // After printing instruction 138853bb5c95afe4ff2627cac513221af2e4e7c5d2e3Devang Patel DW->EndScope(MI); 1389553881bddcdeb66c0ae06bf9f62ca63b9f29b2e8Devang Patel else 1390553881bddcdeb66c0ae06bf9f62ca63b9f29b2e8Devang Patel DW->BeginScope(MI); 1391cd76240f3d0f6c5f8c80e4762a8fe3a4de22e059Argyrios Kyrtzidis} 13923ce9b67e0c0f171c6d09c19407930ce6989f1b9dChris Lattner 139353bb5c95afe4ff2627cac513221af2e4e7c5d2e3Devang Patel 1394300a4c5640fb1c717ba0d7108d15aec1bd7eb396Chris Lattner/// EmitInlineAsm - This method formats and emits the specified machine 13950264d1a4777370009176157b76d116b3195e3767Chris Lattner/// instruction that is an inline asm. 1396300a4c5640fb1c717ba0d7108d15aec1bd7eb396Chris Lattnervoid AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const { 1397f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner assert(MI->isInlineAsm() && "printInlineAsm only works on inline asms"); 1398f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner 1399f2b67cff040d1eb3229f7929d0ec7a5e016a7a57Chris Lattner unsigned NumOperands = MI->getNumOperands(); 1400f2b67cff040d1eb3229f7929d0ec7a5e016a7a57Chris Lattner 1401f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner // Count the number of register definitions to find the asm string. 1402f2b67cff040d1eb3229f7929d0ec7a5e016a7a57Chris Lattner unsigned NumDefs = 0; 1403d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef(); 140467942f5dc30be1810f983aba8c94c49ca44e8634Chris Lattner ++NumDefs) 1405f2b67cff040d1eb3229f7929d0ec7a5e016a7a57Chris Lattner assert(NumDefs != NumOperands-1 && "No asm string?"); 1406f2b67cff040d1eb3229f7929d0ec7a5e016a7a57Chris Lattner 1407d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman assert(MI->getOperand(NumDefs).isSymbol() && "No asm string?"); 14086609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner 14096609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner // Disassemble the AsmStr, printing out the literal pieces, the operands, etc. 1410f2b67cff040d1eb3229f7929d0ec7a5e016a7a57Chris Lattner const char *AsmStr = MI->getOperand(NumDefs).getSymbolName(); 14116609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner 1412ba2a0b960ea4c73d0f81557f63ae2ea126e08905Dale Johannesen // If this asmstr is empty, just print the #APP/#NOAPP markers. 1413ba2a0b960ea4c73d0f81557f63ae2ea126e08905Dale Johannesen // These are useful to see where empty asm's wound up. 1414f26f5dde14dddb7540d4d8024ecdd7f5a8390b39Chris Lattner if (AsmStr[0] == 0) { 1415f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner if (!OutStreamer.hasRawTextSupport()) return; 1416f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner 141758bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+ 1418f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner MAI->getInlineAsmStart()); 141958bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+ 1420f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner MAI->getInlineAsmEnd()); 1421f26f5dde14dddb7540d4d8024ecdd7f5a8390b39Chris Lattner return; 1422f26f5dde14dddb7540d4d8024ecdd7f5a8390b39Chris Lattner } 1423f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner 1424f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner // Emit the #APP start marker. This has to happen even if verbose-asm isn't 1425f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner // enabled, so we use EmitRawText. 1426f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner if (OutStreamer.hasRawTextSupport()) 142758bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+ 1428f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner MAI->getInlineAsmStart()); 1429f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner 1430f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner // Emit the inline asm to a temporary string so we can emit it through 1431f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner // EmitInlineAsm. 1432f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner SmallString<256> StringData; 1433c1e0b76306dd1cf1809a15ff8466de30e3a800e5Chris Lattner raw_svector_ostream OS(StringData); 1434f26f5dde14dddb7540d4d8024ecdd7f5a8390b39Chris Lattner 1435c1e0b76306dd1cf1809a15ff8466de30e3a800e5Chris Lattner OS << '\t'; 1436f26f5dde14dddb7540d4d8024ecdd7f5a8390b39Chris Lattner 1437eb9a42c90bf7e21ad8544315a65f86b668cc0277Bill Wendling // The variant of the current asmprinter. 143833adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner int AsmPrinterVariant = MAI->getAssemblerDialect(); 1439eb9a42c90bf7e21ad8544315a65f86b668cc0277Bill Wendling 14406609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner int CurVariant = -1; // The number of the {.|.|.} region we are in. 14416609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner const char *LastEmitted = AsmStr; // One past the last character emitted. 14422cc2f66c25d9576743026688fdae5ed402726532Chris Lattner 14436609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner while (*LastEmitted) { 14446609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner switch (*LastEmitted) { 14456609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner default: { 14466609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner // Not a special case, emit the string section literally. 14476609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner const char *LiteralEnd = LastEmitted+1; 14486609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner while (*LiteralEnd && *LiteralEnd != '{' && *LiteralEnd != '|' && 14491c05997bd8d8b3e97c9a5384f8197d0348e237a3Chris Lattner *LiteralEnd != '}' && *LiteralEnd != '$' && *LiteralEnd != '\n') 14506609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner ++LiteralEnd; 14516609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner if (CurVariant == -1 || CurVariant == AsmPrinterVariant) 1452c1e0b76306dd1cf1809a15ff8466de30e3a800e5Chris Lattner OS.write(LastEmitted, LiteralEnd-LastEmitted); 14536609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner LastEmitted = LiteralEnd; 14546609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner break; 14556609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner } 14561c05997bd8d8b3e97c9a5384f8197d0348e237a3Chris Lattner case '\n': 14571c05997bd8d8b3e97c9a5384f8197d0348e237a3Chris Lattner ++LastEmitted; // Consume newline character. 1458c1e0b76306dd1cf1809a15ff8466de30e3a800e5Chris Lattner OS << '\n'; // Indent code with newline. 14591c05997bd8d8b3e97c9a5384f8197d0348e237a3Chris Lattner break; 14606609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner case '$': { 14616609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner ++LastEmitted; // Consume '$' character. 1462faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner bool Done = true; 1463faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner 1464faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner // Handle escapes. 1465faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner switch (*LastEmitted) { 1466faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner default: Done = false; break; 1467faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner case '$': // $$ -> $ 14686609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner if (CurVariant == -1 || CurVariant == AsmPrinterVariant) 1469c1e0b76306dd1cf1809a15ff8466de30e3a800e5Chris Lattner OS << '$'; 14706609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner ++LastEmitted; // Consume second '$' character. 14716609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner break; 1472faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner case '(': // $( -> same as GCC's { character. 1473faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner ++LastEmitted; // Consume '(' character. 1474faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner if (CurVariant != -1) { 14757d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin llvm_report_error("Nested variants found in inline asm string: '" 14767d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin + std::string(AsmStr) + "'"); 1477faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner } 1478faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner CurVariant = 0; // We're in the first variant now. 1479faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner break; 1480faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner case '|': 1481faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner ++LastEmitted; // consume '|' character. 14828b1e0549389e4c360ac95f50da95d5009553b447Dale Johannesen if (CurVariant == -1) 1483c1e0b76306dd1cf1809a15ff8466de30e3a800e5Chris Lattner OS << '|'; // this is gcc's behavior for | outside a variant 14848b1e0549389e4c360ac95f50da95d5009553b447Dale Johannesen else 14858b1e0549389e4c360ac95f50da95d5009553b447Dale Johannesen ++CurVariant; // We're in the next variant. 1486faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner break; 1487faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner case ')': // $) -> same as GCC's } char. 1488faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner ++LastEmitted; // consume ')' character. 14898b1e0549389e4c360ac95f50da95d5009553b447Dale Johannesen if (CurVariant == -1) 1490c1e0b76306dd1cf1809a15ff8466de30e3a800e5Chris Lattner OS << '}'; // this is gcc's behavior for } outside a variant 14918b1e0549389e4c360ac95f50da95d5009553b447Dale Johannesen else 14928b1e0549389e4c360ac95f50da95d5009553b447Dale Johannesen CurVariant = -1; 1493faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner break; 14946609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner } 1495faf1daeb92bf4db4a6a68d296e24a6e2a4768022Chris Lattner if (Done) break; 14966609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner 14976609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner bool HasCurlyBraces = false; 14986609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner if (*LastEmitted == '{') { // ${variable} 14996609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner ++LastEmitted; // Consume '{' character. 15006609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner HasCurlyBraces = true; 15016609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner } 15026609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner 15033e0cc2634e861b789850b5103efcc8898bf14c4cChris Lattner // If we have ${:foo}, then this is not a real operand reference, it is a 15043e0cc2634e861b789850b5103efcc8898bf14c4cChris Lattner // "magic" string reference, just like in .td files. Arrange to call 15053e0cc2634e861b789850b5103efcc8898bf14c4cChris Lattner // PrintSpecial. 15063e0cc2634e861b789850b5103efcc8898bf14c4cChris Lattner if (HasCurlyBraces && *LastEmitted == ':') { 15073e0cc2634e861b789850b5103efcc8898bf14c4cChris Lattner ++LastEmitted; 15083e0cc2634e861b789850b5103efcc8898bf14c4cChris Lattner const char *StrStart = LastEmitted; 15093e0cc2634e861b789850b5103efcc8898bf14c4cChris Lattner const char *StrEnd = strchr(StrStart, '}'); 1510c1e0b76306dd1cf1809a15ff8466de30e3a800e5Chris Lattner if (StrEnd == 0) 1511c1e0b76306dd1cf1809a15ff8466de30e3a800e5Chris Lattner llvm_report_error(Twine("Unterminated ${:foo} operand in inline asm" 1512e1783cadf77d6a8e637d0eb79e66f42228d7ec3cChris Lattner " string: '") + Twine(AsmStr) + "'"); 15133e0cc2634e861b789850b5103efcc8898bf14c4cChris Lattner 15143e0cc2634e861b789850b5103efcc8898bf14c4cChris Lattner std::string Val(StrStart, StrEnd); 1515c1e0b76306dd1cf1809a15ff8466de30e3a800e5Chris Lattner PrintSpecial(MI, OS, Val.c_str()); 15163e0cc2634e861b789850b5103efcc8898bf14c4cChris Lattner LastEmitted = StrEnd+1; 15173e0cc2634e861b789850b5103efcc8898bf14c4cChris Lattner break; 15183e0cc2634e861b789850b5103efcc8898bf14c4cChris Lattner } 15193e0cc2634e861b789850b5103efcc8898bf14c4cChris Lattner 15206609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner const char *IDStart = LastEmitted; 15216609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner char *IDEnd; 1522fad2912522a4c97128d8afcc2f40ca0e39287ddbChris Lattner errno = 0; 15236609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner long Val = strtol(IDStart, &IDEnd, 10); // We only accept numbers for IDs. 15246609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner if (!isdigit(*IDStart) || (Val == 0 && errno == EINVAL)) { 15257d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin llvm_report_error("Bad $ operand number in inline asm string: '" 15267d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin + std::string(AsmStr) + "'"); 15276609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner } 15286609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner LastEmitted = IDEnd; 15296609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner 1530a36cb0a6b110f1ac9a9388019febb64620a124b9Chris Lattner char Modifier[2] = { 0, 0 }; 1531a36cb0a6b110f1ac9a9388019febb64620a124b9Chris Lattner 15326609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner if (HasCurlyBraces) { 1533a36cb0a6b110f1ac9a9388019febb64620a124b9Chris Lattner // If we have curly braces, check for a modifier character. This 1534a36cb0a6b110f1ac9a9388019febb64620a124b9Chris Lattner // supports syntax like ${0:u}, which correspond to "%u0" in GCC asm. 1535a36cb0a6b110f1ac9a9388019febb64620a124b9Chris Lattner if (*LastEmitted == ':') { 1536a36cb0a6b110f1ac9a9388019febb64620a124b9Chris Lattner ++LastEmitted; // Consume ':' character. 1537a36cb0a6b110f1ac9a9388019febb64620a124b9Chris Lattner if (*LastEmitted == 0) { 15387d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin llvm_report_error("Bad ${:} expression in inline asm string: '" 15397d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin + std::string(AsmStr) + "'"); 1540a36cb0a6b110f1ac9a9388019febb64620a124b9Chris Lattner } 1541a36cb0a6b110f1ac9a9388019febb64620a124b9Chris Lattner 1542a36cb0a6b110f1ac9a9388019febb64620a124b9Chris Lattner Modifier[0] = *LastEmitted; 1543a36cb0a6b110f1ac9a9388019febb64620a124b9Chris Lattner ++LastEmitted; // Consume modifier character. 1544a36cb0a6b110f1ac9a9388019febb64620a124b9Chris Lattner } 1545a36cb0a6b110f1ac9a9388019febb64620a124b9Chris Lattner 15466609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner if (*LastEmitted != '}') { 15477d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin llvm_report_error("Bad ${} expression in inline asm string: '" 15487d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin + std::string(AsmStr) + "'"); 15496609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner } 15506609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner ++LastEmitted; // Consume '}' character. 15516609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner } 15526609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner 15536609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner if ((unsigned)Val >= NumOperands-1) { 15547d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin llvm_report_error("Invalid $ operand number in inline asm string: '" 15557d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin + std::string(AsmStr) + "'"); 15566609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner } 15576609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner 1558c3a9f8d31ce93ba384bd2bbdd55c757b06600a15Chris Lattner // Okay, we finally have a value number. Ask the target to print this 15596609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner // operand! 1560c3a9f8d31ce93ba384bd2bbdd55c757b06600a15Chris Lattner if (CurVariant == -1 || CurVariant == AsmPrinterVariant) { 1561c3a9f8d31ce93ba384bd2bbdd55c757b06600a15Chris Lattner unsigned OpNo = 1; 1562fd561cded3cbaec1a4bdfae0703b4be4ea4092f3Chris Lattner 1563fd561cded3cbaec1a4bdfae0703b4be4ea4092f3Chris Lattner bool Error = false; 1564fd561cded3cbaec1a4bdfae0703b4be4ea4092f3Chris Lattner 1565c3a9f8d31ce93ba384bd2bbdd55c757b06600a15Chris Lattner // Scan to find the machine operand number for the operand. 1566daf6bc6347b4785102611bdf21c512e8a7678cceChris Lattner for (; Val; --Val) { 1567fd561cded3cbaec1a4bdfae0703b4be4ea4092f3Chris Lattner if (OpNo >= MI->getNumOperands()) break; 15689e3304900ff69c4920fea7369c9c36916c4a6a6aChris Lattner unsigned OpFlags = MI->getOperand(OpNo).getImm(); 1569697cbbfb00c318f98d6eb51945f077e2bfe8781eEvan Cheng OpNo += InlineAsm::getNumOperandRegisters(OpFlags) + 1; 1570daf6bc6347b4785102611bdf21c512e8a7678cceChris Lattner } 1571fd561cded3cbaec1a4bdfae0703b4be4ea4092f3Chris Lattner 1572fd561cded3cbaec1a4bdfae0703b4be4ea4092f3Chris Lattner if (OpNo >= MI->getNumOperands()) { 1573fd561cded3cbaec1a4bdfae0703b4be4ea4092f3Chris Lattner Error = true; 1574dd26033002b1b4c569df84ac947828c0fc02f6baChris Lattner } else { 15759e3304900ff69c4920fea7369c9c36916c4a6a6aChris Lattner unsigned OpFlags = MI->getOperand(OpNo).getImm(); 1576fd561cded3cbaec1a4bdfae0703b4be4ea4092f3Chris Lattner ++OpNo; // Skip over the ID number. 1577fd561cded3cbaec1a4bdfae0703b4be4ea4092f3Chris Lattner 157810b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner if (Modifier[0] == 'l') // labels are target independent 1579c1e0b76306dd1cf1809a15ff8466de30e3a800e5Chris Lattner OS << *MI->getOperand(OpNo).getMBB()->getSymbol(); 1580eb57ea7ea2378b77bc995371c1888193b960cd03Dale Johannesen else { 1581eb57ea7ea2378b77bc995371c1888193b960cd03Dale Johannesen AsmPrinter *AP = const_cast<AsmPrinter*>(this); 158286b49f8e2de796cb46c7c8b6a4c4900533fd53f4Dale Johannesen if ((OpFlags & 7) == 4) { 1583eb57ea7ea2378b77bc995371c1888193b960cd03Dale Johannesen Error = AP->PrintAsmMemoryOperand(MI, OpNo, AsmPrinterVariant, 1584c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner Modifier[0] ? Modifier : 0, 1585c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner OS); 1586eb57ea7ea2378b77bc995371c1888193b960cd03Dale Johannesen } else { 1587eb57ea7ea2378b77bc995371c1888193b960cd03Dale Johannesen Error = AP->PrintAsmOperand(MI, OpNo, AsmPrinterVariant, 1588c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner Modifier[0] ? Modifier : 0, OS); 1589eb57ea7ea2378b77bc995371c1888193b960cd03Dale Johannesen } 1590fd561cded3cbaec1a4bdfae0703b4be4ea4092f3Chris Lattner } 1591dd26033002b1b4c569df84ac947828c0fc02f6baChris Lattner } 1592dd26033002b1b4c569df84ac947828c0fc02f6baChris Lattner if (Error) { 15937d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin std::string msg; 15947d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin raw_string_ostream Msg(msg); 159510b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner Msg << "Invalid operand found in inline asm: '" << AsmStr << "'\n"; 15967d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin MI->print(Msg); 15977d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin llvm_report_error(Msg.str()); 15986609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner } 1599c3a9f8d31ce93ba384bd2bbdd55c757b06600a15Chris Lattner } 16006609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner break; 16016609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner } 16026609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner } 16036609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner } 1604c1e0b76306dd1cf1809a15ff8466de30e3a800e5Chris Lattner OS << "\n"; 1605f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner 1606c1e0b76306dd1cf1809a15ff8466de30e3a800e5Chris Lattner EmitInlineAsm(OS.str()); 1607f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner 1608f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner // Emit the #NOAPP end marker. This has to happen even if verbose-asm isn't 1609f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner // enabled, so we use EmitRawText. 1610f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner if (OutStreamer.hasRawTextSupport()) 161158bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+ 1612f94f8dcda71b0069f9dbde979a81a58a49194ba2Chris Lattner MAI->getInlineAsmEnd()); 16136609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner} 16146609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner 1615300a4c5640fb1c717ba0d7108d15aec1bd7eb396Chris Lattner/// EmitImplicitDef - This method emits the specified machine instruction 1616da47e6e0d003c873da960361549e57ee4617c301Evan Cheng/// that is an implicit def. 1617300a4c5640fb1c717ba0d7108d15aec1bd7eb396Chris Lattnervoid AsmPrinter::EmitImplicitDef(const MachineInstr *MI) const { 1618c5ea263a23f4f15587e35c9cb07cf72a9fba7613Chris Lattner if (!VerboseAsm) return; 16199d1c1ada213c80135fbdda704175aae689daa6f9Chris Lattner unsigned RegNo = MI->getOperand(0).getReg(); 162058bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner OutStreamer.AddComment(Twine("implicit-def: ") + 16219d1c1ada213c80135fbdda704175aae689daa6f9Chris Lattner TM.getRegisterInfo()->getName(RegNo)); 16228e089a9e4d6b7aa2b3968c38644f926f60a7c670Chris Lattner OutStreamer.AddBlankLine(); 1623da47e6e0d003c873da960361549e57ee4617c301Evan Cheng} 1624da47e6e0d003c873da960361549e57ee4617c301Evan Cheng 1625300a4c5640fb1c717ba0d7108d15aec1bd7eb396Chris Lattnervoid AsmPrinter::EmitKill(const MachineInstr *MI) const { 1626ad68264f590f05db3731a452fc91dc22bc75167dJakob Stoklund Olesen if (!VerboseAsm) return; 162758bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner 162858bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner std::string Str = "kill:"; 1629ad68264f590f05db3731a452fc91dc22bc75167dJakob Stoklund Olesen for (unsigned n = 0, e = MI->getNumOperands(); n != e; ++n) { 163058bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner const MachineOperand &Op = MI->getOperand(n); 163158bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner assert(Op.isReg() && "KILL instruction must have only register operands"); 163258bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner Str += ' '; 16339d1c1ada213c80135fbdda704175aae689daa6f9Chris Lattner Str += TM.getRegisterInfo()->getName(Op.getReg()); 163458bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner Str += (Op.isDef() ? "<def>" : "<kill>"); 1635ad68264f590f05db3731a452fc91dc22bc75167dJakob Stoklund Olesen } 163658bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner OutStreamer.AddComment(Str); 16378e089a9e4d6b7aa2b3968c38644f926f60a7c670Chris Lattner OutStreamer.AddBlankLine(); 1638ad68264f590f05db3731a452fc91dc22bc75167dJakob Stoklund Olesen} 1639ad68264f590f05db3731a452fc91dc22bc75167dJakob Stoklund Olesen 16406609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM 16416609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner/// instruction, using the specified assembler variant. Targets should 1642cf0b76649be4eea33aba783d4154ea338b7cbbc2Dale Johannesen/// override this to format as appropriate. 16436609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattnerbool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 1644c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 1645c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 16466609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner // Target doesn't support this yet! 16476609913b7d0ad13058d4ffffb17fb8d8078799efChris Lattner return true; 16480264d1a4777370009176157b76d116b3195e3767Chris Lattner} 1649dd26033002b1b4c569df84ac947828c0fc02f6baChris Lattner 1650dd26033002b1b4c569df84ac947828c0fc02f6baChris Lattnerbool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 1651dd26033002b1b4c569df84ac947828c0fc02f6baChris Lattner unsigned AsmVariant, 1652c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, raw_ostream &O) { 1653dd26033002b1b4c569df84ac947828c0fc02f6baChris Lattner // Target doesn't support this yet! 1654dd26033002b1b4c569df84ac947828c0fc02f6baChris Lattner return true; 1655dd26033002b1b4c569df84ac947828c0fc02f6baChris Lattner} 165637efe6764568a3829fee26aba532283131d1a104Nate Begeman 1657951755445821b92c3dc38f32b5c36e9875fa4318Chris LattnerMCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const { 16583b9d6216a41cfd43759e787db26d797e1f0ba0a8Chris Lattner return MMI->getAddrLabelSymbol(BA->getBasicBlock()); 16598c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman} 16608c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman 16613b9d6216a41cfd43759e787db26d797e1f0ba0a8Chris LattnerMCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const { 16623b9d6216a41cfd43759e787db26d797e1f0ba0a8Chris Lattner return MMI->getAddrLabelSymbol(BB); 16638c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman} 16648c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman 16653924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner/// GetCPISymbol - Return the symbol for the specified constant pool entry. 16663924868a957d5a6d468b61741cbb7db77324d1f6Chris LattnerMCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const { 16679b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol 166898cdab53c302a2d6686fa428c0e896b1fb195311Chris Lattner (Twine(MAI->getPrivateGlobalPrefix()) + "CPI" + Twine(getFunctionNumber()) 166998cdab53c302a2d6686fa428c0e896b1fb195311Chris Lattner + "_" + Twine(CPID)); 16703924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner} 16713924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner 16723924868a957d5a6d468b61741cbb7db77324d1f6Chris Lattner/// GetJTISymbol - Return the symbol for the specified jump table entry. 16733924868a957d5a6d468b61741cbb7db77324d1f6Chris LattnerMCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const { 1674589c6f620e8dcf3d59af1ae0e15372c934647c82Chris Lattner return MF->getJTISymbol(JTID, OutContext, isLinkerPrivate); 16757cb384dcca3f1ccfc993182ee4b972f7fffc8ffaChris Lattner} 16767cb384dcca3f1ccfc993182ee4b972f7fffc8ffaChris Lattner 1677798d1256595dcc0f5d4423572f856d239f7de0e6Chris Lattner/// GetJTSetSymbol - Return the symbol for the specified jump table .set 1678798d1256595dcc0f5d4423572f856d239f7de0e6Chris Lattner/// FIXME: privatize to AsmPrinter. 1679798d1256595dcc0f5d4423572f856d239f7de0e6Chris LattnerMCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const { 16809b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol 168198cdab53c302a2d6686fa428c0e896b1fb195311Chris Lattner (Twine(MAI->getPrivateGlobalPrefix()) + Twine(getFunctionNumber()) + "_" + 168298cdab53c302a2d6686fa428c0e896b1fb195311Chris Lattner Twine(UID) + "_set_" + Twine(MBBID)); 1683798d1256595dcc0f5d4423572f856d239f7de0e6Chris Lattner} 1684798d1256595dcc0f5d4423572f856d239f7de0e6Chris Lattner 16857a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner/// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with 1686d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner/// global value name as its base, with the specified suffix, and where the 16877a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner/// symbol is forced to have private linkage if ForcePrivate is true. 16887a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris LattnerMCSymbol *AsmPrinter::GetSymbolWithGlobalValueBase(const GlobalValue *GV, 16897a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner StringRef Suffix, 16907a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner bool ForcePrivate) const { 1691d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner SmallString<60> NameStr; 16927a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner Mang->getNameWithPrefix(NameStr, GV, ForcePrivate); 1693d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner NameStr.append(Suffix.begin(), Suffix.end()); 16949b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(NameStr.str()); 1695d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner} 1696d588b97cc9acf778282ab10efa4f298cead1215aChris Lattner 16976b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner/// GetExternalSymbolSymbol - Return the MCSymbol for the specified 16986b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner/// ExternalSymbol. 16996b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris LattnerMCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) const { 17006b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner SmallString<60> NameStr; 17016b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner Mang->getNameWithPrefix(NameStr, Sym); 17026b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner return OutContext.GetOrCreateSymbol(NameStr.str()); 17036b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner} 17046b04edee11c2bb35a48b1c42f867b4ba8cdfff97Chris Lattner 17057cb384dcca3f1ccfc993182ee4b972f7fffc8ffaChris Lattner 1706523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1707523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner/// PrintParentLoopComment - Print comments about parent loops of this one. 1708523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattnerstatic void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop, 1709523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner unsigned FunctionNumber) { 1710523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner if (Loop == 0) return; 1711523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner PrintParentLoopComment(OS, Loop->getParentLoop(), FunctionNumber); 1712523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS.indent(Loop->getLoopDepth()*2) 1713523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << "Parent Loop BB" << FunctionNumber << "_" 1714523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << Loop->getHeader()->getNumber() 1715523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << " Depth=" << Loop->getLoopDepth() << '\n'; 1716523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner} 1717523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1718523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1719523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner/// PrintChildLoopComment - Print comments about child loops within 1720523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner/// the loop for this basic block, with nesting. 1721523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattnerstatic void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop, 1722523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner unsigned FunctionNumber) { 1723523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // Add child loop information 1724523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner for (MachineLoop::iterator CL = Loop->begin(), E = Loop->end();CL != E; ++CL){ 1725523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS.indent((*CL)->getLoopDepth()*2) 1726523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << "Child Loop BB" << FunctionNumber << "_" 1727523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << (*CL)->getHeader()->getNumber() << " Depth " << (*CL)->getLoopDepth() 1728523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner << '\n'; 1729523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner PrintChildLoopComment(OS, *CL, FunctionNumber); 1730523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner } 1731523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner} 1732523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1733dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner/// EmitBasicBlockLoopComments - Pretty-print comments for basic blocks. 1734dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattnerstatic void EmitBasicBlockLoopComments(const MachineBasicBlock &MBB, 1735dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner const MachineLoopInfo *LI, 1736dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner const AsmPrinter &AP) { 1737523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // Add loop depth information 1738523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner const MachineLoop *Loop = LI->getLoopFor(&MBB); 1739523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner if (Loop == 0) return; 1740523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1741523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner MachineBasicBlock *Header = Loop->getHeader(); 1742523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner assert(Header && "No header for loop"); 1743523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1744523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // If this block is not a loop header, just print out what is the loop header 1745523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // and return. 1746523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner if (Header != &MBB) { 1747523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner AP.OutStreamer.AddComment(" in Loop: Header=BB" + 1748523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner Twine(AP.getFunctionNumber())+"_" + 1749523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner Twine(Loop->getHeader()->getNumber())+ 1750523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner " Depth="+Twine(Loop->getLoopDepth())); 1751523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner return; 1752523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner } 1753523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1754523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // Otherwise, it is a loop header. Print out information about child and 1755523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner // parent loops. 1756523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner raw_ostream &OS = AP.OutStreamer.GetCommentOS(); 1757523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1758523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber()); 1759523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1760523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS << "=>"; 1761523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS.indent(Loop->getLoopDepth()*2-2); 1762523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1763523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS << "This "; 1764523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner if (Loop->empty()) 1765523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS << "Inner "; 1766523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n'; 1767523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1768523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner PrintChildLoopComment(OS, Loop, AP.getFunctionNumber()); 1769523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner} 1770523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 1771523a508576ee2c31ba58de1ca2fb7ffeebcc4a0bChris Lattner 177270a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner/// EmitBasicBlockStart - This method prints the label for the specified 177370a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner/// MachineBasicBlock, an alignment (if present) and a comment describing 177470a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner/// it if appropriate. 1775662316c997e4eb8c3fdec6999b3e9da03620847aChris Lattnervoid AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const { 1776b1cac33856687715bf8db3860ff55ad2f6ca94b5Dan Gohman // Emit an alignment directive for this block, if needed. 177770a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner if (unsigned Align = MBB->getAlignment()) 177870a54c07a0807bf89d1a8b4414e53298c376eb61Chris Lattner EmitAlignment(Log2_32(Align)); 1779fb8075d03f5c87bd57dcc9c5f2304f6b13c55aadEvan Cheng 1780999aee24c7b7511575146b9950bb85830fab0378Chris Lattner // If the block has its address taken, emit any labels that were used to 1781999aee24c7b7511575146b9950bb85830fab0378Chris Lattner // reference the block. It is possible that there is more than one label 1782999aee24c7b7511575146b9950bb85830fab0378Chris Lattner // here, because multiple LLVM BB's may have been RAUW'd to this block after 1783999aee24c7b7511575146b9950bb85830fab0378Chris Lattner // the references were generated. 17848c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman if (MBB->hasAddressTaken()) { 1785213168ba469703a186d060281e587d828878aa75Chris Lattner const BasicBlock *BB = MBB->getBasicBlock(); 17860fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner if (VerboseAsm) 1787999aee24c7b7511575146b9950bb85830fab0378Chris Lattner OutStreamer.AddComment("Block address taken"); 1788999aee24c7b7511575146b9950bb85830fab0378Chris Lattner 1789999aee24c7b7511575146b9950bb85830fab0378Chris Lattner std::vector<MCSymbol*> Syms = MMI->getAddrLabelSymbolToEmit(BB); 1790999aee24c7b7511575146b9950bb85830fab0378Chris Lattner 1791999aee24c7b7511575146b9950bb85830fab0378Chris Lattner for (unsigned i = 0, e = Syms.size(); i != e; ++i) 1792999aee24c7b7511575146b9950bb85830fab0378Chris Lattner OutStreamer.EmitLabel(Syms[i]); 17938c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman } 17948c2b52552c90f39e4b2fed43e309e599e742b6acDan Gohman 1795b1cac33856687715bf8db3860ff55ad2f6ca94b5Dan Gohman // Print the main label for the block. 17960a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (MBB->pred_empty() || isBlockOnlyReachableByFallthrough(MBB)) { 179758bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner if (VerboseAsm && OutStreamer.hasRawTextSupport()) { 17980fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner if (const BasicBlock *BB = MBB->getBasicBlock()) 17990fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner if (BB->hasName()) 18000fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner OutStreamer.AddComment("%" + BB->getName()); 1801d8d0aee26a5a759085bfa9114302e507c8685599Chris Lattner 1802dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner EmitBasicBlockLoopComments(*MBB, LI, *this); 180358bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner 180458bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner // NOTE: Want this comment at start of line, don't emit with AddComment. 180558bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner OutStreamer.EmitRawText(Twine(MAI->getCommentString()) + " BB#" + 180658bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner Twine(MBB->getNumber()) + ":"); 18070fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner } 1808e3cc3f3c84abfdf8eb3bd19dfa806ceea49f15d6Dan Gohman } else { 18090fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner if (VerboseAsm) { 18100fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner if (const BasicBlock *BB = MBB->getBasicBlock()) 18110fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner if (BB->hasName()) 18120fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner OutStreamer.AddComment("%" + BB->getName()); 1813dfa107e45ac6a145c03376ecc0530d8ece358238Chris Lattner EmitBasicBlockLoopComments(*MBB, LI, *this); 18140fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner } 1815d8d0aee26a5a759085bfa9114302e507c8685599Chris Lattner 18161b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner OutStreamer.EmitLabel(MBB->getSymbol()); 1817e3cc3f3c84abfdf8eb3bd19dfa806ceea49f15d6Dan Gohman } 181837efe6764568a3829fee26aba532283131d1a104Nate Begeman} 181952a51e38dc312aa262b0d771419afe1785f3cb22Nate Begeman 1820be9dfcef82c58063708e039bea3cf972ba41581bChris Lattnervoid AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility) const { 1821152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner MCSymbolAttr Attr = MCSA_Invalid; 1822152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner 1823152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner switch (Visibility) { 1824152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner default: break; 1825152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner case GlobalValue::HiddenVisibility: 1826152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner Attr = MAI->getHiddenVisibilityAttr(); 1827152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner break; 1828152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner case GlobalValue::ProtectedVisibility: 1829152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner Attr = MAI->getProtectedVisibilityAttr(); 1830152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner break; 183153d4d78d9a2c26a67ac8f6e81cc149702103fc2cChris Lattner } 1832152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner 1833152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner if (Attr != MCSA_Invalid) 1834152a29bfa6fa505182658d046bc75626e10d67c3Chris Lattner OutStreamer.EmitSymbolAttribute(Sym, Attr); 183553d4d78d9a2c26a67ac8f6e81cc149702103fc2cChris Lattner} 183653d4d78d9a2c26a67ac8f6e81cc149702103fc2cChris Lattner 18370a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner/// isBlockOnlyReachableByFallthough - Return true if the basic block has 18380a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner/// exactly one predecessor and the control transfer mechanism between 18390a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner/// the predecessor and this block is a fall-through. 1840e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattnerbool AsmPrinter:: 1841e00b59f954c7e27d9d34abf90bfac969fb12f19aChris LattnerisBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { 18420a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // If this is a landing pad, it isn't a fall through. If it has no preds, 18430a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // then nothing falls through to it. 18440a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (MBB->isLandingPad() || MBB->pred_empty()) 18450a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return false; 18460a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 18470a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // If there isn't exactly one predecessor, it can't be a fall through. 18480a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; 18490a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner ++PI2; 18500a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (PI2 != MBB->pred_end()) 18510a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return false; 18520a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 18530a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // The predecessor has to be immediately before this block. 18540a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner const MachineBasicBlock *Pred = *PI; 18550a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 18560a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (!Pred->isLayoutSuccessor(MBB)) 18570a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return false; 18580a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 18590a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // If the block is completely empty, then it definitely does fall through. 18600a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (Pred->empty()) 18610a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return true; 18620a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 18630a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // Otherwise, check the last instruction. 18640a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner const MachineInstr &LastInst = Pred->back(); 18650a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return !LastInst.getDesc().isBarrier(); 18660a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner} 18670a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 18680a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 18690a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 18705eca075b74d62c621b160aa216b4cd50829a2cc7Gordon HenriksenGCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) { 18715eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen if (!S->usesMetadata()) 1872c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen return 0; 1873e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner 1874e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner gcp_map_type &GCMap = getGCMap(GCMetadataPrinters); 1875e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner gcp_map_type::iterator GCPI = GCMap.find(S); 1876e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner if (GCPI != GCMap.end()) 1877c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen return GCPI->second; 1878c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen 18795eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen const char *Name = S->getName().c_str(); 1880c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen 1881c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen for (GCMetadataPrinterRegistry::iterator 1882c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen I = GCMetadataPrinterRegistry::begin(), 1883c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen E = GCMetadataPrinterRegistry::end(); I != E; ++I) 1884c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen if (strcmp(Name, I->getName()) == 0) { 18855eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen GCMetadataPrinter *GMP = I->instantiate(); 18865eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen GMP->S = S; 1887e00b59f954c7e27d9d34abf90bfac969fb12f19aChris Lattner GCMap.insert(std::make_pair(S, GMP)); 18885eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen return GMP; 1889c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen } 1890c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen 189152492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner llvm_report_error("no GCMetadataPrinter registered for GC: " + Twine(Name)); 189252492ac0d03aa86b07ad889b69b0ba38ffec8011Chris Lattner return 0; 1893c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen} 1894014700c1a8cba203fd21ff129426ba8a426ab244David Greene 1895